revset: cache alias expansions
authorPatrick Mezard <patrick@mezard.eu>
Thu, 24 May 2012 13:05:06 +0200
changeset 16838 d37d221334be
parent 16837 1b9d54c00d50
child 16839 0a0cf3f26938
revset: cache alias expansions Caching has no performance effect on the revset aliases which triggered the recent recursive evaluation bug. I wrote it not to feel bad about expanding several times the same complicated expression.
mercurial/revset.py
--- a/mercurial/revset.py	Thu May 24 01:30:12 2012 +0200
+++ b/mercurial/revset.py	Thu May 24 13:05:06 2012 +0200
@@ -1481,7 +1481,7 @@
         return args[arg]
     return tuple(_expandargs(t, args) for t in tree)
 
-def _expandaliases(aliases, tree, expanding):
+def _expandaliases(aliases, tree, expanding, cache):
     """Expand aliases in tree, recursively.
 
     'aliases' is a dictionary mapping user defined aliases to
@@ -1496,17 +1496,20 @@
             raise error.ParseError(_('infinite expansion of revset alias "%s" '
                                      'detected') % alias.name)
         expanding.append(alias)
-        result = _expandaliases(aliases, alias.replacement, expanding)
+        if alias.name not in cache:
+            cache[alias.name] = _expandaliases(aliases, alias.replacement,
+                                               expanding, cache)
+        result = cache[alias.name]
         expanding.pop()
         if alias.args is not None:
             l = getlist(tree[2])
             if len(l) != len(alias.args):
                 raise error.ParseError(
                     _('invalid number of arguments: %s') % len(l))
-            l = [_expandaliases(aliases, a, []) for a in l]
+            l = [_expandaliases(aliases, a, [], cache) for a in l]
             result = _expandargs(result, dict(zip(alias.args, l)))
     else:
-        result = tuple(_expandaliases(aliases, t, expanding)
+        result = tuple(_expandaliases(aliases, t, expanding, cache)
                        for t in tree)
     return result
 
@@ -1516,7 +1519,7 @@
     for k, v in ui.configitems('revsetalias'):
         alias = revsetalias(k, v)
         aliases[alias.name] = alias
-    return _expandaliases(aliases, tree, [])
+    return _expandaliases(aliases, tree, [], {})
 
 parse = parser.parser(tokenize, elements).parse