fileset: narrow status computation by left-hand-side of 'and' node
Timing with warm disk cache:
$ hg status --cwd mozilla-central 'set:path:build/ and unknown()' --time
(orig) time: real 1.970 secs (user 1.560+0.000 sys 0.410+0.000)
(new) time: real 0.330 secs (user 0.310+0.000 sys 0.020+0.000)
--- a/mercurial/fileset.py Sun Jul 22 19:43:57 2018 +0900
+++ b/mercurial/fileset.py Sun Jul 22 19:48:50 2018 +0900
@@ -62,7 +62,7 @@
def andmatch(mctx, x, y):
xm = getmatch(mctx, x)
- ym = getmatch(mctx, y)
+ ym = getmatch(mctx.narrowed(xm), y)
return matchmod.intersectmatchers(xm, ym)
def ormatch(mctx, *xs):
@@ -75,7 +75,7 @@
def minusmatch(mctx, x, y):
xm = getmatch(mctx, x)
- ym = getmatch(mctx, y)
+ ym = getmatch(mctx.narrowed(xm), y)
return matchmod.differencematcher(xm, ym)
def listmatch(mctx, *xs):
@@ -460,19 +460,31 @@
self._basectx = basectx
self.ctx = ctx
self._badfn = badfn
+ self._match = None
self._status = None
+ def narrowed(self, match):
+ """Create matchctx for a sub-tree narrowed by the given matcher"""
+ mctx = matchctx(self._basectx, self.ctx, self._badfn)
+ mctx._match = match
+ # leave wider status which we don't have to care
+ mctx._status = self._status
+ return mctx
+
def switch(self, basectx, ctx):
- return matchctx(basectx, ctx, self._badfn)
+ mctx = matchctx(basectx, ctx, self._badfn)
+ mctx._match = self._match
+ return mctx
def withstatus(self, keys):
"""Create matchctx which has precomputed status specified by the keys"""
mctx = matchctx(self._basectx, self.ctx, self._badfn)
+ mctx._match = self._match
mctx._buildstatus(keys)
return mctx
def _buildstatus(self, keys):
- self._status = self._basectx.status(self.ctx,
+ self._status = self._basectx.status(self.ctx, self._match,
listignored='ignored' in keys,
listclean=True,
listunknown='unknown' in keys)