[PATCH 3 of 3] use per-directory clustered stat calls even in cases where known tree is walked

Petr Kodl petrkodl at gmail.com
Tue Sep 30 16:32:22 CDT 2008


# HG changeset patch
# User Petr Kodl <petrkodl at gmail.com>
# Date 1222809788 14400
# Node ID 88d9e471e94e2914234f49c0d4e0cc49795aabe1
# Parent  89c54a451554b0f9475fe08acbf167dbd065212d
use per-directory clustered stat calls even in cases where known tree is walked

This allows diff and other calls walking known tree to benefit from osutil.c.

Some timings from clean tree with ~23k files

no patch

hg st    .7s
hg diff  3s

with patch

hg diff  .7s

diff -r 89c54a451554 -r 88d9e471e94e mercurial/dirstate.py
--- a/mercurial/dirstate.py	Tue Sep 30 17:23:08 2008 -0400
+++ b/mercurial/dirstate.py	Tue Sep 30 17:23:08 2008 -0400
@@ -507,6 +507,15 @@
                         if (nf in dmap or not ignore(nf)) and matchfn(nf):
                             results[nf] = None
 
+        # if stat on whole directory is fast compared to stat on files
+        # avoid per-file lstat call in favor of per-directory call
+        # proceed normally if specific files are listed
+        recursive = 1
+        if util.fastdirstat() and not len(match.files()) and not len(work):
+            work.append('.')
+            work.extend(self._dirs.keys())
+            recursive = 0
+
         # step 2: visit subdirectories
         while work:
             nd = work.pop()
@@ -521,7 +530,7 @@
                 nf = normalize(nd and (nd + "/" + f) or f, True)
                 if nf not in results:
                     if kind == dirkind:
-                        if not ignore(nf):
+                        if recursive and not ignore(nf):
                             wadd(nf)
                         if nf in dmap and matchfn(nf):
                             results[nf] = None
diff -r 89c54a451554 -r 88d9e471e94e mercurial/util.py
--- a/mercurial/util.py	Tue Sep 30 17:23:08 2008 -0400
+++ b/mercurial/util.py	Tue Sep 30 17:23:08 2008 -0400
@@ -798,6 +798,12 @@
 def openhardlinks():
     '''return true if it is safe to hold open file handles to hardlinks'''
     return True
+
+def fastdirstat():
+    '''Return true if os.listdir(.,True) is very fast compared to lstat
+    per file.  This is true on Win32 with native osutil.c where stat information
+    is constructed directly during directory reading without any lstat calls.'''
+    return sys.platform=='win32'
 
 getuser_fallback = None
 


More information about the Mercurial-devel mailing list