changeset 32801:348b491c0934

revset: fix order of first/last members in compound expression (BC) Suppose len(subset) >> len(ls) in common cases, 'subset & ls' should be avoided whenever possible.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 10 Jun 2017 19:48:48 +0900
parents 3e6f9bff7e3f
children f40eec7af044
files mercurial/revset.py tests/test-revset.t
diffstat 2 files changed, 17 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Sat Jun 10 19:41:42 2017 +0900
+++ b/mercurial/revset.py	Sat Jun 10 19:48:48 2017 +0900
@@ -884,11 +884,11 @@
 
     return subset & s
 
-@predicate('first(set, [n])', safe=True)
-def first(repo, subset, x):
+@predicate('first(set, [n])', safe=True, takeorder=True)
+def first(repo, subset, x, order):
     """An alias for limit().
     """
-    return limit(repo, subset, x)
+    return limit(repo, subset, x, order)
 
 def _follow(repo, subset, x, name, followfirst=False):
     l = getargs(x, 0, 2, _("%s takes no arguments or a pattern "
@@ -1152,8 +1152,8 @@
 
     return subset.filter(matches, condrepr=('<keyword %r>', kw))
 
-@predicate('limit(set[, n[, offset]])', safe=True)
-def limit(repo, subset, x):
+@predicate('limit(set[, n[, offset]])', safe=True, takeorder=True)
+def limit(repo, subset, x, order):
     """First n members of set, defaulting to 1, starting from offset.
     """
     args = getargsdict(x, 'limit', 'set n offset')
@@ -1181,10 +1181,12 @@
             break
         result.append(y)
     ls = baseset(result, datarepr=('<limit n=%d, offset=%d, %r>', lim, ofs, os))
+    if order == followorder and lim > 1:
+        return subset & ls
     return ls & subset
 
-@predicate('last(set, [n])', safe=True)
-def last(repo, subset, x):
+@predicate('last(set, [n])', safe=True, takeorder=True)
+def last(repo, subset, x, order):
     """Last n members of set, defaulting to 1.
     """
     # i18n: "last" is a keyword
@@ -1205,6 +1207,8 @@
             break
         result.append(y)
     ls = baseset(result, datarepr=('<last n=%d, %r>', lim, os))
+    if order == followorder and lim > 1:
+        return subset & ls
     ls.reverse()
     return ls & subset
 
--- a/tests/test-revset.t	Sat Jun 10 19:41:42 2017 +0900
+++ b/tests/test-revset.t	Sat Jun 10 19:48:48 2017 +0900
@@ -1031,13 +1031,12 @@
   $ hg debugrevspec -s '3: & first(4:0, 3)'
   * set:
   <filteredset
+    <spanset+ 3:9>,
     <baseset
       <limit n=3, offset=0,
-        <spanset- 0:4>>>,
-    <spanset+ 3:9>>
+        <spanset- 0:4>>>>
+  3
   4
-  3
-BROKEN: should be '3 4'
 
   $ hg debugrevspec -s 'last(4:0, 3) & :1'
   * set:
@@ -1052,13 +1051,12 @@
   $ hg debugrevspec -s ':1 & last(4:0, 3)'
   * set:
   <filteredset
+    <spanset+ 0:1>,
     <baseset
       <last n=3,
-        <spanset+ 0:4>>>,
-    <spanset+ 0:1>>
+        <spanset+ 0:4>>>>
+  0
   1
-  0
-BROKEN: should be '0 1'
 
 Test matching