[PATCH 4 of 9 "] discovery: use a lower level but faster way to retrieve parents

Pierre-Yves David pierre-yves.david at ens-lyon.org
Tue Mar 5 12:39:15 EST 2019


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at octobus.net>
# Date 1551311787 -3600
#      Thu Feb 28 00:56:27 2019 +0100
# Node ID ffd98d208aa7f92e13bf233b6d752cd2d292ebbe
# Parent  82035c1d714f8f3911632ea1271002745fc620f4
# EXP-Topic discovery-speedup
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r ffd98d208aa7
discovery: use a lower level but faster way to retrieve parents

We already know that no revision in the undecided set are filtered, so we can
skip multiple checks and directly access lower level data.

In a private pathological case, this improves the timing from about 70 seconds
to about 50 seconds. There are other actions to be taken to improve that case,
however this gives an idea of the general overhead.

diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py
--- a/mercurial/setdiscovery.py
+++ b/mercurial/setdiscovery.py
@@ -165,6 +165,12 @@ class partialdiscovery(object):
         # common.bases and all its ancestors
         return self._common.basesheads()
 
+    def _parentsgetter(self):
+        getrev = self._repo.changelog.index.__getitem__
+        def getparents(r):
+            return getrev(r)[5:6]
+        return getparents
+
     def takequicksample(self, headrevs, size):
         """takes a quick sample of size <size>
 
@@ -181,7 +187,7 @@ class partialdiscovery(object):
         if len(sample) >= size:
             return _limitsample(sample, size)
 
-        _updatesample(None, headrevs, sample, self._repo.changelog.parentrevs,
+        _updatesample(None, headrevs, sample, self._parentsgetter(),
                       quicksamplesize=size)
         return sample
 
@@ -191,10 +197,11 @@ class partialdiscovery(object):
             return list(revs)
         repo = self._repo
         sample = set(repo.revs('heads(%ld)', revs))
+        parentrevs = self._parentsgetter()
 
         # update from heads
         revsheads = sample.copy()
-        _updatesample(revs, revsheads, sample, repo.changelog.parentrevs)
+        _updatesample(revs, revsheads, sample, parentrevs)
 
         # update from roots
         revsroots = set(repo.revs('roots(%ld)', revs))
@@ -209,7 +216,6 @@ class partialdiscovery(object):
         # this by keeping a persistent cache of children across invocations.
         children = {}
 
-        parentrevs = repo.changelog.parentrevs
         for rev in repo.changelog.revs(start=min(revsroots)):
             # Always ensure revision has an entry so we don't need to worry
             # about missing keys.


More information about the Mercurial-devel mailing list