dirstate: add a method to efficiently filter by match
Current callers that require just this data call workingctx.walk, which calls
dirstate.walk, which stats all the files. Even worse, workingctx.walk looks for
unknown files, significantly slowing things down, even though callers might not
be interested in them at all.
--- a/mercurial/dirstate.py Sat Aug 02 09:45:21 2014 +0100
+++ b/mercurial/dirstate.py Fri Aug 01 22:05:16 2014 -0700
@@ -873,3 +873,21 @@
return (lookup, modified, added, removed, deleted, unknown, ignored,
clean)
+
+ def matches(self, match):
+ '''
+ return files in the dirstate (in whatever state) filtered by match
+ '''
+ dmap = self._map
+ if match.always():
+ return dmap.keys()
+ files = match.files()
+ if match.matchfn == match.exact:
+ # fast path -- filter the other way around, since typically files is
+ # much smaller than dmap
+ return [f for f in files if f in dmap]
+ if not match.anypats() and util.all(fn in dmap for fn in files):
+ # fast path -- all the values are known to be files, so just return
+ # that
+ return list(files)
+ return [f for f in dmap if match(f)]