~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/hashcache.py

  • Committer: John Arbash Meinel
  • Date: 2005-12-01 19:27:48 UTC
  • mto: (1185.50.19 bzr-jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1532.
  • Revision ID: john@arbash-meinel.com-20051201192748-369238cd06ecf7e8
Added osutils.mkdtemp()

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
CACHE_HEADER = "### bzr hashcache v5\n"
31
31
 
32
32
import os, stat, time
 
33
import sha
33
34
 
34
35
from bzrlib.osutils import sha_file
35
36
from bzrlib.trace import mutter, warning
36
37
from bzrlib.atomicfile import AtomicFile
37
 
 
38
 
 
39
 
 
 
38
from bzrlib.osutils import pathjoin
 
39
 
 
40
 
 
41
FP_MODE_COLUMN = 5
40
42
 
41
43
def _fingerprint(abspath):
42
44
    try:
51
53
    # we discard any high precision because it's not reliable; perhaps we
52
54
    # could do better on some systems?
53
55
    return (fs.st_size, long(fs.st_mtime),
54
 
            long(fs.st_ctime), fs.st_ino, fs.st_dev)
 
56
            long(fs.st_ctime), fs.st_ino, fs.st_dev, fs.st_mode)
55
57
 
56
58
 
57
59
class HashCache(object):
100
102
        self.update_count = 0
101
103
        self._cache = {}
102
104
 
103
 
 
104
105
    def cache_file_name(self):
105
 
        return os.sep.join([self.basedir, '.bzr', 'stat-cache'])
106
 
 
107
 
 
108
 
 
 
106
        # FIXME: duplicate path logic here, this should be 
 
107
        # something like 'branch.controlfile'.
 
108
        return pathjoin(self.basedir, '.bzr', 'stat-cache')
109
109
 
110
110
    def clear(self):
111
111
        """Discard all cached information.
126
126
        prep.sort()
127
127
        
128
128
        for inum, path, cache_entry in prep:
129
 
            abspath = os.sep.join([self.basedir, path])
 
129
            abspath = pathjoin(self.basedir, path)
130
130
            fp = _fingerprint(abspath)
131
131
            self.stat_count += 1
132
132
            
139
139
                del self._cache[path]
140
140
 
141
141
 
142
 
 
143
142
    def get_sha1(self, path):
144
143
        """Return the sha1 of a file.
145
144
        """
146
 
        abspath = os.sep.join([self.basedir, path])
 
145
        abspath = pathjoin(self.basedir, path)
147
146
        self.stat_count += 1
148
147
        file_fp = _fingerprint(abspath)
149
148
        
165
164
            return cache_sha1
166
165
        
167
166
        self.miss_count += 1
168
 
        digest = sha_file(file(abspath, 'rb', buffering=65000))
 
167
 
 
168
 
 
169
        mode = file_fp[FP_MODE_COLUMN]
 
170
        if stat.S_ISREG(mode):
 
171
            digest = sha_file(file(abspath, 'rb', buffering=65000))
 
172
        elif stat.S_ISLNK(mode):
 
173
            link_target = os.readlink(abspath)
 
174
            digest = sha.new(os.readlink(abspath)).hexdigest()
 
175
        else:
 
176
            raise BzrError("file %r: unknown file stat mode: %o"%(abspath,mode))
169
177
 
170
178
        now = int(time.time())
171
179
        if file_fp[1] >= now or file_fp[2] >= now:
181
189
            self.update_count += 1
182
190
            self.needs_write = True
183
191
            self._cache[path] = (digest, file_fp)
184
 
        
185
192
        return digest
186
193
        
187
 
 
188
 
 
189
 
 
190
194
    def write(self):
191
195
        """Write contents of cache to file."""
192
196
        outf = AtomicFile(self.cache_file_name(), 'wb')
207
211
        finally:
208
212
            if not outf.closed:
209
213
                outf.abort()
210
 
        
211
 
 
212
214
 
213
215
    def read(self):
214
216
        """Reinstate cache from file.
223
225
        try:
224
226
            inf = file(fn, 'rb', buffering=65000)
225
227
        except IOError, e:
226
 
            mutter("failed to open %s: %s" % (fn, e))
 
228
            mutter("failed to open %s: %s", fn, e)
227
229
            # better write it now so it is valid
228
230
            self.needs_write = True
229
231
            return
231
233
 
232
234
        hdr = inf.readline()
233
235
        if hdr != CACHE_HEADER:
234
 
            mutter('cache header marker not found at top of %s; discarding cache'
235
 
                   % fn)
 
236
            mutter('cache header marker not found at top of %s;'
 
237
                   ' discarding cache', fn)
236
238
            self.needs_write = True
237
239
            return
238
240
 
245
247
 
246
248
            pos += 3
247
249
            fields = l[pos:].split(' ')
248
 
            if len(fields) != 6:
 
250
            if len(fields) != 7:
249
251
                warning("bad line in hashcache: %r" % l)
250
252
                continue
251
253