Patchwork [4,of,4,V2] revset: fast implementation for fullreposet.__and__

login
register
mail settings
Submitter Pierre-Yves David
Date Sept. 23, 2014, 7:28 p.m.
Message ID <c25eb94bc242f4c7c761.1411500509@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5922/
State Accepted
Headers show

Comments

Pierre-Yves David - Sept. 23, 2014, 7:28 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1398878911 25200
#      Wed Apr 30 10:28:31 2014 -0700
# Node ID c25eb94bc242f4c7c7615d9094944a5ec23307be
# Parent  bfa28d90f22b612283e211a8472b8a46e48f1eea
revset: fast implementation for fullreposet.__and__

"And" operation with something that contains the whole repo should be super
cheap. Check method docstring for details.

This provide massive boost to simple revset that use `subset & xxx`

revset #0: p1(20000)
0) wall 0.002447 comb 0.010000 user 0.010000 sys 0.000000 (best of 767)
1) wall 0.000529 comb 0.000000 user 0.000000 sys 0.000000 (best of 3947)

revset #1: p2(10000)
0) wall 0.002464 comb 0.000000 user 0.000000 sys 0.000000 (best of 913)
1) wall 0.000530 comb 0.000000 user 0.000000 sys 0.000000 (best of 4226)

No other regression spotted.

More performance are expected  in the future as more revset predicate are
converted to use `subset & xxx`

The relaxed way `fullreposet` handle "&" operation may cause some trouble for
people comparing smartset from different filter level. I'm not sure such people
exists and can improve that aspect in later patches.
Durham Goode - Sept. 23, 2014, 10:40 p.m.
On 9/23/14, 12:28 PM, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1398878911 25200
> #      Wed Apr 30 10:28:31 2014 -0700
> # Node ID c25eb94bc242f4c7c7615d9094944a5ec23307be
> # Parent  bfa28d90f22b612283e211a8472b8a46e48f1eea
> revset: fast implementation for fullreposet.__and__
>
> "And" operation with something that contains the whole repo should be super
> cheap. Check method docstring for details.
>
> This provide massive boost to simple revset that use `subset & xxx`
>
> revset #0: p1(20000)
> 0) wall 0.002447 comb 0.010000 user 0.010000 sys 0.000000 (best of 767)
> 1) wall 0.000529 comb 0.000000 user 0.000000 sys 0.000000 (best of 3947)
>
> revset #1: p2(10000)
> 0) wall 0.002464 comb 0.000000 user 0.000000 sys 0.000000 (best of 913)
> 1) wall 0.000530 comb 0.000000 user 0.000000 sys 0.000000 (best of 4226)
>
> No other regression spotted.
>
> More performance are expected  in the future as more revset predicate are
> converted to use `subset & xxx`
>
> The relaxed way `fullreposet` handle "&" operation may cause some trouble for
> people comparing smartset from different filter level. I'm not sure such people
> exists and can improve that aspect in later patches.
>
Queued to the clowncopter repo.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2865,7 +2865,34 @@  class fullreposet(_spanset):
     """
 
     def __init__(self, repo):
         super(fullreposet, self).__init__(repo)
 
+    def __and__(self, other):
+        """fullrepo & other -> other
+
+        As self contains the whole repo, all of the other set should also be in
+        self. Therefor `self & other = other`.
+
+        This boldly assume the other contains valid revs only.
+        """
+        # other not a smartset, make is so
+        if not util.safehasattr(other, 'set'):
+            # filter out hidden revision
+            # (this boldly assume all smartset are pure)
+            #
+            # `other` was used with "&", let's assume this is a set like
+            # object.
+            other = baseset(other - self._hiddenrevs)
+
+        # preserve order:
+        #
+        # this is probably useless and harmful in multiple case but this match
+        # the current behavior.
+        if self.isascending():
+            other.ascending()
+        else:
+            other.descending()
+        return other
+
 # tell hggettext to extract docstrings from these functions:
 i18nfunctions = symbols.values()