shortest: cache disambiguation revset
authorMartin von Zweigbergk <martinvonz@google.com>
Tue, 17 Apr 2018 11:16:59 -0700
changeset 38853 3588e41f796d
parent 38852 a3dacabd476b
child 38854 531b86cc8fb3
shortest: cache disambiguation revset This makes it actually useful. In compared the time in my hg repo with 69.6k revisions and with a disambiguation revset of "not public()" that matches 563 visible revisions. I ran "time hg log -T '{shortest(node1,)}' -r 0:1000" (no revisions within the revset in that revision range). Before this patch, it took 57s and after it took 0.7s. Differential Revision: https://phab.mercurial-scm.org/D4039
mercurial/scmutil.py
mercurial/templatefuncs.py
--- a/mercurial/scmutil.py	Fri Jul 20 14:36:42 2018 -0700
+++ b/mercurial/scmutil.py	Tue Apr 17 11:16:59 2018 -0700
@@ -462,8 +462,12 @@
     repo.changelog.rev(node)  # make sure node isn't filtered
     return node
 
-def shortesthexnodeidprefix(repo, node, minlength=1):
-    """Find the shortest unambiguous prefix that matches hexnode."""
+def shortesthexnodeidprefix(repo, node, minlength=1, cache=None):
+    """Find the shortest unambiguous prefix that matches hexnode.
+
+    If "cache" is not None, it must be a dictionary that can be used for
+    caching between calls to this method.
+    """
     # _partialmatch() of filtered changelog could take O(len(repo)) time,
     # which would be unacceptably slow. so we look for hash collision in
     # unfiltered space, which means some hashes may be slightly longer.
@@ -491,7 +495,13 @@
 
     revset = repo.ui.config('experimental', 'revisions.disambiguatewithin')
     if revset:
-        revs = repo.anyrevs([revset], user=True)
+        revs = None
+        if cache is not None:
+            revs = cache.get('disambiguationrevset')
+        if revs is None:
+            revs = repo.anyrevs([revset], user=True)
+            if cache is not None:
+                cache['disambiguationrevset'] = revs
         if cl.rev(node) in revs:
             hexnode = hex(node)
             for length in range(minlength, len(hexnode) + 1):
--- a/mercurial/templatefuncs.py	Fri Jul 20 14:36:42 2018 -0700
+++ b/mercurial/templatefuncs.py	Tue Apr 17 11:16:59 2018 -0700
@@ -596,7 +596,7 @@
             yield sep
         yield argstr
 
-@templatefunc('shortest(node, minlength=4)', requires={'repo'})
+@templatefunc('shortest(node, minlength=4)', requires={'repo', 'cache'})
 def shortest(context, mapping, args):
     """Obtain the shortest representation of
     a node."""
@@ -629,8 +629,9 @@
             return hexnode
         if not node:
             return hexnode
+    cache = context.resource(mapping, 'cache')
     try:
-        return scmutil.shortesthexnodeidprefix(repo, node, minlength)
+        return scmutil.shortesthexnodeidprefix(repo, node, minlength, cache)
     except error.RepoLookupError:
         return hexnode