[PATCH 5 of 5 V2] revset: make __and__ use _optimizeand

Durham Goode durham at fb.com
Tue Sep 30 13:02:54 CDT 2014


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1412036980 25200
#      Mon Sep 29 17:29:40 2014 -0700
# Node ID b9b6ff020346e2491e9b6574566de9638da11fb2
# Parent  afa88d660f03f3e19a4f9c1cba2442446a4db733
revset: make __and__ use _optimizeand

This makes each __and__ implementation first call _optimizeand 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)

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2287,7 +2287,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 = _optimizeand(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.
@@ -2389,7 +2391,8 @@ class lazyset(object):
                 yield x
 
     def __and__(self, x):
-        return lazyset(self, x.__contains__)
+        iterate, check = _optimizeand(self, x)
+        return lazyset(iterate, check.__contains__)
 
     def __sub__(self, x):
         return lazyset(self, lambda r: r not in x)
@@ -2455,7 +2458,8 @@ class orderedlazyset(_orderedsetmixin, l
             self.reverse()
 
     def __and__(self, x):
-        return orderedlazyset(self, x.__contains__,
+        iterate, check = _optimizeand(self, x)
+        return orderedlazyset(iterate, check.__contains__,
                 ascending=self._ascending)
 
     def __sub__(self, x):
@@ -2547,10 +2551,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 = _optimizeand(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
@@ -2862,7 +2868,9 @@ class _spanset(_orderedsetmixin):
     def __and__(self, x):
         if isinstance(x, baseset):
             x = x.set()
-        return orderedlazyset(self, x.__contains__,
+
+        iterate, check = _optimizeand(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


More information about the Mercurial-devel mailing list