Mercurial > public > mercurial-scm > hg
comparison mercurial/revset.py @ 16838:d37d221334be
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.
author | Patrick Mezard <patrick@mezard.eu> |
---|---|
date | Thu, 24 May 2012 13:05:06 +0200 |
parents | cafd8a8fb713 |
children | eeb464ed7275 |
comparison
equal
deleted
inserted
replaced
16837:1b9d54c00d50 | 16838:d37d221334be |
---|---|
1479 arg = _getaliasarg(tree) | 1479 arg = _getaliasarg(tree) |
1480 if arg is not None: | 1480 if arg is not None: |
1481 return args[arg] | 1481 return args[arg] |
1482 return tuple(_expandargs(t, args) for t in tree) | 1482 return tuple(_expandargs(t, args) for t in tree) |
1483 | 1483 |
1484 def _expandaliases(aliases, tree, expanding): | 1484 def _expandaliases(aliases, tree, expanding, cache): |
1485 """Expand aliases in tree, recursively. | 1485 """Expand aliases in tree, recursively. |
1486 | 1486 |
1487 'aliases' is a dictionary mapping user defined aliases to | 1487 'aliases' is a dictionary mapping user defined aliases to |
1488 revsetalias objects. | 1488 revsetalias objects. |
1489 """ | 1489 """ |
1494 if alias is not None: | 1494 if alias is not None: |
1495 if alias in expanding: | 1495 if alias in expanding: |
1496 raise error.ParseError(_('infinite expansion of revset alias "%s" ' | 1496 raise error.ParseError(_('infinite expansion of revset alias "%s" ' |
1497 'detected') % alias.name) | 1497 'detected') % alias.name) |
1498 expanding.append(alias) | 1498 expanding.append(alias) |
1499 result = _expandaliases(aliases, alias.replacement, expanding) | 1499 if alias.name not in cache: |
1500 cache[alias.name] = _expandaliases(aliases, alias.replacement, | |
1501 expanding, cache) | |
1502 result = cache[alias.name] | |
1500 expanding.pop() | 1503 expanding.pop() |
1501 if alias.args is not None: | 1504 if alias.args is not None: |
1502 l = getlist(tree[2]) | 1505 l = getlist(tree[2]) |
1503 if len(l) != len(alias.args): | 1506 if len(l) != len(alias.args): |
1504 raise error.ParseError( | 1507 raise error.ParseError( |
1505 _('invalid number of arguments: %s') % len(l)) | 1508 _('invalid number of arguments: %s') % len(l)) |
1506 l = [_expandaliases(aliases, a, []) for a in l] | 1509 l = [_expandaliases(aliases, a, [], cache) for a in l] |
1507 result = _expandargs(result, dict(zip(alias.args, l))) | 1510 result = _expandargs(result, dict(zip(alias.args, l))) |
1508 else: | 1511 else: |
1509 result = tuple(_expandaliases(aliases, t, expanding) | 1512 result = tuple(_expandaliases(aliases, t, expanding, cache) |
1510 for t in tree) | 1513 for t in tree) |
1511 return result | 1514 return result |
1512 | 1515 |
1513 def findaliases(ui, tree): | 1516 def findaliases(ui, tree): |
1514 _checkaliasarg(tree) | 1517 _checkaliasarg(tree) |
1515 aliases = {} | 1518 aliases = {} |
1516 for k, v in ui.configitems('revsetalias'): | 1519 for k, v in ui.configitems('revsetalias'): |
1517 alias = revsetalias(k, v) | 1520 alias = revsetalias(k, v) |
1518 aliases[alias.name] = alias | 1521 aliases[alias.name] = alias |
1519 return _expandaliases(aliases, tree, []) | 1522 return _expandaliases(aliases, tree, [], {}) |
1520 | 1523 |
1521 parse = parser.parser(tokenize, elements).parse | 1524 parse = parser.parser(tokenize, elements).parse |
1522 | 1525 |
1523 def match(ui, spec): | 1526 def match(ui, spec): |
1524 if not spec: | 1527 if not spec: |