Patchwork [6,of,6,V3] revsbetween: default to the C implementation

login
register
mail settings
Submitter Laurent Charignon
Date Aug. 7, 2015, 5:38 p.m.
Message ID <9b3381d8cc3bebd125da.1438969095@dev919.prn2.facebook.com>
Download mbox | patch
Permalink /patch/10139/
State Changes Requested
Headers show

Comments

Laurent Charignon - Aug. 7, 2015, 5:38 p.m.
# HG changeset patch
# User Laurent Charignon <lcharignon@fb.com>
# Date 1438924280 25200
#      Thu Aug 06 22:11:20 2015 -0700
# Branch stable
# Node ID 9b3381d8cc3bebd125da608c36848f940b68f9dd
# Parent  3e52fa2d5b5dfa082f87b4cee52d3580c97833ff
revsbetween: default to the C implementation

This patch is part of a series of patches to speed up the computation of
revset.revsbetween by introducing a C implementation. The main motivation is to
speed up smartlog on big repositories. At the end of the series, on our big
repositories the computation of revsbetween is 10-50x faster and smartlog on is
2x-5x faster.

Before this patch, revsbetween was computed in pure Python by default. This
patch makes the C implementation the default and provides a speedup for
revsbetween.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -78,19 +78,13 @@ 
 
     return generatorset(iterate(), iterasc=True)
 
-def revsbetween(repo, roots, heads, includepath=True):
-    """Return all paths between roots and heads, inclusive of both endpoint
-    sets."""
-    if not roots:
-        return baseset()
+def revsbetweenpure(repo, minroot, roots, heads, includepath):
     parentrevs = repo.changelog.parentrevs
     visit = list(heads)
     reachable = set()
     seen = {}
     # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset
     # (and if it is not, it should.)
-    minroot = min(roots)
-    roots = set(roots)
     # prefetch all the things! (because python is slow)
     reached = reachable.add
     dovisit = visit.append
@@ -118,6 +112,19 @@ 
                 reached(rev)
     return baseset(sorted(reachable))
 
+def revsbetween(repo, roots, heads, includepath=True):
+    """Return all paths between roots and heads, inclusive of both endpoint
+    sets."""
+    if not roots:
+        return baseset()
+    minroot = min(roots)
+    roots = set(roots)
+    heads = list(heads)
+    try:
+        return repo.changelog.revsbetween(minroot, heads, roots, includepath)
+    except AttributeError:
+        return revsbetweenpure(repo, minroot, roots, heads, includepath)
+
 elements = {
     # token-type: binding-strength, primary, prefix, infix, suffix
     "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None),