Patchwork [5,of,7,V2] revset: add option to make inner range follow ordering of input set

Submitter Yuya Nishihara June 3, 2016, 3:02 p.m. <1ede480ae4adfb333351.1464966148@mimosa> mbox | patch /patch/15376/ Changes Requested Augie Fackler show

Yuya Nishihara - June 3, 2016, 3:02 p.m.
```# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1462247570 -32400
#      Tue May 03 12:52:50 2016 +0900
revset: add option to make inner range follow ordering of input set

This is simpler and faster than inserting generic _reorder() function.
```

Patch

```diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -357,7 +357,7 @@  def stringset(repo, subset, x):
return baseset([x])
return baseset()

-def rangeset(repo, subset, x, y):
+def rangeset(repo, subset, x, y, o):
m = getset(repo, fullreposet(repo), x)
n = getset(repo, fullreposet(repo), y)

@@ -375,12 +375,13 @@  def rangeset(repo, subset, x, y):
r = spanset(repo, m, n + 1)
else:
r = spanset(repo, m, n - 1)
-    # XXX We should combine with subset first: 'subset & baseset(...)'. This is
-    # necessary to ensure we preserve the order in subset.
-    #
-    # This has performance implication, carrying the sorting over when possible
-    # would be more efficient.
-    return r & subset
+
+    order = getstring(o, "internal error: rangeset requires a order string")
+    if order == _defineorder:
+        return r & subset
+    else:
+        # carrying the sorting over when possible would be more efficient
+        return subset & r

def dagrange(repo, subset, x, y):
r = fullreposet(repo)
@@ -2229,7 +2230,11 @@  def _optimize(x, small, order):
return o[0], (op, o[1])
elif op == 'group':
return _optimize(x[1], small, order)
-    elif op in 'dagrange range parent ancestorspec':
+    elif op == 'range':
+        wa, ta = _optimize(x[1], small, _defineorder)
+        wb, tb = _optimize(x[2], small, _defineorder)
+        return wa + wb, (op, ta, tb, ('string', order))
+    elif op in 'dagrange parent ancestorspec':
if op == 'parent':
# x^:y means (x^) : y, not x ^ (:y)
post = ('parentpost', x[1])
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -123,7 +123,8 @@  trivial
* optimized:
(range
('string', '0')
-    ('string', 'tip'))
+    ('string', 'tip')
+    ('string', 'define'))
* set:
<spanset+ 0:9>
0
@@ -706,7 +707,8 @@  Test opreand of '%' is optimized recursi
(difference
(range
('symbol', '8')
-        ('symbol', '9'))
+        ('symbol', '9')
+        ('string', 'define'))
('symbol', '8')))
* set:
<baseset+ [8, 9]>
@@ -913,6 +915,46 @@  Test order of revisions in compound expr
1
0

+ 'x:y' takes ordering parameter:
+
+  \$ try --optimize '3:0 & 0:3 & not 2:1'
+  (and
+    (and
+      (range
+        ('symbol', '3')
+        ('symbol', '0'))
+      (range
+        ('symbol', '0')
+        ('symbol', '3')))
+    (not
+      (range
+        ('symbol', '2')
+        ('symbol', '1'))))
+  * optimized:
+  (difference
+    (and
+      (range
+        ('symbol', '3')
+        ('symbol', '0')
+        ('string', 'define'))
+      (range
+        ('symbol', '0')
+        ('symbol', '3')
+        ('string', 'follow')))
+    (range
+      ('symbol', '2')
+      ('symbol', '1')
+      ('string', 'any')))
+  * set:
+  <filteredset
+    <filteredset
+      <spanset- 0:3>,
+      <spanset+ 0:3>>,
+    <not
+      <spanset+ 1:2>>>
+  3
+  0
+
'_reorder' should be inserted where necessary:

\$ try --optimize '2:0 & (0 + 1 + 2)'
@@ -929,7 +971,8 @@  Test order of revisions in compound expr
(and
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', '_reorder')
(func
@@ -958,21 +1001,23 @@  Test order of revisions in compound expr
(and
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', '_reorder')
(or
(range
('symbol', '0')
-          ('symbol', '1'))
+          ('symbol', '1')
+          ('string', 'follow'))
('symbol', '2'))))
* set:
<filteredset
<spanset- 0:2>,
<filteredset
-        <spanset+ 0:1>,
-        <spanset- 0:2>>,
+        <spanset- 0:2>,
+        <spanset+ 0:1>>,
<baseset [2]>>>
2
1
@@ -997,7 +1042,8 @@  Test order of revisions in compound expr
(and
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', 'present')
(func
@@ -1027,7 +1073,8 @@  Test order of revisions in compound expr
(and
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', 'present')
(func
@@ -1057,7 +1104,8 @@  Test order of revisions in compound expr
(difference
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', '_list')
('string', '0\x001')))
@@ -1087,11 +1135,13 @@  Test order of revisions in compound expr
(difference
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(and
(range
('symbol', '0')
-        ('symbol', '2'))
+        ('symbol', '2')
+        ('string', 'any'))
(func
('symbol', '_list')
('string', '0\x001'))))
@@ -1119,7 +1169,8 @@  Test order of revisions in compound expr
(and
(range
('symbol', '0')
-      ('symbol', '2'))
+      ('symbol', '2')
+      ('string', 'define'))
(func
('symbol', '_reorder')
(func
@@ -1154,7 +1205,8 @@  Test order of revisions in compound expr
(and
(range
('symbol', '0')
-      ('symbol', '2'))
+      ('symbol', '2')
+      ('string', 'define'))
(func
('symbol', '_reorder')
(func
@@ -1191,7 +1243,8 @@  Test order of revisions in compound expr
(and
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', 'first')
(func
@@ -1220,7 +1273,8 @@  Test order of revisions in compound expr
(difference
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(func
('symbol', 'last')
(func
@@ -1259,18 +1313,20 @@  Test order of revisions in compound expr
(and
(range
('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
(range
(func
('symbol', '_list')
('string', '1\x000\x002'))
(func
('symbol', '_list')
-        ('string', '0\x002\x001'))))
+        ('string', '0\x002\x001'))
+      ('string', 'follow')))
* set:
<filteredset
-    <baseset [1]>,
-    <spanset- 0:2>>
+    <spanset- 0:2>,
+    <baseset [1]>>
1

'A & B' can be rewritten as 'B & A' by weight, but that's fine as long as
@@ -1673,7 +1729,8 @@  test optimization of trivial `or` operat
('string', '0\x001'))
(range
('symbol', '2')
-      ('symbol', '3')))
+      ('symbol', '3')
+      ('string', 'define')))
* set:
<baseset [0, 1]>,
@@ -1698,11 +1755,13 @@  test optimization of trivial `or` operat
(or
(range
('symbol', '0')
-      ('symbol', '1'))
+      ('symbol', '1')
+      ('string', 'define'))
('symbol', '2')
(range
('symbol', '3')
-      ('symbol', '4'))
+      ('symbol', '4')
+      ('string', 'define'))
(func
('symbol', '_list')
('string', '5\x006')))

```