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]