comparison mercurial/fileset.py @ 38882:ff42ec7845e4

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)
author Yuya Nishihara <yuya@tcha.org>
date Sun, 22 Jul 2018 19:48:50 +0900
parents dec16c0cce50
children 41e04212261a
comparison
equal deleted inserted replaced
38881:dec16c0cce50 38882:ff42ec7845e4
60 for x in xs] 60 for x in xs]
61 return mctx.matcher(patterns) 61 return mctx.matcher(patterns)
62 62
63 def andmatch(mctx, x, y): 63 def andmatch(mctx, x, y):
64 xm = getmatch(mctx, x) 64 xm = getmatch(mctx, x)
65 ym = getmatch(mctx, y) 65 ym = getmatch(mctx.narrowed(xm), y)
66 return matchmod.intersectmatchers(xm, ym) 66 return matchmod.intersectmatchers(xm, ym)
67 67
68 def ormatch(mctx, *xs): 68 def ormatch(mctx, *xs):
69 ms = [getmatch(mctx, x) for x in xs] 69 ms = [getmatch(mctx, x) for x in xs]
70 return matchmod.unionmatcher(ms) 70 return matchmod.unionmatcher(ms)
73 m = getmatch(mctx, x) 73 m = getmatch(mctx, x)
74 return mctx.predicate(lambda f: not m(f), predrepr=('<not %r>', m)) 74 return mctx.predicate(lambda f: not m(f), predrepr=('<not %r>', m))
75 75
76 def minusmatch(mctx, x, y): 76 def minusmatch(mctx, x, y):
77 xm = getmatch(mctx, x) 77 xm = getmatch(mctx, x)
78 ym = getmatch(mctx, y) 78 ym = getmatch(mctx.narrowed(xm), y)
79 return matchmod.differencematcher(xm, ym) 79 return matchmod.differencematcher(xm, ym)
80 80
81 def listmatch(mctx, *xs): 81 def listmatch(mctx, *xs):
82 raise error.ParseError(_("can't use a list in this context"), 82 raise error.ParseError(_("can't use a list in this context"),
83 hint=_('see \'hg help "filesets.x or y"\'')) 83 hint=_('see \'hg help "filesets.x or y"\''))
458 class matchctx(object): 458 class matchctx(object):
459 def __init__(self, basectx, ctx, badfn=None): 459 def __init__(self, basectx, ctx, badfn=None):
460 self._basectx = basectx 460 self._basectx = basectx
461 self.ctx = ctx 461 self.ctx = ctx
462 self._badfn = badfn 462 self._badfn = badfn
463 self._match = None
463 self._status = None 464 self._status = None
464 465
466 def narrowed(self, match):
467 """Create matchctx for a sub-tree narrowed by the given matcher"""
468 mctx = matchctx(self._basectx, self.ctx, self._badfn)
469 mctx._match = match
470 # leave wider status which we don't have to care
471 mctx._status = self._status
472 return mctx
473
465 def switch(self, basectx, ctx): 474 def switch(self, basectx, ctx):
466 return matchctx(basectx, ctx, self._badfn) 475 mctx = matchctx(basectx, ctx, self._badfn)
476 mctx._match = self._match
477 return mctx
467 478
468 def withstatus(self, keys): 479 def withstatus(self, keys):
469 """Create matchctx which has precomputed status specified by the keys""" 480 """Create matchctx which has precomputed status specified by the keys"""
470 mctx = matchctx(self._basectx, self.ctx, self._badfn) 481 mctx = matchctx(self._basectx, self.ctx, self._badfn)
482 mctx._match = self._match
471 mctx._buildstatus(keys) 483 mctx._buildstatus(keys)
472 return mctx 484 return mctx
473 485
474 def _buildstatus(self, keys): 486 def _buildstatus(self, keys):
475 self._status = self._basectx.status(self.ctx, 487 self._status = self._basectx.status(self.ctx, self._match,
476 listignored='ignored' in keys, 488 listignored='ignored' in keys,
477 listclean=True, 489 listclean=True,
478 listunknown='unknown' in keys) 490 listunknown='unknown' in keys)
479 491
480 def status(self): 492 def status(self):