[PATCH 7 of 7] revset: fix order of nested '_(|int|hex)list' expression (BC)
Yuya Nishihara
yuya at tcha.org
Tue Sep 13 12:13:28 EDT 2016
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1466934088 -32400
# Sun Jun 26 18:41:28 2016 +0900
# Node ID 75ba18a83289dcff7b652a6db9334bcbd01f198f
# Parent 14af6142b21b0f3e3cf742410d4e7adb92ff4c76
revset: fix order of nested '_(|int|hex)list' expression (BC)
This fixes the order of 'x & (y + z)' where 'y' and 'z' are trivial, and the
other uses of _list()-family functions. The original functions are renamed to
'_ordered(|int|hex)list' to say clearly that they do not follow the subset
ordering.
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2253,9 +2253,7 @@ def wdir(repo, subset, x):
return baseset([node.wdirrev])
return baseset()
-# for internal use
- at predicate('_list', safe=True)
-def _list(repo, subset, x):
+def _orderedlist(repo, subset, x):
s = getstring(x, "internal error")
if not s:
return baseset()
@@ -2284,8 +2282,15 @@ def _list(repo, subset, x):
return baseset(ls)
# for internal use
- at predicate('_intlist', safe=True)
-def _intlist(repo, subset, x):
+ at predicate('_list', safe=True, takeorder=True)
+def _list(repo, subset, x, order):
+ if order == followorder:
+ # slow path to take the subset order
+ return subset & _orderedlist(repo, fullreposet(repo), x)
+ else:
+ return _orderedlist(repo, subset, x)
+
+def _orderedintlist(repo, subset, x):
s = getstring(x, "internal error")
if not s:
return baseset()
@@ -2294,8 +2299,15 @@ def _intlist(repo, subset, x):
return baseset([r for r in ls if r in s])
# for internal use
- at predicate('_hexlist', safe=True)
-def _hexlist(repo, subset, x):
+ at predicate('_intlist', safe=True, takeorder=True)
+def _intlist(repo, subset, x, order):
+ if order == followorder:
+ # slow path to take the subset order
+ return subset & _orderedintlist(repo, fullreposet(repo), x)
+ else:
+ return _orderedintlist(repo, subset, x)
+
+def _orderedhexlist(repo, subset, x):
s = getstring(x, "internal error")
if not s:
return baseset()
@@ -2304,6 +2316,15 @@ def _hexlist(repo, subset, x):
s = subset
return baseset([r for r in ls if r in s])
+# for internal use
+ at predicate('_hexlist', safe=True, takeorder=True)
+def _hexlist(repo, subset, x, order):
+ if order == followorder:
+ # slow path to take the subset order
+ return subset & _orderedhexlist(repo, fullreposet(repo), x)
+ else:
+ return _orderedhexlist(repo, subset, x)
+
methods = {
"range": rangeset,
"dagrange": dagrange,
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1281,11 +1281,12 @@ ordering defined by it.
follow)
define)
* set:
- <baseset [0, 1, 2]>
+ <filteredset
+ <spanset- 0:2>,
+ <baseset [0, 1, 2]>>
+ 2
+ 1
0
- 1
- 2
- BROKEN: should be '2 1 0'
'A + B' should take the ordering of the left expression:
@@ -1350,7 +1351,7 @@ ordering defined by it.
* set:
<filteredset
<spanset- 0:2>,
- <baseset [0, 1, 2]>>
+ <baseset+ [0, 1, 2]>>
2
1
0
@@ -1405,11 +1406,12 @@ ordering defined by it.
follow)
define)
* set:
- <baseset [0, 1, 2]>
+ <filteredset
+ <spanset- 0:2>,
+ <baseset [0, 1, 2]>>
+ 2
+ 1
0
- 1
- 2
- BROKEN: should be '2 1 0'
$ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
(and
@@ -1436,6 +1438,53 @@ ordering defined by it.
2
1
+ '_list' should not go through the slow follow-order path if order doesn't
+ matter:
+
+ $ try -p optimized '2:0 & not (0 + 1)'
+ * optimized:
+ (difference
+ (range
+ ('symbol', '2')
+ ('symbol', '0')
+ define)
+ (func
+ ('symbol', '_list')
+ ('string', '0\x001')
+ any)
+ define)
+ * set:
+ <filteredset
+ <spanset- 0:2>,
+ <not
+ <baseset [0, 1]>>>
+ 2
+
+ $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
+ * optimized:
+ (difference
+ (range
+ ('symbol', '2')
+ ('symbol', '0')
+ define)
+ (and
+ (range
+ ('symbol', '0')
+ ('symbol', '2')
+ any)
+ (func
+ ('symbol', '_list')
+ ('string', '0\x001')
+ any)
+ any)
+ define)
+ * set:
+ <filteredset
+ <spanset- 0:2>,
+ <not
+ <baseset [0, 1]>>>
+ 2
+
'present()' should do nothing other than suppressing an error:
$ try --optimize '2:0 & present(0 + 1 + 2)'
@@ -1662,9 +1711,10 @@ ordering defined by it.
<spanset- 0:2>>
1
- 'A & B' can be rewritten as 'B & A' by weight, but the ordering rule should
- be determined before the optimization (i.e. 'B' should take the ordering of
- 'A'):
+ 'A & B' can be rewritten as 'B & A' by weight, but that's fine as long as
+ the ordering rule is determined before the rewrite; in this example,
+ 'B' follows the order of the initial set, which is the same order as 'A'
+ since 'A' also follows the order:
$ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
(and
@@ -1690,12 +1740,14 @@ ordering defined by it.
define)
* set:
<filteredset
- <baseset [2, 0, 1]>,
+ <baseset+ [0, 1, 2]>,
<contains 'glob:*'>>
- 2
0
1
- BROKEN: should be '0 1 2'
+ 2
+
+ and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
+ the order appropriately:
$ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
(and
@@ -1726,12 +1778,11 @@ ordering defined by it.
define)
* set:
<filteredset
- <baseset [1, 2, 0]>,
+ <baseset- [0, 1, 2]>,
<contains 'glob:*'>>
+ 2
1
- 2
0
- BROKEN: should be '2 1 0'
test sort revset
--------------------------------------------
More information about the Mercurial-devel
mailing list