Patchwork D6506: revlog: speed up isancestor

login
register
mail settings
Submitter phabricator
Date June 12, 2019, 4:45 p.m.
Message ID <40679b7600426d12dba31c11d9229440@localhost.localdomain>
Download mbox | patch
Permalink /patch/40447/
State Not Applicable
Headers show

Comments

phabricator - June 12, 2019, 4:45 p.m.
Closed by commit rHG055c3e2c44f0: revlog: speed up isancestor (authored by valentin.gatienbaron).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6506?vs=15429&id=15456

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6506/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6506

AFFECTED FILES
  mercurial/changelog.py
  mercurial/dagop.py
  mercurial/revlog.py

CHANGE DETAILS




To: valentin.gatienbaron, indygreg, #hg-reviewers
Cc: durin42, mercurial-devel

Patch

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1216,14 +1216,25 @@ 
         A revision is considered an ancestor of itself.
 
         The implementation of this is trivial but the use of
-        commonancestorsheads is not."""
+        reachableroots is not."""
         if a == nullrev:
             return True
         elif a == b:
             return True
         elif a > b:
             return False
-        return a in self._commonancestorsheads(a, b)
+        return bool(self.reachableroots(a, [b], [a], includepath=False))
+
+    def reachableroots(self, minroot, heads, roots, includepath=False):
+        """return (heads(::<roots> and <roots>::<heads>))
+
+        If includepath is True, return (<roots>::<heads>)."""
+        try:
+            return self.index.reachableroots2(minroot, heads, roots,
+                                              includepath)
+        except AttributeError:
+            return dagop._reachablerootspure(self.parentrevs,
+                                             minroot, roots, heads, includepath)
 
     def ancestor(self, a, b):
         """calculate the "best" common ancestor of nodes a and b"""
diff --git a/mercurial/dagop.py b/mercurial/dagop.py
--- a/mercurial/dagop.py
+++ b/mercurial/dagop.py
@@ -259,11 +259,10 @@ 
                 yield rev
                 break
 
-def _reachablerootspure(repo, minroot, roots, heads, includepath):
-    """See reachableroots"""
+def _reachablerootspure(pfunc, minroot, roots, heads, includepath):
+    """See revlog.reachableroots"""
     if not roots:
         return []
-    parentrevs = repo.changelog.parentrevs
     roots = set(roots)
     visit = list(heads)
     reachable = set()
@@ -280,7 +279,7 @@ 
             reached(rev)
             if not includepath:
                 continue
-        parents = parentrevs(rev)
+        parents = pfunc(rev)
         seen[rev] = parents
         for parent in parents:
             if parent >= minroot and parent not in seen:
@@ -296,18 +295,13 @@ 
     return reachable
 
 def reachableroots(repo, roots, heads, includepath=False):
-    """return (heads(::<roots> and <roots>::<heads>))
-
-    If includepath is True, return (<roots>::<heads>)."""
+    """See revlog.reachableroots"""
     if not roots:
         return baseset()
     minroot = roots.min()
     roots = list(roots)
     heads = list(heads)
-    try:
-        revs = repo.changelog.reachableroots(minroot, heads, roots, includepath)
-    except AttributeError:
-        revs = _reachablerootspure(repo, minroot, roots, heads, includepath)
+    revs = repo.changelog.reachableroots(minroot, heads, roots, includepath)
     revs = baseset(revs)
     revs.sort()
     return revs
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -420,9 +420,6 @@ 
             if i not in self.filteredrevs:
                 yield i
 
-    def reachableroots(self, minroot, heads, roots, includepath=False):
-        return self.index.reachableroots2(minroot, heads, roots, includepath)
-
     def _checknofilteredinrevs(self, revs):
         """raise the appropriate error if 'revs' contains a filtered revision