~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/hashcache.py

[merge] jam-integration

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
import os, stat, time
33
33
import sha
34
34
 
35
 
from bzrlib.osutils import sha_file
 
35
from bzrlib.osutils import sha_file, pathjoin
36
36
from bzrlib.trace import mutter, warning
37
37
from bzrlib.atomicfile import AtomicFile
38
 
 
39
 
 
 
38
from bzrlib.errors import BzrError
 
39
 
 
40
 
 
41
FP_MTIME_COLUMN = 1
 
42
FP_CTIME_COLUMN = 2
40
43
FP_MODE_COLUMN = 5
41
44
 
42
45
def _fingerprint(abspath):
104
107
    def cache_file_name(self):
105
108
        # FIXME: duplicate path logic here, this should be 
106
109
        # something like 'branch.controlfile'.
107
 
        return os.sep.join([self.basedir, '.bzr', 'stat-cache'])
 
110
        return pathjoin(self.basedir, '.bzr', 'stat-cache')
108
111
 
109
112
    def clear(self):
110
113
        """Discard all cached information.
125
128
        prep.sort()
126
129
        
127
130
        for inum, path, cache_entry in prep:
128
 
            abspath = os.sep.join([self.basedir, path])
 
131
            abspath = pathjoin(self.basedir, path)
129
132
            fp = _fingerprint(abspath)
130
133
            self.stat_count += 1
131
134
            
141
144
    def get_sha1(self, path):
142
145
        """Return the sha1 of a file.
143
146
        """
144
 
        abspath = os.sep.join([self.basedir, path])
 
147
        abspath = pathjoin(self.basedir, path)
145
148
        self.stat_count += 1
146
149
        file_fp = _fingerprint(abspath)
147
150
        
169
172
        if stat.S_ISREG(mode):
170
173
            digest = sha_file(file(abspath, 'rb', buffering=65000))
171
174
        elif stat.S_ISLNK(mode):
172
 
            link_target = os.readlink(abspath)
173
175
            digest = sha.new(os.readlink(abspath)).hexdigest()
174
176
        else:
175
177
            raise BzrError("file %r: unknown file stat mode: %o"%(abspath,mode))
176
178
 
177
179
        now = int(time.time())
178
 
        if file_fp[1] >= now or file_fp[2] >= now:
 
180
        if file_fp[FP_MTIME_COLUMN] >= now or file_fp[FP_CTIME_COLUMN] >= now:
179
181
            # changed too recently; can't be cached.  we can
180
182
            # return the result and it could possibly be cached
181
183
            # next time.
 
184
            #
 
185
            # the point is that we only want to cache when we are sure that any
 
186
            # subsequent modifications of the file can be detected.  If a
 
187
            # modification neither changes the inode, the device, the size, nor
 
188
            # the mode, then we can only distinguish it by time; therefore we
 
189
            # need to let sufficient time elapse before we may cache this entry
 
190
            # again.  If we didn't do this, then, for example, a very quick 1
 
191
            # byte replacement in the file might go undetected.
182
192
            self.danger_count += 1 
183
193
            if cache_fp:
184
194
                self.removed_count += 1
210
220
        finally:
211
221
            if not outf.closed:
212
222
                outf.abort()
213
 
        
214
 
 
215
223
 
216
224
    def read(self):
217
225
        """Reinstate cache from file.
226
234
        try:
227
235
            inf = file(fn, 'rb', buffering=65000)
228
236
        except IOError, e:
229
 
            mutter("failed to open %s: %s" % (fn, e))
 
237
            mutter("failed to open %s: %s", fn, e)
230
238
            # better write it now so it is valid
231
239
            self.needs_write = True
232
240
            return
234
242
 
235
243
        hdr = inf.readline()
236
244
        if hdr != CACHE_HEADER:
237
 
            mutter('cache header marker not found at top of %s; discarding cache'
238
 
                   % fn)
 
245
            mutter('cache header marker not found at top of %s;'
 
246
                   ' discarding cache', fn)
239
247
            self.needs_write = True
240
248
            return
241
249