revset: fast implementation for fullreposet.__and__
authorPierre-Yves David <pierre-yves.david@fb.com>
Wed, 24 Sep 2014 20:11:36 -0700
changeset 22510 911f5a6579d1
parent 22509 fbae659543cf
child 22511 b1ec65b3ba31
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 improvements are expected in the future as more revset predicate are converted to use `subset & xxx` The relaxed way `fullreposet` handles "&" operation may cause some trouble for people comparing smartset from different filter levels. I'm not sure such people exist and we can improve that aspect in later patches.
mercurial/revset.py
--- a/mercurial/revset.py	Thu Sep 18 13:04:02 2014 -0700
+++ b/mercurial/revset.py	Wed Sep 24 20:11:36 2014 -0700
@@ -2871,5 +2871,36 @@
     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 assumes 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 assumes all smartset are pure)
+            #
+            # `other` was used with "&", let's assume this is a set like
+            # object.
+            other = baseset(other - self._hiddenrevs)
+        elif not util.safehasattr(other, 'ascending'):
+            # "other" is _generatorset not a real smart set
+            # we fallback to the old way (sad kitten)
+            return super(fullreposet, self).__and__(other)
+
+        # preserve order:
+        #
+        # this is probably useless and harmful in multiple cases but matches
+        # the current behavior.
+        if self.isascending():
+            other.ascending()
+        else:
+            other.descending()
+        return other
+
 # tell hggettext to extract docstrings from these functions:
 i18nfunctions = symbols.values()