changeset 26006:1ffd97cbf9a2

reachableroots: default to the C implementation This patch is part of a series of patches to speed up the computation of revset.reachableroots 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 reachableroots is 10-50x faster and smartlog on is 2x-5x faster. Before this patch, reachableroots was computed in pure Python by default. This patch makes the C implementation the default and provides a speedup for reachableroots.
author Laurent Charignon <lcharignon@fb.com>
date Thu, 06 Aug 2015 22:11:20 -0700
parents 6f4a280298c1
children 1ebf4ac07582
files mercurial/revset.py
diffstat 1 files changed, 17 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Thu Aug 06 22:10:31 2015 -0700
+++ b/mercurial/revset.py	Thu Aug 06 22:11:20 2015 -0700
@@ -87,7 +87,7 @@
 
     return generatorset(iterate(), iterasc=True)
 
-def reachableroots(repo, roots, heads, includepath=False):
+def reachablerootspure(repo, minroot, roots, heads, includepath):
     """return (heads(::<roots> and ::<heads>))
 
     If includepath is True, return (<roots>::<heads>)."""
@@ -97,10 +97,6 @@
     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
@@ -128,6 +124,22 @@
                 reached(rev)
     return baseset(sorted(reachable))
 
+def reachableroots(repo, roots, heads, includepath=False):
+    """return (heads(::<roots> and ::<heads>))
+
+    If includepath is True, return (<roots>::<heads>)."""
+    if not roots:
+        return baseset()
+    # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset
+    # (and if it is not, it should.)
+    minroot = min(roots)
+    roots = set(roots)
+    heads = list(heads)
+    try:
+        return repo.changelog.reachableroots(minroot, heads, roots, includepath)
+    except AttributeError:
+        return reachablerootspure(repo, minroot, roots, heads, includepath)
+
 elements = {
     # token-type: binding-strength, primary, prefix, infix, suffix
     "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None),