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
--- a/mercurial/revset.py Thu Jan 30 17:46:08 2014 -0800
+++ b/mercurial/revset.py Fri Jan 31 10:47:51 2014 -0800
@@ -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()