ANN: hg graphlog extension

Alexis S. L. Carvalho alexis at cecm.usp.br
Sun Apr 8 07:26:59 UTC 2007


Thus spake Joel Rosdahl:
> Done. Current performance in the linux-2.6 repo on my box:
> 
> hg glog -q > /dev/null # --> 8.0 seconds
> hg log -q > /dev/null # --> 4.1 seconds

Turns out that glog was hitting a performance buglet in revlog.py.
After fixing it (changeset 43dedce9667e), in my (not up to date) kernel
repo, the time goes from ~6.9s to ~6.3s (log -q is still around 3.8s).

The patch below changes revision_grapher to walk the changeset graph
using revision numbers instead of nodes - this is usually a bit faster,
since the graph is stored using numbers, not nodes.  The running time
goes to ~5.6s.

Alexis

# HG changeset patch
# User Alexis S. L. Carvalho <alexis at cecm.usp.br>
# Date 1176016277 10800
# Node ID 6fdbc3df86cceac27e8838c0518a20d89d427ae8
# Parent  8d0bbc825ac0a46a550cab519d80c91c737e3884
Walk the changeset graph using revision numbers, not nodes.

diff -r 8d0bbc825ac0 -r 6fdbc3df86cc graphlog.py
--- a/graphlog.py	Sun Apr 08 04:02:49 2007 -0300
+++ b/graphlog.py	Sun Apr 08 04:11:17 2007 -0300
@@ -45,42 +45,42 @@ def revision_grapher(repo, start_rev, st
 
     assert start_rev >= stop_rev
     rev = start_rev
-    nodes = []
+    revs = []
     while rev >= stop_rev:
         node = repo.changelog.node(rev)
 
         # Compute nodes and next nodes.
-        if node not in nodes:
-            # New head node.
-            nodes.append(node)
-        node_index = nodes.index(node)
-        next_nodes = nodes[:]
-
-        # Add parents to next nodes.
-        parents = get_node_parents(repo, node)
+        if rev not in revs:
+            # New head rev.
+            revs.append(rev)
+        rev_index = revs.index(rev)
+        next_revs = revs[:]
+
+        # Add parents to next revs.
+        parents = get_rev_parents(repo, rev)
         parents_to_add = []
         for parent in parents:
-            if parent not in next_nodes:
+            if parent not in next_revs:
                 parents_to_add.append(parent)
         if len(parents_to_add) == 0:
-            del next_nodes[node_index]
-        else:
-            next_nodes[node_index] = parents_to_add[0]
+            del next_revs[rev_index]
+        else:
+            next_revs[rev_index] = parents_to_add[0]
             if len(parents_to_add) == 2:
-                next_nodes.insert(node_index, parents_to_add[1])
+                next_revs.insert(rev_index, parents_to_add[1])
 
         edges = []
         for parent in parents:
-            edges.append((node_index, next_nodes.index(parent)))
-
-        n_nodes_diff = len(next_nodes) - len(nodes)
-        yield (rev, node, node_index, edges, len(nodes), n_nodes_diff)
-
-        nodes = next_nodes
+            edges.append((rev_index, next_revs.index(parent)))
+
+        n_revs_diff = len(next_revs) - len(revs)
+        yield (rev, node, rev_index, edges, len(revs), n_revs_diff)
+
+        revs = next_revs
         rev -= 1
 
-def get_node_parents(repo, node):
-    return [x for x in repo.changelog.parents(node) if x != nullid]
+def get_rev_parents(repo, rev):
+    return [x for x in repo.changelog.parentrevs(rev) if x != nullrev]
 
 def fix_cross_edge(edges):
     for (i, (start, end)) in enumerate(edges):



More information about the Mercurial mailing list