Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 13259:3b616dfa4b17
revlog: do revlog node->rev mapping by scanning
Now that the nodemap is lazily created, we use linear scanning back
from tip for typical node to rev mapping. Given that nodemap creation
is O(n log n) and revisions searched for are usually very close to
tip, this is often a significant performance win for a small number of
searches.
When we do end up building a nodemap for bulk lookups, the scanning
function is replaced with a hash lookup.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 11 Jan 2011 21:52:03 -0600 |
parents | c2661863f16f |
children | 8439526fb407 |
comparison
equal
deleted
inserted
replaced
13258:c2661863f16f | 13259:3b616dfa4b17 |
---|---|
281 def nodemap(self): | 281 def nodemap(self): |
282 n = {nullid: nullrev} | 282 n = {nullid: nullrev} |
283 i = self.index | 283 i = self.index |
284 for r in xrange(len(i) - 1): | 284 for r in xrange(len(i) - 1): |
285 n[i[r][7]] = r | 285 n[i[r][7]] = r |
286 self.rev = self._revmap | |
286 return n | 287 return n |
287 | 288 |
288 def tip(self): | 289 def tip(self): |
289 return self.node(len(self.index) - 2) | 290 return self.node(len(self.index) - 2) |
290 def __len__(self): | 291 def __len__(self): |
291 return len(self.index) - 1 | 292 return len(self.index) - 1 |
292 def __iter__(self): | 293 def __iter__(self): |
293 for i in xrange(len(self)): | 294 for i in xrange(len(self)): |
294 yield i | 295 yield i |
295 def rev(self, node): | 296 def _revmap(self, node): |
296 try: | 297 try: |
297 return self.nodemap[node] | 298 return self.nodemap[node] |
298 except KeyError: | 299 except KeyError: |
299 raise LookupError(node, self.indexfile, _('no node')) | 300 raise LookupError(node, self.indexfile, _('no node')) |
301 | |
302 def rev(self, node): | |
303 if node == nullid: | |
304 return nullrev | |
305 i = self.index | |
306 for r in xrange(len(i) - 2, -1, -1): | |
307 if i[r][7] == node: | |
308 return r | |
309 raise LookupError(node, self.indexfile, _('no node')) | |
300 def node(self, rev): | 310 def node(self, rev): |
301 return self.index[rev][7] | 311 return self.index[rev][7] |
302 def linkrev(self, rev): | 312 def linkrev(self, rev): |
303 return self.index[rev][4] | 313 return self.index[rev][4] |
304 def parents(self, node): | 314 def parents(self, node): |
709 | 719 |
710 if len(id) < 40: | 720 if len(id) < 40: |
711 try: | 721 try: |
712 # hex(node)[:...] | 722 # hex(node)[:...] |
713 l = len(id) // 2 # grab an even number of digits | 723 l = len(id) // 2 # grab an even number of digits |
714 bin_id = bin(id[:l * 2]) | 724 prefix = bin(id[:l * 2]) |
715 nl = [n for n in self.nodemap if n[:l] == bin_id] | 725 nl = [e[7] for e in self.index if e[7].startswith(prefix)] |
716 nl = [n for n in nl if hex(n).startswith(id)] | 726 nl = [n for n in nl if hex(n).startswith(id)] |
717 if len(nl) > 0: | 727 if len(nl) > 0: |
718 if len(nl) == 1: | 728 if len(nl) == 1: |
719 self._pcache[id] = nl[0] | 729 self._pcache[id] = nl[0] |
720 return nl[0] | 730 return nl[0] |