~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/hashcache.py

  • Committer: Martin Pool
  • Date: 2005-09-29 05:06:14 UTC
  • mto: (1185.12.2) (1393.1.12)
  • mto: This revision was merged to the branch mainline in revision 1396.
  • Revision ID: mbp@sourcefrog.net-20050929050614-a41e6f72af36bb4c
- better error on failing to import bzrlib

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