Patchwork [3,of,4] templater: remember cache key of evaluated revset

login
register
mail settings
Submitter Yuya Nishihara
Date March 24, 2020, 2:42 p.m.
Message ID <d686edd2bf8868661260.1585060955@mimosa>
Download mbox | patch
Permalink /patch/45872/
State Accepted
Headers show

Comments

Yuya Nishihara - March 24, 2020, 2:42 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1584255645 -32400
#      Sun Mar 15 16:00:45 2020 +0900
# Node ID d686edd2bf8868661260854dfbe37292fec79b4c
# Parent  2149f8b5c2eeb0cab6cc6aafb06db7cb7370253d
templater: remember cache key of evaluated revset

This provides a hint for caching further computation result of the given
revset. See the next patch for example.

Patch

diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
--- a/mercurial/templatefuncs.py
+++ b/mercurial/templatefuncs.py
@@ -658,17 +658,19 @@  def revset(context, mapping, args):
         return m(repo)
 
     if len(args) > 1:
+        key = None  # dynamically-created revs shouldn't be cached
         formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
         revs = query(revsetlang.formatspec(raw, *formatargs))
     else:
         cache = context.resource(mapping, b'cache')
         revsetcache = cache.setdefault(b"revsetcache", {})
-        if raw in revsetcache:
-            revs = revsetcache[raw]
+        key = raw
+        if key in revsetcache:
+            revs = revsetcache[key]
         else:
             revs = query(raw)
-            revsetcache[raw] = revs
-    return templateutil.revslist(repo, revs, name=b'revision')
+            revsetcache[key] = revs
+    return templateutil.revslist(repo, revs, name=b'revision', cachekey=key)
 
 
 @templatefunc(b'rstdoc(text, style)')
diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py
--- a/mercurial/templateutil.py
+++ b/mercurial/templateutil.py
@@ -414,13 +414,18 @@  class revslist(wrapped):
 
     If name specified, the revs will be rendered with the old-style list
     template of the given name by default.
+
+    The cachekey provides a hint to cache further computation on this
+    smartset. If the underlying smartset is dynamically created, the cachekey
+    should be None.
     """
 
-    def __init__(self, repo, revs, name=None):
+    def __init__(self, repo, revs, name=None, cachekey=None):
         assert isinstance(revs, smartset.abstractsmartset)
         self._repo = repo
         self._revs = revs
         self._name = name
+        self.cachekey = cachekey
 
     def contains(self, context, mapping, item):
         rev = unwrapinteger(context, mapping, item)