[PATCH] largefiles: optimize status when files are specified on the command line (issue3144)

Na'Tosha Bard natosha at unity3d.com
Fri Dec 9 15:02:09 UTC 2011


# HG changeset patch
# User Na'Tosha Bard <natosha at unity3d.com>
# Date 1323442785 -3600
# Node ID 46fb85de1dc5e2a9075ec237f0cccb1d136ef760
# Parent  fc8c7a5ccc4a928e7559013ecdf50462c271418c
largefiles: optimize status when files are specified on the command line (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.

diff -r fc8c7a5ccc4a -r 46fb85de1dc5 hgext/largefiles/reposetup.py
--- a/hgext/largefiles/reposetup.py	Thu Dec 08 16:01:44 2011 -0600
+++ b/hgext/largefiles/reposetup.py	Fri Dec 09 15:59:45 2011 +0100
@@ -120,6 +120,23 @@
                 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:
+                    matchedfiles = [f for f in match._files if f in lfdirstate]
+                    if not matchedfiles:
+                        try:
+                            return super(lfiles_repo, self).status(node1, node2,
+                                         match, listignored, listclean,
+                                         listunknown, listsubrepos)
+                        except TypeError:
+                            return super(lfiles_repo, self).status(node1, node2,
+                                         match, listignored, listclean,
+                                         listunknown)
+
                 # Create a copy of match that matches standins instead
                 # of largefiles.
                 def tostandin(file):
@@ -155,7 +172,8 @@
                         # 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)
+                        if not lfdirstate:
+                            lfdirstate = lfutil.openlfdirstate(ui, self)
                         # Override lfdirstate's ignore matcher to not do
                         # anything
                         orig_ignore = lfdirstate._ignore



More information about the Mercurial-devel mailing list