comparison mercurial/localrepo.py @ 14056:bcfe78c3d15c

branchcache: improve speed relative to the amount of heads Updating the branch cache is quadratic to the amount of heads in the repository. One consequence of this was that cloning a pathological repository with 10,000 heads (and nothing else) took hours of CPU time. This patch makes one of the inner loop much faster, by removing a changectx instantiation, and removes another entirely in cases where there are no candidate branch heads which descend from other branch heads.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Sat, 30 Apr 2011 12:56:28 +0200
parents 58e58406ed19
children e4bfb9c337f3
comparison
equal deleted inserted replaced
14055:421d56a055fd 14056:bcfe78c3d15c
507 for branch, newnodes in newbranches.iteritems(): 507 for branch, newnodes in newbranches.iteritems():
508 bheads = partial.setdefault(branch, []) 508 bheads = partial.setdefault(branch, [])
509 bheads.extend(newnodes) 509 bheads.extend(newnodes)
510 if len(bheads) <= 1: 510 if len(bheads) <= 1:
511 continue 511 continue
512 bheads = sorted(bheads, key=lambda x: self[x].rev())
512 # starting from tip means fewer passes over reachable 513 # starting from tip means fewer passes over reachable
513 while newnodes: 514 while newnodes:
514 latest = newnodes.pop() 515 latest = newnodes.pop()
515 if latest not in bheads: 516 if latest not in bheads:
516 continue 517 continue
517 minbhrev = self[min([self[bh].rev() for bh in bheads])].node() 518 minbhrev = self[bheads[0]].node()
518 reachable = self.changelog.reachable(latest, minbhrev) 519 reachable = self.changelog.reachable(latest, minbhrev)
519 reachable.remove(latest) 520 reachable.remove(latest)
520 bheads = [b for b in bheads if b not in reachable] 521 if reachable:
522 bheads = [b for b in bheads if b not in reachable]
521 partial[branch] = bheads 523 partial[branch] = bheads
522 524
523 def lookup(self, key): 525 def lookup(self, key):
524 if isinstance(key, int): 526 if isinstance(key, int):
525 return self.changelog.node(key) 527 return self.changelog.node(key)