Patchwork [STABLE] status: make 'hg status --rev' faster when there are deleted files

login
register
mail settings
Submitter Martin von Zweigbergk
Date Oct. 24, 2014, 11:08 p.m.
Message ID <221543f4a2362dc6d249.1414192098@handduk2.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/6464/
State Accepted
Headers show

Comments

Martin von Zweigbergk - Oct. 24, 2014, 11:08 p.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1414185868 25200
#      Fri Oct 24 14:24:28 2014 -0700
# Branch stable
# Node ID 221543f4a2362dc6d2499ffb65da53bce3193d3e
# Parent  eb763217152ab2b472416bcc57722451c317f282
status: make 'hg status --rev' faster when there are deleted files

In order not to avoid listing files as both added and deleted, for
example, we check for every file in the manifest if it is in the
_list_ of deleted files. This can get quite slow when there are many
deleted files. Change it to a set to make the containment check
faster. On a somewhat contrived example of the Mozilla repo with the
entire testing/ directory deleted (~14k files), this makes
'hg status --rev .^' go from 26s to 2s.
Pierre-Yves David - Oct. 26, 2014, 11:18 a.m.
On 10/25/2014 01:08 AM, Martin von Zweigbergk wrote:
> # HG changeset patch
> # User Martin von Zweigbergk <martinvonz@google.com>
> # Date 1414185868 25200
> #      Fri Oct 24 14:24:28 2014 -0700
> # Branch stable
> # Node ID 221543f4a2362dc6d2499ffb65da53bce3193d3e
> # Parent  eb763217152ab2b472416bcc57722451c317f282
> status: make 'hg status --rev' faster when there are deleted files

the speedup seems worthy for stable (Stopping clownly list membership 
testing are usually worth it).

Pushed to the clowncopter thanks.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -121,10 +121,11 @@ 
 
         modified, added, clean = [], [], []
         deleted, unknown, ignored = s[3], s[4], s[5]
+        deletedset = set(deleted)
         withflags = mf1.withflags() | mf2.withflags()
         for fn, mf2node in mf2.iteritems():
             if fn in mf1:
-                if (fn not in deleted and
+                if (fn not in deletedset and
                     ((fn in withflags and mf1.flags(fn) != mf2.flags(fn)) or
                      (mf1[fn] != mf2node and
                       (mf2node or self[fn].cmp(other[fn]))))):
@@ -132,7 +133,7 @@ 
                 elif listclean:
                     clean.append(fn)
                 del mf1[fn]
-            elif fn not in deleted:
+            elif fn not in deletedset:
                 added.append(fn)
         removed = mf1.keys()
         if removed: