home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyth_os2.zip / python-1.0.2 / Lib / cmpcache.py < prev    next >
Text File  |  1993-12-29  |  2KB  |  69 lines

  1. # Module 'cmpcache'
  2. #
  3. # Efficiently compare files, boolean outcome only (equal / not equal).
  4. #
  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
  11.  
  12. import os
  13. from stat import *
  14. import statcache
  15.  
  16.  
  17. # The cache.
  18. #
  19. cache = {}
  20.  
  21.  
  22. # Compare two files, use the cache if possible.
  23. # May raise os.error if a stat or open of either fails.
  24. #
  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
  51.  
  52. # Return signature (i.e., type, size, mtime) from raw stat data.
  53. #
  54. def sig(st):
  55.     return S_IFMT(st[ST_MODE]), st[ST_SIZE], st[ST_MTIME]
  56.  
  57. # Compare two files, really.
  58. #
  59. def do_cmp(f1, f2):
  60.     #print '    cmp', f1, f2 # XXX remove when debugged
  61.     bufsize = 8096 # 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
  69.