discovery: move children computation in its own method
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 28 Feb 2019 01:15:45 +0100
changeset 41884 d5e6ae6e8012
parent 41883 1f069f37e601
child 41885 5baf06d2bb41
discovery: move children computation in its own method This clarifies the main logic and starts to pave the way to some caching.
mercurial/setdiscovery.py
--- a/mercurial/setdiscovery.py	Tue Mar 05 15:39:54 2019 +0100
+++ b/mercurial/setdiscovery.py	Thu Feb 28 01:15:45 2019 +0100
@@ -171,6 +171,32 @@
             return getrev(r)[5:6]
         return getparents
 
+    def _childrengetter(self, revs):
+
+        # _updatesample() essentially does interaction over revisions to look
+        # up their children. This lookup is expensive and doing it in a loop is
+        # quadratic. We precompute the children for all relevant revisions and
+        # make the lookup in _updatesample() a simple dict lookup.
+        #
+        # Because this function can be called multiple times during discovery,
+        # we may still perform redundant work and there is room to optimize
+        # this by keeping a persistent cache of children across invocations.
+        children = {}
+
+        parentrevs = self._parentsgetter()
+
+        for rev in sorted(revs):
+            # Always ensure revision has an entry so we don't need to worry
+            # about missing keys.
+            children[rev] = []
+            for prev in parentrevs(rev):
+                if prev == nullrev:
+                    continue
+                c = children.get(prev)
+                if c is not None:
+                    c.append(rev)
+        return children.__getitem__
+
     def takequicksample(self, headrevs, size):
         """takes a quick sample of size <size>
 
@@ -206,28 +232,9 @@
         # update from roots
         revsroots = set(repo.revs('roots(%ld)', revs))
 
-        # _updatesample() essentially does interaction over revisions to look
-        # up their children. This lookup is expensive and doing it in a loop is
-        # quadratic. We precompute the children for all relevant revisions and
-        # make the lookup in _updatesample() a simple dict lookup.
-        #
-        # Because this function can be called multiple times during discovery,
-        # we may still perform redundant work and there is room to optimize
-        # this by keeping a persistent cache of children across invocations.
-        children = {}
+        childrenrevs = self._childrengetter(revs)
 
-        for rev in sorted(revs):
-            # Always ensure revision has an entry so we don't need to worry
-            # about missing keys.
-            children[rev] = []
-            for prev in parentrevs(rev):
-                if prev == nullrev:
-                    continue
-                c = children.get(prev)
-                if c is not None:
-                    c.append(rev)
-
-        _updatesample(revs, revsroots, sample, children.__getitem__)
+        _updatesample(revs, revsroots, sample, childrenrevs)
         assert sample
         sample = _limitsample(sample, size)
         if len(sample) < size: