diff mercurial/dagop.py @ 42462:055c3e2c44f0

revlog: speed up isancestor Currently, it is implemented on top of commonancestorsheads. Implement it on top of reachableroots instead, as reachableroots could stop walking the graph much sooner than commonancestorsheads. Measuring repo.changelog.isancestorrev on two revisions in a private repository: before: ! wall 0.005175 comb 0.010000 user 0.010000 sys 0.000000 (best of 550) after : ! wall 0.000072 comb 0.000000 user 0.000000 sys 0.000000 (best of 36199) When hg does this kind of operations 1500 times in pull -> bookmarks.comparebookmarks -> bookmarks.validdest, that's 11s that drop from the --profile output. Differential Revision: https://phab.mercurial-scm.org/D6506
author Valentin Gatien-Baron <vgatien-baron@janestreet.com>
date Mon, 10 Jun 2019 13:23:14 -0400
parents 3e42fc243741
children 2372284d9457
line wrap: on
line diff
--- a/mercurial/dagop.py	Mon Jun 10 11:40:43 2019 -0400
+++ b/mercurial/dagop.py	Mon Jun 10 13:23:14 2019 -0400
@@ -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