Patchwork [5,of,6,V5] changelog: add way to call the reachableroots C implementation

login
register
mail settings
Submitter Pierre-Yves David
Date Aug. 7, 2015, 9:06 p.m.
Message ID <62d61128bd7d35f668b3.1438981614@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/10156/
State Accepted
Headers show

Comments

Pierre-Yves David - Aug. 7, 2015, 9:06 p.m.
# HG changeset patch
# User Laurent Charignon <lcharignon@fb.com>
# Date 1438924231 25200
#      Thu Aug 06 22:10:31 2015 -0700
# Node ID 62d61128bd7d35f668b3ff982567b2976601f616
# Parent  04da30178f96b68a4d2a9b019f927f1944d62075
changelog: add way to call the reachableroots 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.

This patch allows us to call the new C implementation of reachableroots from
python by creating an entry point in the changelog class.

Patch

diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -5,11 +5,11 @@ 
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
 from node import bin, hex, nullid
 from i18n import _
-import util, error, revlog, encoding
+import util, error, revlog, encoding, revset
 
 _defaultextra = {'branch': 'default'}
 
 def _string_escape(text):
     """
@@ -170,10 +170,20 @@  class changelog(revlog.revlog):
     def nodemap(self):
         # XXX need filtering too
         self.rev(self.node(0))
         return self._nodecache
 
+    def reachableroots(self, minroot, heads, roots, includepath=False):
+        reachable = self.index.reachableroots(minroot, heads, roots,
+                                              includepath)
+        if reachable is None:
+            # The C code hasn't been able to initialize a list, something went
+            # really wrong, let's rely on the pure implementation in that case
+            raise AttributeError()
+        else:
+            return revset.baseset(sorted(reachable))
+
     def headrevs(self):
         if self.filteredrevs:
             try:
                 return self.index.headrevsfiltered(self.filteredrevs)
             # AttributeError covers non-c-extension environments and