Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 13275:68da048b4c88
revlog: incrementally build node cache with linear searches
This avoids needing to prime the cache for operations like verify
which visit most or all of the index.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 18 Jan 2011 15:55:46 -0600 |
parents | fff12b3d953a |
children | ba6a63339f7c |
comparison
equal
deleted
inserted
replaced
13274:57d433f632b7 | 13275:68da048b4c88 |
---|---|
174 self.size = struct.calcsize(indexformatng) | 174 self.size = struct.calcsize(indexformatng) |
175 | 175 |
176 def parseindex(self, data, inline): | 176 def parseindex(self, data, inline): |
177 # call the C implementation to parse the index data | 177 # call the C implementation to parse the index data |
178 index, cache = parsers.parse_index2(data, inline) | 178 index, cache = parsers.parse_index2(data, inline) |
179 nodemap = None | 179 return index, None, cache |
180 if not data: | |
181 nodemap = {nullid: nullrev} | |
182 return index, nodemap, cache | |
183 | 180 |
184 def packentry(self, entry, node, version, rev): | 181 def packentry(self, entry, node, version, rev): |
185 p = _pack(indexformatng, *entry) | 182 p = _pack(indexformatng, *entry) |
186 if rev == 0: | 183 if rev == 0: |
187 p = _pack(versionformat, version) + p[4:] | 184 p = _pack(versionformat, version) + p[4:] |
226 self._chunkcache = (0, '') | 223 self._chunkcache = (0, '') |
227 self.index = [] | 224 self.index = [] |
228 self._shallowroot = shallowroot | 225 self._shallowroot = shallowroot |
229 self._parentdelta = 0 | 226 self._parentdelta = 0 |
230 self._pcache = {} | 227 self._pcache = {} |
228 self._nodecache = {nullid: nullrev} | |
229 self._nodepos = None | |
231 | 230 |
232 v = REVLOG_DEFAULT_VERSION | 231 v = REVLOG_DEFAULT_VERSION |
233 if hasattr(opener, 'options') and 'defversion' in opener.options: | 232 if hasattr(opener, 'options') and 'defversion' in opener.options: |
234 v = opener.options['defversion'] | 233 v = opener.options['defversion'] |
235 if v & REVLOGNG: | 234 if v & REVLOGNG: |
272 d = self._io.parseindex(i, self._inline) | 271 d = self._io.parseindex(i, self._inline) |
273 except (ValueError, IndexError): | 272 except (ValueError, IndexError): |
274 raise RevlogError(_("index %s is corrupted") % (self.indexfile)) | 273 raise RevlogError(_("index %s is corrupted") % (self.indexfile)) |
275 self.index, nodemap, self._chunkcache = d | 274 self.index, nodemap, self._chunkcache = d |
276 if nodemap is not None: | 275 if nodemap is not None: |
277 self.nodemap = nodemap | 276 self.nodemap = self._nodecache = nodemap |
278 self.rev = self._revmap | |
279 if not self._chunkcache: | 277 if not self._chunkcache: |
280 self._chunkclear() | 278 self._chunkclear() |
281 | |
282 @util.propertycache | |
283 def nodemap(self): | |
284 n = {nullid: nullrev} | |
285 i = self.index | |
286 for r in xrange(len(i) - 1): | |
287 n[i[r][7]] = r | |
288 self.rev = self._revmap | |
289 return n | |
290 | 279 |
291 def tip(self): | 280 def tip(self): |
292 return self.node(len(self.index) - 2) | 281 return self.node(len(self.index) - 2) |
293 def __len__(self): | 282 def __len__(self): |
294 return len(self.index) - 1 | 283 return len(self.index) - 1 |
295 def __iter__(self): | 284 def __iter__(self): |
296 for i in xrange(len(self)): | 285 for i in xrange(len(self)): |
297 yield i | 286 yield i |
298 def _revmap(self, node): | 287 |
288 @util.propertycache | |
289 def nodemap(self): | |
290 n = self.rev(self.node(0)) | |
291 return self._nodecache | |
292 | |
293 def rev(self, node): | |
299 try: | 294 try: |
300 return self.nodemap[node] | 295 return self._nodecache[node] |
301 except KeyError: | 296 except KeyError: |
297 n = self._nodecache | |
298 if node in n: | |
299 return n[node] | |
300 i = self.index | |
301 p = self._nodepos | |
302 if p is None: | |
303 p = len(i) - 2 | |
304 for r in xrange(p, -1, -1): | |
305 v = i[r][7] | |
306 n[v] = r | |
307 if v == node: | |
308 self._nodepos = r - 1 | |
309 return r | |
302 raise LookupError(node, self.indexfile, _('no node')) | 310 raise LookupError(node, self.indexfile, _('no node')) |
303 | 311 |
304 def rev(self, node): | |
305 if node == nullid: | |
306 return nullrev | |
307 i = self.index | |
308 for r in xrange(len(i) - 2, -1, -1): | |
309 if i[r][7] == node: | |
310 return r | |
311 raise LookupError(node, self.indexfile, _('no node')) | |
312 def node(self, rev): | 312 def node(self, rev): |
313 return self.index[rev][7] | 313 return self.index[rev][7] |
314 def linkrev(self, rev): | 314 def linkrev(self, rev): |
315 return self.index[rev][4] | 315 return self.index[rev][4] |
316 def parents(self, node): | 316 def parents(self, node): |