Patchwork [3,of,4] revset: add _optimize_and function

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

Comments

Durham Goode - Sept. 30, 2014, 1:12 a.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1412036832 25200
#      Mon Sep 29 17:27:12 2014 -0700
# Node ID 090bc7d312f7c8ad94d9a380fd0e9f80a0e8e5c7
# Parent  93be919300f04bfd26fd5294499fb62c96ba7f93
revset: add _optimize_and function

Adds an _optimize_and function that takes two sets (the iterate set, and the
check set) and reverses them if the iterate set is bigger than the check set.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -16,6 +16,8 @@  import encoding
 import obsolete as obsmod
 import pathutil
 import repoview
+import sys
+import util
 
 def _revancestors(repo, revs, followfirst):
     """Like revlog.ancestors(), but supports followfirst."""
@@ -2194,6 +2196,33 @@  def funcsused(tree):
             funcs.add(tree[1][1])
         return funcs
 
+def _optimize_and(iterate, check):
+    """Return the given sets in the optimal order for iterating and checking
+    containment. The iterate set is the first return arg, the check set is the
+    second.
+    """
+    if util.safehasattr(iterate, '__length_hint__'):
+        ilen = iterate.__length_hint__()
+    elif util.safehasattr(iterate, '__len__'):
+        ilen = len(iterate)
+    else:
+        ilen = sys.maxint
+
+    if util.safehasattr(check, '__length_hint__'):
+        clen = check.__length_hint__()
+    elif util.safehasattr(check, '__len__'):
+        clen = len(check)
+    else:
+        clen = sys.maxint
+
+    # Don't reorder if the `check` is a set. Many revsets assume the result will
+    # be a smart class, and if we reorder such that there is a set on the left
+    # of a X & Y expression, the result is a set, which breaks things.
+    if ilen > clen and not isinstance(check, set):
+        return check, iterate
+    else:
+        return iterate, check
+
 class baseset(list):
     """Basic data structure that represents a revset and contains the basic
     operation that it should be able to perform.