Patchwork [5,of,7,V4] revset: add option to make nested range follow ordering of input set (BC)

login
register
mail settings
Submitter Yuya Nishihara
Date June 23, 2016, 3:59 p.m.
Message ID <7fcfd3c037c8695a510e.1466697597@mimosa>
Download mbox | patch
Permalink /patch/15583/
State Accepted
Headers show

Comments

Yuya Nishihara - June 23, 2016, 3:59 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1462247570 -32400
#      Tue May 03 12:52:50 2016 +0900
# Node ID 7fcfd3c037c8695a510e633c7f92432acda35118
# Parent  fb16f5ab09a67c438615294f1e98a4b7cd84a91a
revset: add option to make nested range follow ordering of input set (BC)

This is simpler and faster than inserting generic _unordered() 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)
@@ -2474,7 +2475,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
@@ -163,7 +163,8 @@  trivial
   * optimized:
   (range
     ('string', '0')
-    ('string', 'tip'))
+    ('string', 'tip')
+    ('string', 'define'))
   * set:
   <spanset+ 0:9>
   0
@@ -746,7 +747,8 @@  Test opreand of '%' is optimized recursi
     (difference
       (range
         ('symbol', '8')
-        ('symbol', '9'))
+        ('symbol', '9')
+        ('string', 'define'))
       ('symbol', '8')))
   * set:
   <baseset+ [8, 9]>
@@ -960,6 +962,46 @@  ordering defined by it.
   2
  BROKEN: should be '2 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
+
  'a + b', which is optimized to '_list(a b)', should take the ordering of
  the left expression:
 
@@ -977,7 +1019,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', '_unordered')
       (func
@@ -1008,13 +1051,15 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', '_unordered')
       (or
         (range
           ('symbol', '0')
-          ('symbol', '1'))
+          ('symbol', '1')
+          ('string', 'follow'))
         ('symbol', '2'))))
   * set:
   <filteredset
@@ -1045,7 +1090,8 @@  ordering defined by it.
         ('string', '0\x001\x002')))
     (range
       ('symbol', '2')
-      ('symbol', '0')))
+      ('symbol', '0')
+      ('string', 'define')))
   * set:
   <filteredset
     <spanset- 0:2>,
@@ -1069,15 +1115,15 @@  ordering defined by it.
       ('string', '0\x002\x001'))
     (range
       ('symbol', '2')
-      ('symbol', '0')))
+      ('symbol', '0')
+      ('string', 'follow')))
   * set:
   <filteredset
-    <spanset- 0:2>,
-    <baseset [0, 2, 1]>>
+    <baseset [0, 2, 1]>,
+    <spanset- 0:2>>
+  0
   2
   1
-  0
- BROKEN: should be '0 2 1'
 
  '_hexlist(a b)' should behave like 'a + b':
 
@@ -1093,7 +1139,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', '_unordered')
       (func
@@ -1119,7 +1166,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'follow'))
     (func
       ('symbol', '_hexlist')
       ('string', '*'))) (glob)
@@ -1145,7 +1193,8 @@  ordering defined by it.
   (difference
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', '_list')
       ('string', '0\x001')))
@@ -1175,11 +1224,13 @@  ordering defined by it.
   (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'))))
@@ -1209,7 +1260,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', 'present')
       (func
@@ -1239,7 +1291,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', 'present')
       (func
@@ -1269,7 +1322,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '0')
-      ('symbol', '2'))
+      ('symbol', '2')
+      ('string', 'define'))
     (func
       ('symbol', 'reverse')
       (func
@@ -1303,7 +1357,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '0')
-      ('symbol', '2'))
+      ('symbol', '2')
+      ('string', 'define'))
     (func
       ('symbol', 'sort')
       (list
@@ -1337,7 +1392,8 @@  ordering defined by it.
   (and
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', 'first')
       (func
@@ -1366,7 +1422,8 @@  ordering defined by it.
   (difference
     (range
       ('symbol', '2')
-      ('symbol', '0'))
+      ('symbol', '0')
+      ('string', 'define'))
     (func
       ('symbol', 'last')
       (func
@@ -1405,18 +1462,20 @@  ordering defined by it.
   (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
@@ -1887,7 +1946,8 @@  test optimization of trivial `or` operat
       ('string', '0\x001'))
     (range
       ('symbol', '2')
-      ('symbol', '3')))
+      ('symbol', '3')
+      ('string', 'define')))
   * set:
   <addset
     <baseset [0, 1]>,
@@ -1912,11 +1972,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')))