Mercurial > hg-stable
changeset 29933:b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
This makes the number of 'or' arguments deterministic so we can attach
additional ordering flag to all operator nodes. See the next patch.
We rewrite the tree immediately after chained 'or' operations are flattened
by simplifyinfixops(), so we don't need to care if arguments are stored in
x[1] or x[1:].
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 07 Aug 2016 17:04:05 +0900 |
parents | e5a97ec6ebb8 |
children | 90455e7bf543 |
files | mercurial/revset.py tests/test-glog.t tests/test-revset.t |
diffstat | 3 files changed, 270 insertions(+), 215 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/revset.py Tue Sep 13 20:30:19 2016 +0200 +++ b/mercurial/revset.py Sun Aug 07 17:04:05 2016 +0900 @@ -397,15 +397,18 @@ def differenceset(repo, subset, x, y): return getset(repo, subset, x) - getset(repo, subset, y) -def orset(repo, subset, *xs): +def _orsetlist(repo, subset, xs): assert xs if len(xs) == 1: return getset(repo, subset, xs[0]) p = len(xs) // 2 - a = orset(repo, subset, *xs[:p]) - b = orset(repo, subset, *xs[p:]) + a = _orsetlist(repo, subset, xs[:p]) + b = _orsetlist(repo, subset, xs[p:]) return a + b +def orset(repo, subset, x): + return _orsetlist(repo, subset, getlist(x)) + def notset(repo, subset, x): return subset - getset(repo, subset, x) @@ -2339,6 +2342,10 @@ return _fixops(('range', post, x[2][1])) elif x[2][0] == 'rangeall': return _fixops(('rangepost', post)) + elif op == 'or': + # make number of arguments deterministic: + # x + y + z -> (or x y z) -> (or (list x y z)) + return (op, _fixops(('list',) + x[1:])) return (op,) + tuple(_fixops(y) for y in x[1:]) @@ -2374,7 +2381,7 @@ tb = _analyze(x[2]) return (op, ta, tb) elif op == 'or': - return (op,) + tuple(_analyze(y) for y in x[1:]) + return (op, _analyze(x[1])) elif op == 'not': return (op, _analyze(x[1])) elif op == 'parentpost': @@ -2445,7 +2452,7 @@ ws.append(w) ts.append(t) del ss[:] - for y in x[1:]: + for y in getlist(x[1]): w, t = _optimize(y, False) if t is not None and (t[0] == 'string' or t[0] == 'symbol'): ss.append((w, t)) @@ -2459,7 +2466,7 @@ # we can't reorder trees by weight because it would change the order. # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a") # ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0])) - return max(ws), (op,) + tuple(ts) + return max(ws), (op, ('list',) + tuple(ts)) elif op == 'not': # Optimize not public() to _notpublic() because we have a fast version if x[1] == ('func', ('symbol', 'public'), None): @@ -2613,7 +2620,7 @@ if len(specs) == 1: tree = parse(specs[0], lookup) else: - tree = ('or',) + tuple(parse(s, lookup) for s in specs) + tree = ('or', ('list',) + tuple(parse(s, lookup) for s in specs)) if ui: tree = expandaliases(ui, tree)
--- a/tests/test-glog.t Tue Sep 13 20:30:19 2016 +0200 +++ b/tests/test-glog.t Sun Aug 07 17:04:05 2016 +0900 @@ -1455,12 +1455,13 @@ (group (group (or - (func - ('symbol', 'user') - ('string', 'test')) - (func - ('symbol', 'user') - ('string', 'not-a-user'))))) + (list + (func + ('symbol', 'user') + ('string', 'test')) + (func + ('symbol', 'user') + ('string', 'not-a-user')))))) $ testlog -b not-a-branch abort: unknown revision 'not-a-branch'! abort: unknown revision 'not-a-branch'! @@ -1470,26 +1471,28 @@ (group (group (or - (func - ('symbol', 'branch') - ('string', 'default')) - (func - ('symbol', 'branch') - ('string', 'branch')) - (func - ('symbol', 'branch') - ('string', 'branch'))))) + (list + (func + ('symbol', 'branch') + ('string', 'default')) + (func + ('symbol', 'branch') + ('string', 'branch')) + (func + ('symbol', 'branch') + ('string', 'branch')))))) $ testlog -k expand -k merge [] (group (group (or - (func - ('symbol', 'keyword') - ('string', 'expand')) - (func - ('symbol', 'keyword') - ('string', 'merge'))))) + (list + (func + ('symbol', 'keyword') + ('string', 'expand')) + (func + ('symbol', 'keyword') + ('string', 'merge')))))) $ testlog --only-merges [] (group @@ -1520,17 +1523,19 @@ (not (group (or - ('string', '31') - (func - ('symbol', 'ancestors') - ('string', '31'))))) + (list + ('string', '31') + (func + ('symbol', 'ancestors') + ('string', '31')))))) (not (group (or - ('string', '32') - (func - ('symbol', 'ancestors') - ('string', '32')))))))) + (list + ('string', '32') + (func + ('symbol', 'ancestors') + ('string', '32'))))))))) Dedicated repo for --follow and paths filtering. The g is crafted to have 2 filelog topological heads in a linear changeset graph. @@ -1587,12 +1592,13 @@ (group (group (or - (func - ('symbol', 'filelog') - ('string', 'a')) - (func - ('symbol', 'filelog') - ('string', 'b'))))) + (list + (func + ('symbol', 'filelog') + ('string', 'a')) + (func + ('symbol', 'filelog') + ('string', 'b')))))) Test falling back to slow path for non-existing files @@ -1744,12 +1750,13 @@ (group (group (or - (func - ('symbol', 'follow') - ('string', 'g')) - (func - ('symbol', 'follow') - ('string', 'e'))))) + (list + (func + ('symbol', 'follow') + ('string', 'g')) + (func + ('symbol', 'follow') + ('string', 'e')))))) $ cat log.nodes nodetag 4 nodetag 3
--- a/tests/test-revset.t Tue Sep 13 20:30:19 2016 +0200 +++ b/tests/test-revset.t Sun Aug 07 17:04:05 2016 +0900 @@ -187,9 +187,10 @@ 6 $ try '0|1|2' (or - ('symbol', '0') - ('symbol', '1') - ('symbol', '2')) + (list + ('symbol', '0') + ('symbol', '1') + ('symbol', '2'))) * set: <baseset [0, 1, 2]> 0 @@ -339,10 +340,11 @@ $ log '1&2' $ try '1&2|3' # precedence - and is higher (or - (and - ('symbol', '1') - ('symbol', '2')) - ('symbol', '3')) + (list + (and + ('symbol', '1') + ('symbol', '2')) + ('symbol', '3'))) * set: <addset <baseset []>, @@ -350,10 +352,11 @@ 3 $ try '1|2&3' (or - ('symbol', '1') - (and - ('symbol', '2') - ('symbol', '3'))) + (list + ('symbol', '1') + (and + ('symbol', '2') + ('symbol', '3')))) * set: <addset <baseset [1]>, @@ -369,11 +372,13 @@ <baseset []> $ try '1|(2|3)' (or - ('symbol', '1') - (group - (or - ('symbol', '2') - ('symbol', '3')))) + (list + ('symbol', '1') + (group + (or + (list + ('symbol', '2') + ('symbol', '3')))))) * set: <addset <baseset [1]>, @@ -465,8 +470,9 @@ (keyvalue ('symbol', 'foo') (or - ('symbol', 'bar') - ('symbol', 'baz'))) + (list + ('symbol', 'bar') + ('symbol', 'baz')))) hg: parse error: can't use a key-value pair in this context [255] @@ -528,14 +534,16 @@ (minus (group (or - ('symbol', '0') - ('symbol', '1'))) + (list + ('symbol', '0') + ('symbol', '1')))) ('symbol', '1')) * analyzed: (and (or - ('symbol', '0') - ('symbol', '1')) + (list + ('symbol', '0') + ('symbol', '1'))) (not ('symbol', '1'))) * optimized: @@ -1242,9 +1250,10 @@ ('symbol', '0')) (group (or - ('symbol', '0') - ('symbol', '1') - ('symbol', '2')))) + (list + ('symbol', '0') + ('symbol', '1') + ('symbol', '2'))))) * optimized: (and (range @@ -1269,20 +1278,22 @@ ('symbol', '0')) (group (or - (range - ('symbol', '0') - ('symbol', '1')) - ('symbol', '2')))) + (list + (range + ('symbol', '0') + ('symbol', '1')) + ('symbol', '2'))))) * optimized: (and (range ('symbol', '2') ('symbol', '0')) (or - (range - ('symbol', '0') - ('symbol', '1')) - ('symbol', '2'))) + (list + (range + ('symbol', '0') + ('symbol', '1')) + ('symbol', '2')))) * set: <addset <filteredset @@ -1402,9 +1413,10 @@ (func ('symbol', 'present') (or - ('symbol', '0') - ('symbol', '1') - ('symbol', '2')))) + (list + ('symbol', '0') + ('symbol', '1') + ('symbol', '2'))))) * optimized: (and (range @@ -1499,9 +1511,10 @@ (func ('symbol', 'first') (or - ('symbol', '1') - ('symbol', '0') - ('symbol', '2')))) + (list + ('symbol', '1') + ('symbol', '0') + ('symbol', '2'))))) * optimized: (and (range @@ -1528,9 +1541,10 @@ (func ('symbol', 'last') (or - ('symbol', '0') - ('symbol', '2') - ('symbol', '1'))))) + (list + ('symbol', '0') + ('symbol', '2') + ('symbol', '1')))))) * optimized: (difference (range @@ -1562,14 +1576,16 @@ (range (group (or - ('symbol', '1') - ('symbol', '0') - ('symbol', '2'))) + (list + ('symbol', '1') + ('symbol', '0') + ('symbol', '2')))) (group (or - ('symbol', '0') - ('symbol', '2') - ('symbol', '1'))))) + (list + ('symbol', '0') + ('symbol', '2') + ('symbol', '1')))))) * optimized: (and (range @@ -1599,9 +1615,10 @@ ('string', 'glob:*')) (group (or - ('symbol', '2') - ('symbol', '0') - ('symbol', '1')))) + (list + ('symbol', '2') + ('symbol', '0') + ('symbol', '1'))))) * optimized: (and (func @@ -1628,9 +1645,10 @@ ('string', 'glob:*'))) (group (or - ('symbol', '0') - ('symbol', '2') - ('symbol', '1')))) + (list + ('symbol', '0') + ('symbol', '2') + ('symbol', '1'))))) * optimized: (and (func @@ -1975,14 +1993,15 @@ $ try 'reverse(1::5) or ancestors(4)' (or - (func - ('symbol', 'reverse') - (dagrange - ('symbol', '1') - ('symbol', '5'))) - (func - ('symbol', 'ancestors') - ('symbol', '4'))) + (list + (func + ('symbol', 'reverse') + (dagrange + ('symbol', '1') + ('symbol', '5'))) + (func + ('symbol', 'ancestors') + ('symbol', '4')))) * set: <addset <baseset- [1, 3, 5]>, @@ -1997,14 +2016,15 @@ (func ('symbol', 'sort') (or - (func - ('symbol', 'ancestors') - ('symbol', '4')) - (func - ('symbol', 'reverse') - (dagrange - ('symbol', '1') - ('symbol', '5'))))) + (list + (func + ('symbol', 'ancestors') + ('symbol', '4')) + (func + ('symbol', 'reverse') + (dagrange + ('symbol', '1') + ('symbol', '5')))))) * set: <addset+ <generatorset+>, @@ -2020,14 +2040,15 @@ $ try --optimize '0|(1)|"2"|-2|tip|null' (or - ('symbol', '0') - (group - ('symbol', '1')) - ('string', '2') - (negate - ('symbol', '2')) - ('symbol', 'tip') - ('symbol', 'null')) + (list + ('symbol', '0') + (group + ('symbol', '1')) + ('string', '2') + (negate + ('symbol', '2')) + ('symbol', 'tip') + ('symbol', 'null'))) * optimized: (func ('symbol', '_list') @@ -2043,19 +2064,21 @@ $ try --optimize '0|1|2:3' (or - ('symbol', '0') - ('symbol', '1') - (range - ('symbol', '2') - ('symbol', '3'))) + (list + ('symbol', '0') + ('symbol', '1') + (range + ('symbol', '2') + ('symbol', '3')))) * optimized: (or - (func - ('symbol', '_list') - ('string', '0\x001')) - (range - ('symbol', '2') - ('symbol', '3'))) + (list + (func + ('symbol', '_list') + ('string', '0\x001')) + (range + ('symbol', '2') + ('symbol', '3')))) * set: <addset <baseset [0, 1]>, @@ -2067,27 +2090,29 @@ $ try --optimize '0:1|2|3:4|5|6' (or - (range - ('symbol', '0') - ('symbol', '1')) - ('symbol', '2') - (range - ('symbol', '3') - ('symbol', '4')) - ('symbol', '5') - ('symbol', '6')) + (list + (range + ('symbol', '0') + ('symbol', '1')) + ('symbol', '2') + (range + ('symbol', '3') + ('symbol', '4')) + ('symbol', '5') + ('symbol', '6'))) * optimized: (or - (range - ('symbol', '0') - ('symbol', '1')) - ('symbol', '2') - (range - ('symbol', '3') - ('symbol', '4')) - (func - ('symbol', '_list') - ('string', '5\x006'))) + (list + (range + ('symbol', '0') + ('symbol', '1')) + ('symbol', '2') + (range + ('symbol', '3') + ('symbol', '4')) + (func + ('symbol', '_list') + ('string', '5\x006')))) * set: <addset <addset @@ -2109,11 +2134,12 @@ $ try --no-optimized -p analyzed '0|1|2|3|4' * analyzed: (or - ('symbol', '0') - ('symbol', '1') - ('symbol', '2') - ('symbol', '3') - ('symbol', '4')) + (list + ('symbol', '0') + ('symbol', '1') + ('symbol', '2') + ('symbol', '3') + ('symbol', '4'))) * set: <addset <addset @@ -2188,21 +2214,22 @@ $ try '0:1|1:2|2:3|3:4|4:5' (or - (range - ('symbol', '0') - ('symbol', '1')) - (range - ('symbol', '1') - ('symbol', '2')) - (range - ('symbol', '2') - ('symbol', '3')) - (range - ('symbol', '3') - ('symbol', '4')) - (range - ('symbol', '4') - ('symbol', '5'))) + (list + (range + ('symbol', '0') + ('symbol', '1')) + (range + ('symbol', '1') + ('symbol', '2')) + (range + ('symbol', '2') + ('symbol', '3')) + (range + ('symbol', '3') + ('symbol', '4')) + (range + ('symbol', '4') + ('symbol', '5')))) * set: <addset <addset @@ -2224,13 +2251,15 @@ $ try --optimize '0|()' (or - ('symbol', '0') - (group - None)) + (list + ('symbol', '0') + (group + None))) * optimized: (or - ('symbol', '0') - None) + (list + ('symbol', '0') + None)) hg: parse error: missing argument [255] @@ -2715,10 +2744,12 @@ ('symbol', '3'))) * expanded: (or - ('symbol', '3') - (or - ('symbol', '1') - ('symbol', '2'))) + (list + ('symbol', '3') + (or + (list + ('symbol', '1') + ('symbol', '2'))))) * set: <addset <baseset [3]>, @@ -2769,15 +2800,16 @@ ('symbol', '3')))) * expanded: (or - (range - ('symbol', '0') - ('symbol', '1')) - (range - ('symbol', '1') - ('symbol', '2')) - (range - ('symbol', '2') - ('symbol', '3'))) + (list + (range + ('symbol', '0') + ('symbol', '1')) + (range + ('symbol', '1') + ('symbol', '2')) + (range + ('symbol', '2') + ('symbol', '3')))) * set: <addset <spanset+ 0:1>, @@ -2868,10 +2900,11 @@ ('symbol', 'tip'))) * expanded: (or - ('symbol', 'tip') - (func - ('symbol', 'desc') - ('string', '$1'))) + (list + ('symbol', 'tip') + (func + ('symbol', 'desc') + ('string', '$1')))) * set: <addset <baseset [9]>, @@ -2907,8 +2940,9 @@ ('symbol', 'rs') (list (or - ('symbol', '2') - ('symbol', '3')) + (list + ('symbol', '2') + ('symbol', '3'))) ('symbol', 'date'))) * expanded: (func @@ -2917,8 +2951,9 @@ ('symbol', 'sort') (list (or - ('symbol', '2') - ('symbol', '3')) + (list + ('symbol', '2') + ('symbol', '3'))) ('symbol', 'date')))) * set: <baseset [3, 2]> @@ -2950,8 +2985,9 @@ ('symbol', 'rs4') (list (or - ('symbol', '2') - ('symbol', '3')) + (list + ('symbol', '2') + ('symbol', '3'))) ('symbol', 'x') ('symbol', 'x') ('symbol', 'date'))) @@ -2962,8 +2998,9 @@ ('symbol', 'sort') (list (or - ('symbol', '2') - ('symbol', '3')) + (list + ('symbol', '2') + ('symbol', '3'))) ('symbol', 'date')))) * set: <baseset [3, 2]> @@ -3034,9 +3071,10 @@ ('symbol', 'limit') (list (or - ('symbol', '1') - ('symbol', '2') - ('symbol', '3')) + (list + ('symbol', '1') + ('symbol', '2') + ('symbol', '3'))) ('symbol', '2'))) (not ('symbol', '2'))) @@ -3054,8 +3092,9 @@ (func ('symbol', 'max') (or - ('symbol', '1') - ('symbol', '2'))) + (list + ('symbol', '1') + ('symbol', '2')))) (not ('symbol', '2'))) * set: @@ -3071,8 +3110,9 @@ (func ('symbol', 'min') (or - ('symbol', '1') - ('symbol', '2'))) + (list + ('symbol', '1') + ('symbol', '2')))) (not ('symbol', '1'))) * set: @@ -3089,8 +3129,9 @@ ('symbol', 'last') (list (or - ('symbol', '1') - ('symbol', '2')) + (list + ('symbol', '1') + ('symbol', '2'))) ('symbol', '1'))) (not ('symbol', '2')))