##// END OF EJS Templates
revset: reduce nesting of chained 'or' operations (issue4624)...
Yuya Nishihara -
r25309:b333ca94 default
parent child Browse files
Show More
@@ -356,10 +356,9 b' def dagrange(repo, subset, x, y):'
356 def andset(repo, subset, x, y):
356 def andset(repo, subset, x, y):
357 return getset(repo, getset(repo, subset, x), y)
357 return getset(repo, getset(repo, subset, x), y)
358
358
359 def orset(repo, subset, x, y):
359 def orset(repo, subset, *xs):
360 xl = getset(repo, subset, x)
360 rs = [getset(repo, subset, x) for x in xs]
361 yl = getset(repo, subset, y)
361 return _combinesets(rs)
362 return xl + yl
363
362
364 def notset(repo, subset, x):
363 def notset(repo, subset, x):
365 return subset - getset(repo, subset, x)
364 return subset - getset(repo, subset, x)
@@ -2160,13 +2159,11 b' def optimize(x, small):'
2160 return w, (op, tb, ta)
2159 return w, (op, tb, ta)
2161 return w, (op, ta, tb)
2160 return w, (op, ta, tb)
2162 elif op == 'or':
2161 elif op == 'or':
2163 wa, ta = optimize(x[1], False)
2162 ws, ts = zip(*[optimize(y, False) for y in x[1:]])
2164 wb, tb = optimize(x[2], False)
2165 # we can't reorder trees by weight because it would change the order.
2163 # we can't reorder trees by weight because it would change the order.
2166 # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a")
2164 # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a")
2167 # if wb < wa:
2165 # ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0]))
2168 # tb, ta = ta, tb
2166 return max(ws), (op,) + ts
2169 return max(wa, wb), (op, ta, tb)
2170 elif op == 'not':
2167 elif op == 'not':
2171 # Optimize not public() to _notpublic() because we have a fast version
2168 # Optimize not public() to _notpublic() because we have a fast version
2172 if x[1] == ('func', ('symbol', 'public'), None):
2169 if x[1] == ('func', ('symbol', 'public'), None):
@@ -2384,7 +2381,7 b' def _parsealiasdefn(defn, args):'
2384 tree, pos = p.parse(defn)
2381 tree, pos = p.parse(defn)
2385 if pos != len(defn):
2382 if pos != len(defn):
2386 raise error.ParseError(_('invalid token'), pos)
2383 raise error.ParseError(_('invalid token'), pos)
2387 return tree
2384 return parser.simplifyinfixops(tree, ('or',))
2388
2385
2389 class revsetalias(object):
2386 class revsetalias(object):
2390 # whether own `error` information is already shown or not.
2387 # whether own `error` information is already shown or not.
@@ -2515,7 +2512,7 b' def parse(spec, lookup=None):'
2515 tree, pos = p.parse(spec, lookup=lookup)
2512 tree, pos = p.parse(spec, lookup=lookup)
2516 if pos != len(spec):
2513 if pos != len(spec):
2517 raise error.ParseError(_("invalid token"), pos)
2514 raise error.ParseError(_("invalid token"), pos)
2518 return tree
2515 return parser.simplifyinfixops(tree, ('or',))
2519
2516
2520 def posttreebuilthook(tree, repo):
2517 def posttreebuilthook(tree, repo):
2521 # hook for extensions to execute code on the optimized tree
2518 # hook for extensions to execute code on the optimized tree
@@ -1469,13 +1469,12 b' glog always reorders nodes which explain'
1469 (group
1469 (group
1470 (group
1470 (group
1471 (or
1471 (or
1472 (or
1472 (func
1473 (func
1473 ('symbol', 'branch')
1474 ('symbol', 'branch')
1474 ('string', 'default'))
1475 ('string', 'default'))
1475 (func
1476 (func
1476 ('symbol', 'branch')
1477 ('symbol', 'branch')
1477 ('string', 'branch'))
1478 ('string', 'branch')))
1479 (func
1478 (func
1480 ('symbol', 'branch')
1479 ('symbol', 'branch')
1481 ('string', 'branch')))))
1480 ('string', 'branch')))))
@@ -128,16 +128,15 b' trivial'
128 6
128 6
129 $ try '0|1|2'
129 $ try '0|1|2'
130 (or
130 (or
131 (or
131 ('symbol', '0')
132 ('symbol', '0')
132 ('symbol', '1')
133 ('symbol', '1'))
134 ('symbol', '2'))
133 ('symbol', '2'))
135 * set:
134 * set:
136 <addset
135 <addset
136 <baseset [0]>,
137 <addset
137 <addset
138 <baseset [0]>,
138 <baseset [1]>,
139 <baseset [1]>>,
139 <baseset [2]>>>
140 <baseset [2]>>
141 0
140 0
142 1
141 1
143 2
142 2
@@ -910,6 +909,49 b' test that `or` operation skips duplicate'
910 4
909 4
911 5
910 5
912
911
912 test that chained `or` operations make balanced addsets
913
914 $ try '0:1|1:2|2:3|3:4|4:5'
915 (or
916 (range
917 ('symbol', '0')
918 ('symbol', '1'))
919 (range
920 ('symbol', '1')
921 ('symbol', '2'))
922 (range
923 ('symbol', '2')
924 ('symbol', '3'))
925 (range
926 ('symbol', '3')
927 ('symbol', '4'))
928 (range
929 ('symbol', '4')
930 ('symbol', '5')))
931 * set:
932 <addset
933 <addset
934 <spanset+ 0:1>,
935 <spanset+ 1:2>>,
936 <addset
937 <spanset+ 2:3>,
938 <addset
939 <spanset+ 3:4>,
940 <spanset+ 4:5>>>>
941 0
942 1
943 2
944 3
945 4
946 5
947
948 test that chained `or` operations never eat up stack (issue4624)
949 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
950
951 $ hg log -T '{rev}\n' -r "`python -c "print '|'.join(['0:1'] * 500)"`"
952 0
953 1
954
913 check that conversion to only works
955 check that conversion to only works
914 $ try --optimize '::3 - ::1'
956 $ try --optimize '::3 - ::1'
915 (minus
957 (minus
@@ -1352,6 +1394,44 b' test nesting and variable passing'
1352 <baseset [5]>
1394 <baseset [5]>
1353 5
1395 5
1354
1396
1397 test chained `or` operations are flattened at parsing phase
1398
1399 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
1400 $ try 'chainedorops(0:1, 1:2, 2:3)'
1401 (func
1402 ('symbol', 'chainedorops')
1403 (list
1404 (list
1405 (range
1406 ('symbol', '0')
1407 ('symbol', '1'))
1408 (range
1409 ('symbol', '1')
1410 ('symbol', '2')))
1411 (range
1412 ('symbol', '2')
1413 ('symbol', '3'))))
1414 (or
1415 (range
1416 ('symbol', '0')
1417 ('symbol', '1'))
1418 (range
1419 ('symbol', '1')
1420 ('symbol', '2'))
1421 (range
1422 ('symbol', '2')
1423 ('symbol', '3')))
1424 * set:
1425 <addset
1426 <spanset+ 0:1>,
1427 <addset
1428 <spanset+ 1:2>,
1429 <spanset+ 2:3>>>
1430 0
1431 1
1432 2
1433 3
1434
1355 test variable isolation, variable placeholders are rewritten as string
1435 test variable isolation, variable placeholders are rewritten as string
1356 then parsed and matched again as string. Check they do not leak too
1436 then parsed and matched again as string. Check they do not leak too
1357 far away.
1437 far away.
General Comments 0
You need to be logged in to leave comments. Login now