diff mercurial/scmutil.py @ 38892:3588e41f796d

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
author Martin von Zweigbergk <martinvonz@google.com>
date Tue, 17 Apr 2018 11:16:59 -0700
parents 6f7c9527030b
children 531b86cc8fb3
line wrap: on
line diff
--- 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):