Patchwork templater: compute revset lazily

login
register
mail settings
Submitter Yuya Nishihara
Date Nov. 4, 2018, 12:50 p.m.
Message ID <217637aec0097552e235.1541335820@mimosa>
Download mbox | patch
Permalink /patch/36355/
State Accepted
Headers show

Comments

Yuya Nishihara - Nov. 4, 2018, 12:50 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1541331866 -32400
#      Sun Nov 04 20:44:26 2018 +0900
# Node ID 217637aec0097552e2353740c0b1c9b66f77fa69
# Parent  78e5b9d815facdba962950aad03e8e1b3ae60288
templater: compute revset lazily

This speeds up e.g. "{ifcontains(rev, revset('::.'), ...)}" in common cases
where 'rev' is near the working parent.

The templater API is ugly, but it helps here. 'f' can be either a generator
or a function returning a generator.
Augie Fackler - Nov. 5, 2018, 8:05 p.m.
queued, thanks

> On Nov 4, 2018, at 07:50, Yuya Nishihara <yuya@tcha.org> wrote:
> 
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1541331866 -32400
> #      Sun Nov 04 20:44:26 2018 +0900
> # Node ID 217637aec0097552e2353740c0b1c9b66f77fa69
> # Parent  78e5b9d815facdba962950aad03e8e1b3ae60288
> templater: compute revset lazily
> 
> This speeds up e.g. "{ifcontains(rev, revset('::.'), ...)}" in common cases
> where 'rev' is near the working parent.
> 
> The templater API is ugly, but it helps here. 'f' can be either a generator
> or a function returning a generator.
> 
> diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
> --- a/mercurial/templatefuncs.py
> +++ b/mercurial/templatefuncs.py
> @@ -559,7 +559,6 @@ def revset(context, mapping, args):
>     if len(args) > 1:
>         formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
>         revs = query(revsetlang.formatspec(raw, *formatargs))
> -        revs = list(revs)
>     else:
>         cache = context.resource(mapping, 'cache')
>         revsetcache = cache.setdefault("revsetcache", {})
> @@ -567,7 +566,6 @@ def revset(context, mapping, args):
>             revs = revsetcache[raw]
>         else:
>             revs = query(raw)
> -            revs = list(revs)
>             revsetcache[raw] = revs
>     return templatekw.showrevslist(context, mapping, "revision", revs)
> 
> diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
> --- a/mercurial/templatekw.py
> +++ b/mercurial/templatekw.py
> @@ -774,7 +774,10 @@ def showrevslist(context, mapping, name,
>     """helper to generate a list of revisions in which a mapped template will
>     be evaluated"""
>     repo = context.resource(mapping, 'repo')
> -    f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
> +    # revs may be a smartset; don't compute it until f() has to be evaluated
> +    def f():
> +        srevs = ['%d' % r for r in revs]
> +        return _showcompatlist(context, mapping, name, srevs)
>     return _hybrid(f, revs,
>                    lambda x: {name: x, 'ctx': repo[x]},
>                    pycompat.identity, keytype=int)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py
--- a/mercurial/templatefuncs.py
+++ b/mercurial/templatefuncs.py
@@ -559,7 +559,6 @@  def revset(context, mapping, args):
     if len(args) > 1:
         formatargs = [evalfuncarg(context, mapping, a) for a in args[1:]]
         revs = query(revsetlang.formatspec(raw, *formatargs))
-        revs = list(revs)
     else:
         cache = context.resource(mapping, 'cache')
         revsetcache = cache.setdefault("revsetcache", {})
@@ -567,7 +566,6 @@  def revset(context, mapping, args):
             revs = revsetcache[raw]
         else:
             revs = query(raw)
-            revs = list(revs)
             revsetcache[raw] = revs
     return templatekw.showrevslist(context, mapping, "revision", revs)
 
diff --git a/mercurial/templatekw.py b/mercurial/templatekw.py
--- a/mercurial/templatekw.py
+++ b/mercurial/templatekw.py
@@ -774,7 +774,10 @@  def showrevslist(context, mapping, name,
     """helper to generate a list of revisions in which a mapped template will
     be evaluated"""
     repo = context.resource(mapping, 'repo')
-    f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
+    # revs may be a smartset; don't compute it until f() has to be evaluated
+    def f():
+        srevs = ['%d' % r for r in revs]
+        return _showcompatlist(context, mapping, name, srevs)
     return _hybrid(f, revs,
                    lambda x: {name: x, 'ctx': repo[x]},
                    pycompat.identity, keytype=int)