revset: filter first/last members by __and__ operation
This replaces 'if y in subset' with '& subset'. first(null) and last(wdir())
are fixed thanks to fullreposet.__and__.
This also revealed that first() and last() don't follow the order of the
input set. 'ls & subset' is valid only if the ordering requirement is 'define'
or 'any'.
No performance regression observed:
revset #0: limit(0:9999, 100, 9000)
0) 0.001164
1) 0.001135
revset #2: 9000 & limit(0:9999, 100, 9000)
0) 0.001224
1) 0.001181
revset #3: last(0:9999, 100)
0) 0.000237
1) 0.000199
--- a/mercurial/revset.py Sat Jun 10 18:35:11 2017 +0900
+++ b/mercurial/revset.py Sat Jun 10 19:41:42 2017 +0900
@@ -1179,10 +1179,9 @@
y = next(it, None)
if y is None:
break
- elif y in subset:
- result.append(y)
- return baseset(result, datarepr=('<limit n=%d, offset=%d, %r, %r>',
- lim, ofs, subset, os))
+ result.append(y)
+ ls = baseset(result, datarepr=('<limit n=%d, offset=%d, %r>', lim, ofs, os))
+ return ls & subset
@predicate('last(set, [n])', safe=True)
def last(repo, subset, x):
@@ -1204,10 +1203,10 @@
y = next(it, None)
if y is None:
break
- elif y in subset:
- result.append(y)
- return baseset(result[::-1], datarepr=('<last n=%d, %r, %r>',
- lim, subset, os))
+ result.append(y)
+ ls = baseset(result, datarepr=('<last n=%d, %r>', lim, os))
+ ls.reverse()
+ return ls & subset
@predicate('max(set)', safe=True)
def maxrev(repo, subset, x):
--- a/tests/test-revset.t Sat Jun 10 18:35:11 2017 +0900
+++ b/tests/test-revset.t Sat Jun 10 19:41:42 2017 +0900
@@ -1016,6 +1016,50 @@
8
9
+Test order of first/last revisions
+
+ $ hg debugrevspec -s 'first(4:0, 3) & 3:'
+ * set:
+ <filteredset
+ <baseset
+ <limit n=3, offset=0,
+ <spanset- 0:4>>>,
+ <spanset+ 3:9>>
+ 4
+ 3
+
+ $ hg debugrevspec -s '3: & first(4:0, 3)'
+ * set:
+ <filteredset
+ <baseset
+ <limit n=3, offset=0,
+ <spanset- 0:4>>>,
+ <spanset+ 3:9>>
+ 4
+ 3
+BROKEN: should be '3 4'
+
+ $ hg debugrevspec -s 'last(4:0, 3) & :1'
+ * set:
+ <filteredset
+ <baseset
+ <last n=3,
+ <spanset+ 0:4>>>,
+ <spanset+ 0:1>>
+ 1
+ 0
+
+ $ hg debugrevspec -s ':1 & last(4:0, 3)'
+ * set:
+ <filteredset
+ <baseset
+ <last n=3,
+ <spanset+ 0:4>>>,
+ <spanset+ 0:1>>
+ 1
+ 0
+BROKEN: should be '0 1'
+
Test matching
$ log 'matching(6)'
@@ -1230,10 +1274,10 @@
$ log 'reverse(null:)' | tail -2
0
-1
+ $ log 'first(null:)'
+ -1
+ $ log 'min(null:)'
BROKEN: should be '-1'
- $ log 'first(null:)'
-BROKEN: should be '-1'
- $ log 'min(null:)'
$ log 'tip:null and all()' | tail -2
1
0
@@ -1295,9 +1339,9 @@
9
$ log '(all() + wdir()) & max(. + wdir())'
2147483647
- $ log '(all() + wdir()) & first(wdir() + .)'
+ $ log 'first(wdir() + .)'
2147483647
- $ log '(all() + wdir()) & last(. + wdir())'
+ $ log 'last(. + wdir())'
2147483647
Test working-directory integer revision and node id
@@ -1907,10 +1951,11 @@
follow)
define)
* set:
- <baseset
- <limit n=1, offset=0,
- <spanset- 0:2>,
- <baseset [1, 0, 2]>>>
+ <filteredset
+ <baseset
+ <limit n=1, offset=0,
+ <baseset [1, 0, 2]>>>,
+ <spanset- 0:2>>
1
$ try --optimize '2:0 & not last(0 + 2 + 1)'
@@ -1946,7 +1991,6 @@
<not
<baseset
<last n=1,
- <fullreposet+ 0:9>,
<baseset [1, 2, 0]>>>>>
2
0
@@ -3573,7 +3617,6 @@
<filteredset
<baseset
<limit n=2, offset=0,
- <fullreposet+ 0:9>,
<baseset [1, 2, 3]>>>,
<not
<baseset [2]>>>
@@ -3630,7 +3673,6 @@
<filteredset
<baseset
<last n=1,
- <fullreposet+ 0:9>,
<baseset [2, 1]>>>,
<not
<baseset [2]>>>