Mercurial > cpython-lru_cache-weakref
annotate Lib/cmp.py @ 10123:bc287c6cfa23 legacy-trunk
Restructured a bit.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Mon, 08 Feb 1999 22:27:18 +0000 |
| parents | e1806b280f53 |
| children | 222aee96dc42 |
| rev | line source |
|---|---|
| 5 | 1 # Module 'cmp' |
| 2 | |
| 3 # Efficiently compare files, boolean outcome only (equal / not equal). | |
| 4 | |
| 5 # Tricks (used in this order): | |
| 6 # - Files with identical type, size & mtime are assumed to be clones | |
| 7 # - Files with different type or size cannot be identical | |
| 8 # - We keep a cache of outcomes of earlier comparisons | |
| 9 # - We don't fork a process to run 'cmp' but read the files ourselves | |
| 10 | |
| 776 | 11 import os |
| 5 | 12 |
| 13 cache = {} | |
| 14 | |
| 15 def cmp(f1, f2): # Compare two files, use the cache if possible. | |
| 16 # Return 1 for identical files, 0 for different. | |
| 17 # Raise exceptions if either file could not be statted, read, etc. | |
| 776 | 18 s1, s2 = sig(os.stat(f1)), sig(os.stat(f2)) |
| 5 | 19 if s1[0] <> 8 or s2[0] <> 8: |
| 20 # Either is a not a plain file -- always report as different | |
| 21 return 0 | |
| 559 | 22 if s1 == s2: |
| 5 | 23 # type, size & mtime match -- report same |
| 24 return 1 | |
| 25 if s1[:2] <> s2[:2]: # Types or sizes differ, don't bother | |
| 26 # types or sizes differ -- report different | |
| 27 return 0 | |
| 28 # same type and size -- look in the cache | |
|
9423
e1806b280f53
Use (f1, f2) as cache key instead of f1 + ' ' + f2.
Guido van Rossum <guido@python.org>
parents:
1965
diff
changeset
|
29 key = (f1, f2) |
| 5 | 30 try: |
| 31 cs1, cs2, outcome = cache[key] | |
| 32 # cache hit | |
| 559 | 33 if s1 == cs1 and s2 == cs2: |
| 5 | 34 # cached signatures match |
| 35 return outcome | |
| 36 # stale cached signature(s) | |
| 521 | 37 except KeyError: |
| 5 | 38 # cache miss |
| 39 pass | |
| 40 # really compare | |
| 41 outcome = do_cmp(f1, f2) | |
| 42 cache[key] = s1, s2, outcome | |
| 43 return outcome | |
| 44 | |
| 45 def sig(st): # Return signature (i.e., type, size, mtime) from raw stat data | |
| 46 # 0-5: st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid | |
| 47 # 6-9: st_size, st_atime, st_mtime, st_ctime | |
| 48 type = st[0] / 4096 | |
| 49 size = st[6] | |
| 50 mtime = st[8] | |
| 51 return type, size, mtime | |
| 52 | |
| 53 def do_cmp(f1, f2): # Compare two files, really | |
| 1965 | 54 bufsize = 8*1024 # Could be tuned |
| 5 | 55 fp1 = open(f1, 'r') |
| 56 fp2 = open(f2, 'r') | |
| 57 while 1: | |
| 58 b1 = fp1.read(bufsize) | |
| 59 b2 = fp2.read(bufsize) | |
| 60 if b1 <> b2: return 0 | |
| 61 if not b1: return 1 |
