Mercurial > hg
changeset 38832:ca4de8ba5b5f
fileset: optimize 'x and not y' to 'x - y'
'x - y' is first rewritten to 'x and not y' so that x and y are reordered
by weight.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 21 Jul 2018 16:49:01 +0900 |
parents | b975c5801487 |
children | c83ad57627ae |
files | mercurial/filesetlang.py tests/test-fileset.t |
diffstat | 2 files changed, 77 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/filesetlang.py Sat Jul 21 16:41:45 2018 +0900 +++ b/mercurial/filesetlang.py Sat Jul 21 16:49:01 2018 +0900 @@ -149,10 +149,12 @@ if op == 'not': t = _analyze(x[1]) return (op, t) - if op in {'and', 'minus'}: + if op == 'and': ta = _analyze(x[1]) tb = _analyze(x[2]) return (op, ta, tb) + if op == 'minus': + return _analyze(('and', x[1], ('not', x[2]))) if op in {'list', 'or'}: ts = tuple(_analyze(y) for y in x[1:]) return (op,) + ts @@ -171,6 +173,11 @@ """ return _analyze(x) +def _optimizeandops(op, ta, tb): + if tb is not None and tb[0] == 'not': + return ('minus', ta, tb[1]) + return (op, ta, tb) + def _optimize(x): if x is None: return 0, x @@ -188,13 +195,9 @@ wa, ta = _optimize(x[1]) wb, tb = _optimize(x[2]) if wa <= wb: - return wa, (op, ta, tb) + return wa, _optimizeandops(op, ta, tb) else: - return wb, (op, tb, ta) - if op == 'minus': - wa, ta = _optimize(x[1]) - wb, tb = _optimize(x[2]) - return max(wa, wb), (op, ta, tb) + return wb, _optimizeandops(op, tb, ta) if op == 'or': ws, ts = zip(*(_optimize(y) for y in x[1:])) return max(ws), (op,) + ts
--- a/tests/test-fileset.t Sat Jul 21 16:41:45 2018 +0900 +++ b/tests/test-fileset.t Sat Jul 21 16:49:01 2018 +0900 @@ -203,6 +203,73 @@ b1 b2 +Use differencematcher for 'x and not y': + + $ fileset -p optimized -s 'a* and not a1' + * optimized: + (minus + (symbol 'a*') + (symbol 'a1')) + * matcher: + <differencematcher + m1=<patternmatcher patterns='(?:a[^/]*$)'>, + m2=<patternmatcher patterns='(?:a1$)'>> + a2 + + $ fileset -p optimized -s '!binary() and a*' + * optimized: + (minus + (symbol 'a*') + (func + (symbol 'binary') + None)) + * matcher: + <differencematcher + m1=<patternmatcher patterns='(?:a[^/]*$)'>, + m2=<predicatenmatcher pred=binary>> + a1 + a2 + +'x - y' is rewritten to 'x and not y' first so the operands can be reordered: + + $ fileset -p analyzed -p optimized -s 'a* - a1' + * analyzed: + (and + (symbol 'a*') + (not + (symbol 'a1'))) + * optimized: + (minus + (symbol 'a*') + (symbol 'a1')) + * matcher: + <differencematcher + m1=<patternmatcher patterns='(?:a[^/]*$)'>, + m2=<patternmatcher patterns='(?:a1$)'>> + a2 + + $ fileset -p analyzed -p optimized -s 'binary() - a*' + * analyzed: + (and + (func + (symbol 'binary') + None) + (not + (symbol 'a*'))) + * optimized: + (and + (not + (symbol 'a*')) + (func + (symbol 'binary') + None)) + * matcher: + <intersectionmatcher + m1=<predicatenmatcher + pred=<not + <patternmatcher patterns='(?:a[^/]*$)'>>>, + m2=<predicatenmatcher pred=binary>> + Test files status $ rm a1