Patchwork [2,of,8] revset: added lazyset implementation to checkstatus

login
register
mail settings
Submitter Lucas Moscovicz
Date Feb. 11, 2014, 9:54 p.m.
Message ID <bccc2dbcf3b60c9c2d07.1392155680@dev1037.prn2.facebook.com>
Download mbox | patch
Permalink /patch/3591/
State Accepted
Commit ed7b674824a3e1f0fdbdc815bbf87b82999c3d73
Headers show

Comments

Lucas Moscovicz - Feb. 11, 2014, 9:54 p.m.
# HG changeset patch
# User Lucas Moscovicz <lmoscovicz@fb.com>
# Date 1391194071 28800
#      Fri Jan 31 10:47:51 2014 -0800
# Node ID bccc2dbcf3b60c9c2d0721c7ca5ebd09fa460c50
# Parent  9851a5014e418df1a1c908d1755d65836559c0c8
revset: added lazyset implementation to checkstatus

This improves the performance of the revsets 'adds' 'modifies' and 'removes'

Performance benchmarking:

$ time hg log -qr "first(adds(README))"
0:9117c6561b0b

real  0m2.279s
user  0m2.222s
sys 0m0.053s

$ time ./hg log -qr "first(adds(README))"
0:9117c6561b0b

real  0m0.172s
user  0m0.131s
sys 0m0.041s

$ time hg log -qr "first(modifies(README))"
1:273ce12ad8f1

real  0m2.292s
user  0m2.227s
sys 0m0.061s

$ time ./hg log -qr "first(modifies(README))"
1:273ce12ad8f1

real  0m0.178s
user  0m0.130s
sys 0m0.038s

$ time hg log -qr "first(removes(README))"
2379:e90cff87f871

real  0m2.297s
user  0m2.235s
sys 0m0.058s

$ time ./hg log -qr "first(removes(README))"
2379:e90cff87f871

real  0m0.975s
user  0m0.797s
sys 0m0.056s

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -464,35 +464,35 @@ 
     return subset & bundlerevs
 
 def checkstatus(repo, subset, pat, field):
-    m = None
-    s = []
     hasset = matchmod.patkind(pat) == 'set'
-    fname = None
-    for r in subset:
-        c = repo[r]
+
+    def matches(x):
+        m = None
+        fname = None
+        c = repo[x]
         if not m or hasset:
             m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
             if not m.anypats() and len(m.files()) == 1:
                 fname = m.files()[0]
         if fname is not None:
             if fname not in c.files():
-                continue
+                return False
         else:
             for f in c.files():
                 if m(f):
                     break
             else:
-                continue
+                return False
         files = repo.status(c.p1().node(), c.node())[field]
         if fname is not None:
             if fname in files:
-                s.append(r)
+                return True
         else:
             for f in files:
                 if m(f):
-                    s.append(r)
-                    break
-    return baseset(s)
+                    return True
+
+    return lazyset(subset, matches)
 
 def _children(repo, narrow, parentset):
     cs = set()