smartset: extract method to slice abstractsmartset
Sub classes can provide optimized implementations.
--- a/mercurial/revset.py Sun May 24 11:07:14 2015 +0900
+++ b/mercurial/revset.py Tue Mar 24 00:14:53 2015 +0900
@@ -1169,18 +1169,7 @@
if ofs < 0:
raise error.ParseError(_("negative offset"))
os = getset(repo, fullreposet(repo), args['set'])
- result = []
- it = iter(os)
- for x in xrange(ofs):
- y = next(it, None)
- if y is None:
- break
- for x in xrange(lim):
- y = next(it, None)
- if y is None:
- break
- result.append(y)
- ls = baseset(result, datarepr=('<limit n=%d, offset=%d, %r>', lim, ofs, os))
+ ls = os.slice(ofs, ofs + lim)
if order == followorder and lim > 1:
return subset & ls
return ls & subset
@@ -1199,14 +1188,7 @@
raise error.ParseError(_("negative number to select"))
os = getset(repo, fullreposet(repo), l[0])
os.reverse()
- result = []
- it = iter(os)
- for x in xrange(lim):
- y = next(it, None)
- if y is None:
- break
- result.append(y)
- ls = baseset(result, datarepr=('<last n=%d, %r>', lim, os))
+ ls = os.slice(0, lim)
if order == followorder and lim > 1:
return subset & ls
ls.reverse()
--- a/mercurial/smartset.py Sun May 24 11:07:14 2015 +0900
+++ b/mercurial/smartset.py Tue Mar 24 00:14:53 2015 +0900
@@ -8,6 +8,7 @@
from __future__ import absolute_import
from . import (
+ error,
util,
)
@@ -155,6 +156,28 @@
condition = util.cachefunc(condition)
return filteredset(self, condition, condrepr)
+ def slice(self, start, stop):
+ """Return new smartset that contains selected elements from this set"""
+ if start < 0 or stop < 0:
+ raise error.ProgrammingError('negative index not allowed')
+ return self._slice(start, stop)
+
+ def _slice(self, start, stop):
+ # sub classes may override this. start and stop must not be negative,
+ # but start > stop is allowed, which should be an empty set.
+ ys = []
+ it = iter(self)
+ for x in xrange(start):
+ y = next(it, None)
+ if y is None:
+ break
+ for x in xrange(stop - start):
+ y = next(it, None)
+ if y is None:
+ break
+ ys.append(y)
+ return baseset(ys, datarepr=('slice=%d:%d %r', start, stop, self))
+
class baseset(abstractsmartset):
"""Basic data structure that represents a revset and contains the basic
operation that it should be able to perform.
--- a/tests/test-revset.t Sun May 24 11:07:14 2015 +0900
+++ b/tests/test-revset.t Tue Mar 24 00:14:53 2015 +0900
@@ -1016,14 +1016,34 @@
8
9
+Test smartset.slice() by first/last()
+
+ (using unoptimized set, filteredset as example)
+
+ $ hg debugrevspec --no-show-revs -s '0:7 & branch("re:")'
+ * set:
+ <filteredset
+ <spanset+ 0:8>,
+ <branch 're:'>>
+ $ log 'limit(0:7 & branch("re:"), 3, 4)'
+ 4
+ 5
+ 6
+ $ log 'limit(7:0 & branch("re:"), 3, 4)'
+ 3
+ 2
+ 1
+ $ log 'last(0:7 & branch("re:"), 2)'
+ 6
+ 7
+
Test order of first/last revisions
$ hg debugrevspec -s 'first(4:0, 3) & 3:'
* set:
<filteredset
- <baseset
- <limit n=3, offset=0,
- <spanset- 0:5>>>,
+ <baseset slice=0:3
+ <spanset- 0:5>>,
<spanset+ 3:10>>
4
3
@@ -1032,18 +1052,16 @@
* set:
<filteredset
<spanset+ 3:10>,
- <baseset
- <limit n=3, offset=0,
- <spanset- 0:5>>>>
+ <baseset slice=0:3
+ <spanset- 0:5>>>
3
4
$ hg debugrevspec -s 'last(4:0, 3) & :1'
* set:
<filteredset
- <baseset
- <last n=3,
- <spanset+ 0:5>>>,
+ <baseset slice=0:3
+ <spanset+ 0:5>>,
<spanset+ 0:2>>
1
0
@@ -1052,9 +1070,8 @@
* set:
<filteredset
<spanset+ 0:2>,
- <baseset
- <last n=3,
- <spanset+ 0:5>>>>
+ <baseset slice=0:3
+ <spanset+ 0:5>>>
0
1
@@ -1950,9 +1967,8 @@
define)
* set:
<filteredset
- <baseset
- <limit n=1, offset=0,
- <baseset [1, 0, 2]>>>,
+ <baseset slice=0:1
+ <baseset [1, 0, 2]>>,
<spanset- 0:3>>
1
@@ -1987,9 +2003,8 @@
<filteredset
<spanset- 0:3>,
<not
- <baseset
- <last n=1,
- <baseset [1, 2, 0]>>>>>
+ <baseset slice=0:1
+ <baseset [1, 2, 0]>>>>
2
0
@@ -3613,9 +3628,8 @@
('symbol', '2')))
* set:
<filteredset
- <baseset
- <limit n=2, offset=0,
- <baseset [1, 2, 3]>>>,
+ <baseset slice=0:2
+ <baseset [1, 2, 3]>>,
<not
<baseset [2]>>>
1
@@ -3669,9 +3683,8 @@
('symbol', '2')))
* set:
<filteredset
- <baseset
- <last n=1,
- <baseset [2, 1]>>>,
+ <baseset slice=0:1
+ <baseset [2, 1]>>,
<not
<baseset [2]>>>