[PATCH 5 of 6 v6] localrepo: convert _updatebranchcache from nodespace to revspace

Joshua Redstone joshua.redstone at fb.com
Fri Jun 8 16:27:42 CDT 2012


# HG changeset patch
# User Joshua Redstone <joshua.redstone at fb.com>
# Date 1338566177 25200
# Node ID 8034be1f0da7ccd9e4ddd8ad6cd68e3cd45d631c
# Parent  7c3743522de855a2cee411341ce6f63c15c02ee9
localrepo: convert _updatebranchcache from nodespace to revspace

_updatebranchcache used to use revlog.reachable.  After the switch to
revlog.ancestors, we can now clean it up a bit and switch the algorithm from
nodes to revs.

This also fixes a small performance bug.  The function would iterate over new
candidate heads in order from oldest to newest, in contrast to the comment that
observes that iterating from newest to oldest results in fewer pases over the
set of reachable nodes.

diff -r 7c3743522de8 -r 8034be1f0da7 mercurial/localrepo.py
--- a/mercurial/localrepo.py	Fri Jun 08 14:23:31 2012 -0700
+++ b/mercurial/localrepo.py	Fri Jun 01 08:56:17 2012 -0700
@@ -574,29 +574,26 @@
         # collect new branch entries
         newbranches = {}
         for c in ctxgen:
-            newbranches.setdefault(c.branch(), []).append(c.node())
+            newbranches.setdefault(c.branch(), []).append(c.rev())
         # if older branchheads are reachable from new ones, they aren't
         # really branchheads. Note checking parents is insufficient:
         # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
-        for branch, newnodes in newbranches.iteritems():
-            bheads = partial.setdefault(branch, [])
-            bheads.extend(newnodes)
-            if len(bheads) <= 1:
-                continue
-            bheads = sorted(bheads, key=lambda x: self[x].rev())
+        for branch, newrevs in newbranches.iteritems():
+            bheadrevs = [self.changelog.rev(node) for node in
+                         partial.setdefault(branch, [])]
+            bheadrevs.extend(newrevs)
+            bheadrevs.sort()
             # starting from tip means fewer passes over reachable
-            while newnodes:
-                latest = newnodes.pop()
-                if latest not in bheads:
+            newrevs.sort(reverse=True)
+            while newrevs:
+                latest = newrevs.pop()
+                if latest not in bheadrevs:
                     continue
-                minbhnode = self[bheads[0]].node()
-                cl = self.changelog
-                ancestors = cl.ancestors([cl.rev(latest)],
-                                          cl.rev(minbhnode))
-                reachable = [cl.node(rev) for rev in ancestors]
-                if reachable:
-                    bheads = [b for b in bheads if b not in reachable]
-            partial[branch] = bheads
+                ancestors = set(self.changelog.ancestors([latest],
+                                                         bheadrevs[0]))
+                if ancestors:
+                    bheadrevs = [b for b in bheadrevs if b not in ancestors]
+            partial[branch] = [self.changelog.node(rev) for rev in bheadrevs]
 
     def lookup(self, key):
         return self[key].node()


More information about the Mercurial-devel mailing list