Fix cold cache diff performance
authorChris Mason <mason@suse.com>
Wed, 21 Jun 2006 09:28:48 -0700
changeset 2474 1e32e2fe8a67
parent 2473 30c267cb4c2f
child 2475 7a77934ece46
Fix cold cache diff performance cold cache diff performance has regressed in two ways. localrepo.changes has optimizations for diffing against the working dir parent that expect node1 to be None. commands.revpair() usage means that commands.dodiff() never sends node1 == None. This is fixed in localrepo.changes by checking against the dirstate parents. In the non-dirstate parents case, localrepo.changes does a loop comparing files without first sorting the file names, leading to random access across the disk.
mercurial/localrepo.py
--- a/mercurial/localrepo.py	Wed Jun 21 09:15:42 2006 -0700
+++ b/mercurial/localrepo.py	Wed Jun 21 09:28:48 2006 -0700
@@ -618,7 +618,11 @@
                     del mf[fn]
             return mf
 
-        if node1:
+        compareworking = False
+        if not node1 or node1 == self.dirstate.parents()[0]:
+            compareworking = True
+
+        if not compareworking:
             # read the manifest from node1 before the manifest from node2,
             # so that we'll hit the manifest cache if we're going through
             # all the revisions in parent->child order.
@@ -635,7 +639,7 @@
                 self.dirstate.changes(files, match, show_ignored))
 
             # are we comparing working dir against its parent?
-            if not node1:
+            if compareworking:
                 if lookup:
                     # do a full compare of any files that might have changed
                     mf2 = mfmatches(self.dirstate.parents()[0])
@@ -658,11 +662,15 @@
             deleted, unknown, ignored = [], [], []
             mf2 = mfmatches(node2)
 
-        if node1:
+        if not compareworking:
             # flush lists from dirstate before comparing manifests
             modified, added = [], []
 
-            for fn in mf2:
+            # make sure to sort the files so we talk to the disk in a
+            # reasonable order
+            mf2keys = mf2.keys()
+            mf2keys.sort()
+            for fn in mf2keys:
                 if mf1.has_key(fn):
                     if mf1[fn] != mf2[fn] and (mf2[fn] != "" or fcmp(fn, mf1)):
                         modified.append(fn)