changeset 15653:93c77d5b9752

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.
author Na'Tosha Bard <natosha@unity3d.com>
date Thu, 15 Dec 2011 16:23:26 +0100
parents ca6accdad79c
children 2a7fa7c641d8
files hgext/largefiles/reposetup.py
diffstat 1 files changed, 12 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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