Patchwork [5,of,5] smartset: micro optimize spanset.slice() to narrow range accordingly

login
register
mail settings
Submitter Yuya Nishihara
Date June 13, 2017, 2:15 p.m.
Message ID <492e99b540fc32838481.1497363359@mimosa>
Download mbox | patch
Permalink /patch/21359/
State Accepted
Headers show

Comments

Yuya Nishihara - June 13, 2017, 2:15 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1428592456 -32400
#      Fri Apr 10 00:14:16 2015 +0900
# Node ID 492e99b540fc3283848168ecc9d781e931a5e9fc
# Parent  72a4a69c2d18c0cba33956a634c9d3e56ecd9bf9
smartset: micro optimize spanset.slice() to narrow range accordingly

-1ms isn't significant, but seems not bad.

  revset #0: limit(0:9999, 100, 9000)
  6) 0.001145
  7) 0.000214
  revset #3: last(0:9999, 100)
  6) 0.000197
  7) 0.000171
Augie Fackler - June 13, 2017, 2:51 p.m.
On Tue, Jun 13, 2017 at 11:15:59PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1428592456 -32400
> #      Fri Apr 10 00:14:16 2015 +0900
> # Node ID 492e99b540fc3283848168ecc9d781e931a5e9fc
> # Parent  72a4a69c2d18c0cba33956a634c9d3e56ecd9bf9
> smartset: micro optimize spanset.slice() to narrow range accordingly

queued, thanks

Patch

diff --git a/mercurial/smartset.py b/mercurial/smartset.py
--- a/mercurial/smartset.py
+++ b/mercurial/smartset.py
@@ -1056,6 +1056,18 @@  class _spanset(abstractsmartset):
             return x
         return None
 
+    def _slice(self, start, stop):
+        if self._hiddenrevs:
+            # unoptimized since all hidden revisions in range has to be scanned
+            return super(_spanset, self)._slice(start, stop)
+        if self._ascending:
+            x = min(self._start + start, self._end)
+            y = min(self._start + stop, self._end)
+        else:
+            x = max(self._end - stop, self._start)
+            y = max(self._end - start, self._start)
+        return _spanset(x, y, self._ascending, self._hiddenrevs)
+
     def __repr__(self):
         d = {False: '-', True: '+'}[self._ascending]
         return '<%s%s %d:%d>' % (type(self).__name__.lstrip('_'), d,
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1080,13 +1080,54 @@  Test smartset.slice() by first/last()
   * set:
   <baseset+ []>
 
+ (using spanset)
+
+  $ hg debugrevspec --no-show-revs -s 0:7
+  * set:
+  <spanset+ 0:8>
+  $ log 'limit(0:7, 3, 4)'
+  4
+  5
+  6
+  $ log 'limit(7:0, 3, 4)'
+  3
+  2
+  1
+  $ log 'limit(0:7, 3, 6)'
+  6
+  7
+  $ log 'limit(7:0, 3, 6)'
+  1
+  0
+  $ log 'last(0:7, 2)'
+  6
+  7
+  $ hg debugrevspec -s 'limit(0:7, 3, 6)'
+  * set:
+  <spanset+ 6:8>
+  6
+  7
+  $ hg debugrevspec -s 'limit(0:7, 3, 9)'
+  * set:
+  <spanset+ 8:8>
+  $ hg debugrevspec -s 'limit(7:0, 3, 6)'
+  * set:
+  <spanset- 0:2>
+  1
+  0
+  $ hg debugrevspec -s 'limit(7:0, 3, 9)'
+  * set:
+  <spanset- 0:0>
+  $ hg debugrevspec -s 'limit(0:7, 0)'
+  * set:
+  <spanset+ 0:0>
+
 Test order of first/last revisions
 
   $ hg debugrevspec -s 'first(4:0, 3) & 3:'
   * set:
   <filteredset
-    <baseset slice=0:3
-      <spanset- 0:5>>,
+    <spanset- 2:5>,
     <spanset+ 3:10>>
   4
   3
@@ -1095,16 +1136,14 @@  Test order of first/last revisions
   * set:
   <filteredset
     <spanset+ 3:10>,
-    <baseset slice=0:3
-      <spanset- 0:5>>>
+    <spanset- 2:5>>
   3
   4
 
   $ hg debugrevspec -s 'last(4:0, 3) & :1'
   * set:
   <filteredset
-    <baseset slice=0:3
-      <spanset+ 0:5>>,
+    <spanset- 0:3>,
     <spanset+ 0:2>>
   1
   0
@@ -1113,8 +1152,7 @@  Test order of first/last revisions
   * set:
   <filteredset
     <spanset+ 0:2>,
-    <baseset slice=0:3
-      <spanset+ 0:5>>>
+    <spanset+ 0:3>>
   0
   1