Patchwork [4,of,4] revset: make __and__ use _optimize_and

login
register
mail settings
Submitter Durham Goode
Date Sept. 30, 2014, 1:12 a.m.
Message ID <da02de5d7925a3f98898.1412039533@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/6032/
State Superseded
Headers show

Comments

Durham Goode - Sept. 30, 2014, 1:12 a.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1412036980 25200
#      Mon Sep 29 17:29:40 2014 -0700
# Node ID da02de5d7925a3f98898034738ec0b2b7589c08e
# Parent  090bc7d312f7c8ad94d9a380fd0e9f80a0e8e5c7
revset: make __and__ use _optimize_and

This makes each __and__ implementation first call _optimize_and to reorder the
iteration set and the containment check set such that the smaller of the two is
iterated over.

On a large repo, this shaves 40% off certain rebase times (17 seconds -> 9
seconds).

revset #29: (children(ancestor(tip~5, tip)) and ::(tip~5))::
0) wall 0.175531 comb 0.180000 user 0.180000 sys 0.000000 (best of 48)
1) wall 0.015348 comb 0.020000 user 0.020000 sys 0.000000 (best of 111)

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2288,7 +2288,9 @@  class baseset(list):
         This is part of the mandatory API for smartset."""
         if isinstance(other, baseset):
             other = other.set()
-        return baseset([y for y in self if y in other])
+
+        iterate, check = _optimize_and(self, other)
+        return baseset([y for y in iterate if y in check])
 
     def __add__(self, other):
         """Returns a new object with the union of the two collections.
@@ -2390,7 +2392,8 @@  class lazyset(object):
                 yield x
 
     def __and__(self, x):
-        return lazyset(self, x.__contains__)
+        iterate, check = _optimize_and(self, x)
+        return lazyset(iterate, check.__contains__)
 
     def __sub__(self, x):
         return lazyset(self, lambda r: r not in x)
@@ -2456,7 +2459,8 @@  class orderedlazyset(_orderedsetmixin, l
             self.reverse()
 
     def __and__(self, x):
-        return orderedlazyset(self, x.__contains__,
+        iterate, check = _optimize_and(self, x)
+        return orderedlazyset(iterate, check.__contains__,
                 ascending=self._ascending)
 
     def __sub__(self, x):
@@ -2544,10 +2548,12 @@  class _addset(_orderedsetmixin):
                 self.reverse()
 
     def __and__(self, other):
-        filterfunc = other.__contains__
-        if self._ascending is not None:
-            return orderedlazyset(self, filterfunc, ascending=self._ascending)
-        return lazyset(self, filterfunc)
+        iterate, check = _optimize_and(self, other)
+        filterfunc = check.__contains__
+        if iterate._ascending is not None:
+            return orderedlazyset(iterate, filterfunc,
+                ascending=iterate._ascending)
+        return lazyset(iterate, filterfunc)
 
     def __sub__(self, other):
         filterfunc = lambda r: r not in other
@@ -2861,7 +2867,9 @@  class _spanset(_orderedsetmixin):
     def __and__(self, x):
         if isinstance(x, baseset):
             x = x.set()
-        return orderedlazyset(self, x.__contains__,
+
+        iterate, check = _optimize_and(self, x)
+        return orderedlazyset(iterate, check.__contains__,
                               ascending=self.isascending())
 
     def __sub__(self, x):
diff --git a/tests/test-rebase-scenario-global.t b/tests/test-rebase-scenario-global.t
--- a/tests/test-rebase-scenario-global.t
+++ b/tests/test-rebase-scenario-global.t
@@ -626,12 +626,6 @@  each root have a different common ancest
   $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)'
   saved backup bundle to $TESTTMP/a8/.hg/strip-backup/e7ec4e813ba6-backup.hg (glob)
   $ hg log --rev 'children(desc(G))'
-  changeset:   9:adb617877056
-  parent:      6:eea13746799a
-  user:        test
-  date:        Thu Jan 01 00:00:00 1970 +0000
-  summary:     I
-  
   changeset:   10:882431a34a0e
   tag:         tip
   parent:      6:eea13746799a
@@ -639,6 +633,12 @@  each root have a different common ancest
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     K
   
+  changeset:   9:adb617877056
+  parent:      6:eea13746799a
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     I
+  
   $ hg tglog
   @  10: 'K'
   |
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -273,8 +273,8 @@  ancestor can accept 0 or more arguments
   6 _a_b_c_
   7 .a.b.c.
   $ log 'children(ancestor(4,5))'
+  3
   2
-  3
   $ log 'closed()'
   $ log 'contains(a)'
   0