revsetlang: enable optimization of 'x + y' expression
It's been disabled since
4d1e56b29a91, but it can be enabled now as the
ordering requirement is resolved at analyze().
--- a/mercurial/revsetlang.py Sat Apr 01 15:24:03 2017 -0700
+++ b/mercurial/revsetlang.py Sat May 14 20:51:57 2016 +0900
@@ -434,9 +434,9 @@
flushss()
if len(ts) == 1:
return ws[0], ts[0] # 'or' operation is fully optimized out
- # 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]))
+ if order != defineorder:
+ # reorder by weight only when f(a + b) == f(b + a)
+ ts = [wt[1] for wt in sorted(zip(ws, ts), key=lambda wt: wt[0])]
return max(ws), (op, ('list',) + tuple(ts), order)
elif op == 'not':
# Optimize not public() to _notpublic() because we have a fast version
--- a/tests/test-revset.t Sat Apr 01 15:24:03 2017 -0700
+++ b/tests/test-revset.t Sat May 14 20:51:57 2016 +0900
@@ -1420,19 +1420,19 @@
define)
(or
(list
+ ('symbol', '2')
(range
('symbol', '0')
('symbol', '1')
- follow)
- ('symbol', '2'))
+ follow))
follow)
define)
* set:
<filteredset
<spanset- 0:2>,
<addset
- <spanset+ 0:1>,
- <baseset [2]>>>
+ <baseset [2]>,
+ <spanset+ 0:1>>>
2
1
0
@@ -1917,6 +1917,69 @@
1
0
+ 'A + B' can be rewritten to 'B + A' by weight only when the order doesn't
+ matter (e.g. 'X & (A + B)' can be 'X & (B + A)', but '(A + B) & X' can't):
+
+ $ try -p optimized '0:2 & (reverse(contains("a")) + 2)'
+ * optimized:
+ (and
+ (range
+ ('symbol', '0')
+ ('symbol', '2')
+ define)
+ (or
+ (list
+ ('symbol', '2')
+ (func
+ ('symbol', 'reverse')
+ (func
+ ('symbol', 'contains')
+ ('string', 'a')
+ define)
+ follow))
+ follow)
+ define)
+ * set:
+ <filteredset
+ <spanset+ 0:2>,
+ <addset
+ <baseset [2]>,
+ <filteredset
+ <fullreposet+ 0:9>,
+ <contains 'a'>>>>
+ 0
+ 1
+ 2
+
+ $ try -p optimized '(reverse(contains("a")) + 2) & 0:2'
+ * optimized:
+ (and
+ (range
+ ('symbol', '0')
+ ('symbol', '2')
+ follow)
+ (or
+ (list
+ (func
+ ('symbol', 'reverse')
+ (func
+ ('symbol', 'contains')
+ ('string', 'a')
+ define)
+ define)
+ ('symbol', '2'))
+ define)
+ define)
+ * set:
+ <addset
+ <filteredset
+ <spanset- 0:2>,
+ <contains 'a'>>,
+ <baseset [2]>>
+ 1
+ 0
+ 2
+
test sort revset
--------------------------------------------