largefiles: optimize status when files are specified (issue3144)
authorNa'Tosha Bard <natosha@unity3d.com>
Thu, 15 Dec 2011 16:23:26 +0100
changeset 15653 93c77d5b9752
parent 15652 ca6accdad79c
child 15654 2a7fa7c641d8
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.
hgext/largefiles/reposetup.py
--- 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