revset: fix order of nested 'or' expression (BC)
authorYuya Nishihara <yuya@tcha.org>
Sun, 26 Jun 2016 18:17:12 +0900
changeset 29934 2c6a05b938d8
parent 29933 91a95ad985d8
child 29935 e34cd85dc5b1
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)
mercurial/revset.py
tests/test-revset.t
--- 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':