revset: fix order of nested 'or' expression (BC)
This fixes the order of 'x & (y + z)' where 'y' and 'z' are not trivial.
The follow-order 'or' operation is slower than the ordered operation if
an input set is large:
#0 #1 #2 #3
0) 0.002968 0.002980 0.002982 0.073042
1) 0.004513 0.004485 0.012029 0.075261
#0: 0:4000 & (0:1099 + 1000:2099 + 2000:3099)
#1: 4000:0 & (0:1099 + 1000:2099 + 2000:3099)
#2: 10000:0 & (0:1099 + 1000:2099 + 2000:3099)
#3: file("path:hg") & (0:1099 + 1000:2099 + 2000:3099)
I've tried another implementation, but which appeared to be slower than
this version.
ss = [getset(repo, fullreposet(repo), x) for x in xs]
return subset.filter(lambda r: any(r in s for s in ss), cache=False)
--- a/mercurial/revset.py Sun Aug 07 17:58:50 2016 +0900
+++ b/mercurial/revset.py Sun Jun 26 18:17:12 2016 +0900
@@ -407,7 +407,12 @@
return a + b
def orset(repo, subset, x, order):
- return _orsetlist(repo, subset, getlist(x))
+ xs = getlist(x)
+ if order == followorder:
+ # slow path to take the subset order
+ return subset & _orsetlist(repo, fullreposet(repo), xs)
+ else:
+ return _orsetlist(repo, subset, xs)
def notset(repo, subset, x, order):
return subset - getset(repo, subset, x)
--- a/tests/test-revset.t Sun Aug 07 17:58:50 2016 +0900
+++ b/tests/test-revset.t Sun Jun 26 18:17:12 2016 +0900
@@ -1317,15 +1317,14 @@
follow)
define)
* set:
- <addset
- <filteredset
+ <filteredset
+ <spanset- 0:2>,
+ <addset
<spanset+ 0:1>,
- <spanset- 0:2>>,
- <baseset [2]>>
+ <baseset [2]>>>
+ 2
+ 1
0
- 1
- 2
- BROKEN: should be '2 1 0'
'_intlist(a b)' should behave like 'a + b':