Use py_resource module
[python/dscho.git] / Lib / cmpcache.py
blob494dcc1c4639f09fde92a5d377712e6d2916b749
1 # Module 'cmpcache'
3 # Efficiently compare files, boolean outcome only (equal / not equal).
5 # Tricks (used in this order):
6 # - Use the statcache module to avoid statting files more than once
7 # - Files with identical type, size & mtime are assumed to be clones
8 # - Files with different type or size cannot be identical
9 # - We keep a cache of outcomes of earlier comparisons
10 # - We don't fork a process to run 'cmp' but read the files ourselves
12 import os
13 from stat import *
14 import statcache
17 # The cache.
19 cache = {}
22 # Compare two files, use the cache if possible.
23 # May raise os.error if a stat or open of either fails.
25 def cmp(f1, f2):
26 # Return 1 for identical files, 0 for different.
27 # Raise exceptions if either file could not be statted, read, etc.
28 s1, s2 = sig(statcache.stat(f1)), sig(statcache.stat(f2))
29 if not S_ISREG(s1[0]) or not S_ISREG(s2[0]):
30 # Either is a not a plain file -- always report as different
31 return 0
32 if s1 == s2:
33 # type, size & mtime match -- report same
34 return 1
35 if s1[:2] <> s2[:2]: # Types or sizes differ, don't bother
36 # types or sizes differ -- report different
37 return 0
38 # same type and size -- look in the cache
39 key = f1 + ' ' + f2
40 if cache.has_key(key):
41 cs1, cs2, outcome = cache[key]
42 # cache hit
43 if s1 == cs1 and s2 == cs2:
44 # cached signatures match
45 return outcome
46 # stale cached signature(s)
47 # really compare
48 outcome = do_cmp(f1, f2)
49 cache[key] = s1, s2, outcome
50 return outcome
52 # Return signature (i.e., type, size, mtime) from raw stat data.
54 def sig(st):
55 return S_IFMT(st[ST_MODE]), st[ST_SIZE], st[ST_MTIME]
57 # Compare two files, really.
59 def do_cmp(f1, f2):
60 #print ' cmp', f1, f2 # XXX remove when debugged
61 bufsize = 8*1024 # Could be tuned
62 fp1 = open(f1, 'r')
63 fp2 = open(f2, 'r')
64 while 1:
65 b1 = fp1.read(bufsize)
66 b2 = fp2.read(bufsize)
67 if b1 <> b2: return 0
68 if not b1: return 1