~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/hashcache.py

  • Committer: Martin Pool
  • Date: 2005-07-22 18:49:46 UTC
  • Revision ID: mbp@sourcefrog.net-20050722184946-4bd334f8c0d75957
- separate out code that just scans the hash cache to find files that are possibly
  changed; don't actually re-read them unless the content has changed

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
        self.miss_count = 0
93
93
        self.stat_count = 0
94
94
        self.danger_count = 0
95
 
        self.gone_count = 0
96
95
        self.removed_count = 0
 
96
        self.update_count = 0
97
97
        self._cache = {}
98
98
 
99
99
 
112
112
            self._cache = {}
113
113
 
114
114
 
115
 
    def refresh_all(self):
116
 
        prep = [(ce[1][3], path) for (path, ce) in self._cache.iteritems()]
 
115
    def scan(self):
 
116
        """Scan all files and remove entries where the cache entry is obsolete.
 
117
        
 
118
        Obsolete entries are those where the file has been modified or deleted
 
119
        since the entry was inserted.        
 
120
        """
 
121
        prep = [(ce[1][3], path, ce) for (path, ce) in self._cache.iteritems()]
117
122
        prep.sort()
118
123
        
119
 
        for inum, path in prep:
120
 
            # we don't really need to re-hash them; we just need to check 
121
 
            # if they're up to date
122
 
            self.get_sha1(path)
 
124
        for inum, path, cache_entry in prep:
 
125
            abspath = os.sep.join([self.basedir, path])
 
126
            fp = _fingerprint(abspath)
 
127
            self.stat_count += 1
 
128
            
 
129
            cache_fp = cache_entry[1]
 
130
    
 
131
            if (not fp) or (cache_fp != fp):
 
132
                # not here or not a regular file anymore
 
133
                self.removed_count += 1
 
134
                self.needs_write = True
 
135
                del self._cache[path]
 
136
 
123
137
 
124
138
 
125
139
    def get_sha1(self, path):
126
140
        """Return the sha1 of a file.
127
141
        """
128
142
        abspath = os.sep.join([self.basedir, path])
129
 
        fp = _fingerprint(abspath)
 
143
        self.stat_count += 1
 
144
        file_fp = _fingerprint(abspath)
 
145
        
 
146
        if not file_fp:
 
147
            # not a regular file or not existing
 
148
            if path in self._cache:
 
149
                self.removed_count += 1
 
150
                self.needs_write = True
 
151
                del self._cache[path]
 
152
            return None        
130
153
 
131
 
        c = self._cache.get(path)
132
 
        if c:
133
 
            cache_sha1, cache_fp = c
 
154
        if path in self._cache:
 
155
            cache_sha1, cache_fp = self._cache[path]
134
156
        else:
135
157
            cache_sha1, cache_fp = None, None
136
158
 
137
 
        self.stat_count += 1
138
 
 
139
 
        if not fp:
140
 
            # not a regular file
141
 
            if path in self._cache:
142
 
                self.removed_count += 1
143
 
                self.needs_write = True
144
 
                del self._cache[path]
145
 
            return None
146
 
        elif cache_fp and (cache_fp == fp):
 
159
        if cache_fp == file_fp:
147
160
            self.hit_count += 1
148
161
            return cache_sha1
 
162
        
 
163
        self.miss_count += 1
 
164
        digest = sha_file(file(abspath, 'rb', buffering=65000))
 
165
 
 
166
        now = int(time.time())
 
167
        if file_fp[1] >= now or file_fp[2] >= now:
 
168
            # changed too recently; can't be cached.  we can
 
169
            # return the result and it could possibly be cached
 
170
            # next time.
 
171
            self.danger_count += 1 
 
172
            if cache_fp:
 
173
                self.removed_count += 1
 
174
                self.needs_write = True
 
175
                del self._cache[path]
149
176
        else:
150
 
            self.miss_count += 1
151
 
            digest = sha_file(file(abspath, 'rb', buffering=65000))
152
 
 
153
 
            now = int(time.time())
154
 
            if fp[1] >= now or fp[2] >= now:
155
 
                # changed too recently; can't be cached.  we can
156
 
                # return the result and it could possibly be cached
157
 
                # next time.
158
 
                self.danger_count += 1 
159
 
                if cache_fp:
160
 
                    self.removed_count += 1
161
 
                    self.needs_write = True
162
 
                    del self._cache[path]
163
 
            elif (fp != cache_fp) or (digest != cache_sha1):
164
 
#                 mutter("update entry for %s" % path)
165
 
#                 mutter("  %r" % (fp,))
166
 
#                 mutter("  %r" % (cache_fp,))
167
 
                self.needs_write = True
168
 
                self._cache[path] = (digest, fp)
169
 
            else:
170
 
                # huh?
171
 
                assert 0
172
 
            
173
 
            return digest
174
 
            
 
177
            self.update_count += 1
 
178
            self.needs_write = True
 
179
            self._cache[path] = (digest, file_fp)
 
180
        
 
181
        return digest
 
182
        
175
183
 
176
184
 
177
185