largefiles: optimize status when files are specified (
issue3144)
This fixes a performance issue with 'hg status' when files are specified
on the command-line. Previously, a large amount of largefiles code was
executed, even if files were specified on the command-line and those files
were not largefiles. This patch fixes the problem by first checking if
non-largefiles were specified on the command-line and, just letting the
normal status function handle the case if they were.
On a brand new machine, the execution time for 'hg status filename' on
a repository with largefiles was:
real 0m0.636s
user 0m0.512s
sys 0m0.120s
versus the following (the same repository, with largefiles disabled):
real 0m0.215s
user 0m0.180s
sys 0m0.032s
After this patch, the performance of 'hg status filename' on the same
repository, with largefiles enabled is:
real 0m0.228s
user 0m0.189s
sys 0m0.036s
This performance boost is also true when patterns (rather than specific
files) are specified on the command-line.
In the case where patterns are specified in addition to a file list, we
just defer to the normal codepath in order to not spend extra time
expanding the patterns to just risk having to expand them again later.
--- a/hgext/largefiles/reposetup.py Mon Dec 12 15:16:58 2011 +0100
+++ b/hgext/largefiles/reposetup.py Thu Dec 15 16:23:26 2011 +0100
@@ -113,6 +113,18 @@
if match is None:
match = match_.always(self.root, self.getcwd())
+ # First check if there were files specified on the
+ # command line. If there were, and none of them were
+ # largefiles, we should just bail here and let super
+ # handle it -- thus gaining a big performance boost.
+ lfdirstate = lfutil.openlfdirstate(ui, self)
+ if match.files() and not match.anypats():
+ matchedfiles = [f for f in match.files() if f in lfdirstate]
+ if not matchedfiles:
+ return super(lfiles_repo, self).status(node1, node2,
+ match, listignored, listclean,
+ listunknown, listsubrepos)
+
# Create a copy of match that matches standins instead
# of largefiles.
def tostandin(file):
@@ -144,7 +156,6 @@
# taken out or lfdirstate.status will report an error.
# The status of these files was already computed using
# super's status.
- lfdirstate = lfutil.openlfdirstate(ui, self)
# Override lfdirstate's ignore matcher to not do
# anything
orig_ignore = lfdirstate._ignore