<div dir="ltr">I am not sure that this patch breaks nothing.  Please let me know if it actually improves performance or breaks something on your environments.  Thanks in advance.<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Tue, Feb 4, 2014 at 3:55 PM, Kaz Nishimura <span dir="ltr"><<a href="mailto:kazssym@vx68k.org" target="_blank">kazssym@vx68k.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
# HG changeset patch<br>
# User Kaz Nishimura <<a href="mailto:kazssym@vx68k.org">kazssym@vx68k.org</a>><br>
# Date 1381984037 -32400<br>
#      Thu Oct 17 13:27:17 2013 +0900<br>
# Branch stable<br>
# Node ID be24685ef8ae89aa89964fc0b147260325b309d9<br>
# Parent  7d269e7620c48eee93871d33e673b7a8acb503cc<br>
win32: improve the performance of win32.unlink() over CIFS<br>
<br>
Emulating POSIX unlink() behavior with os.rename() and os.unlink() is often slow<br>
especially over CIFS from Windows clients due to its protocol overhead. This<br>
patch changes win32.unlink() to try first an exclusive open with the Win32<br>
delete-on-close flag, and if a sharing violation is detected, to fall back to<br>
the original emulation.<br>
<br>
This patch also removes a test with os.path.isdir() since we expect opening a<br>
directory shall fail as os.unlink() would.<br>
<br>
Example measurements (repeated 3-times after 1-time calibration):<br>
<br>
(Without this patch: hg update from null to default)<br>
127 files updated, 0 files merged, 0 files removed, 0 files unresolved<br>
time: real 19.871 secs (user 0.328+0.000 sys 1.794+0.000)<br>
time: real 19.622 secs (user 0.312+0.000 sys 2.044+0.000)<br>
time: real 19.138 secs (user 0.250+0.000 sys 1.872+0.000)<br>
<br>
(Without this patch: hg update from default to null)<br>
0 files updated, 0 files merged, 127 files removed, 0 files unresolved<br>
time: real 35.158 secs (user 0.156+0.000 sys 2.512+0.000)<br>
time: real 35.272 secs (user 0.250+0.000 sys 2.512+0.000)<br>
time: real 36.569 secs (user 0.203+0.000 sys 2.387+0.000)<br>
<br>
(With this patch: hg update from null to default)<br>
127 files updated, 0 files merged, 0 files removed, 0 files unresolved<br>
time: real 17.893 secs (user 0.328+0.000 sys 1.700+0.000)<br>
time: real 18.512 secs (user 0.265+0.000 sys 1.529+0.000)<br>
time: real 20.238 secs (user 0.312+0.000 sys 1.685+0.000)<br>
<br>
(With this patch: hg update from default to null)<br>
0 files updated, 0 files merged, 127 files removed, 0 files unresolved<br>
time: real 12.312 secs (user 0.250+0.000 sys 0.811+0.000)<br>
time: real 12.471 secs (user 0.156+0.000 sys 0.889+0.000)<br>
time: real 9.727 secs (user 0.125+0.000 sys 0.858+0.000)<br>
<br>
diff -r 7d269e7620c4 -r be24685ef8ae mercurial/win32.py<br>
--- a/mercurial/win32.py<br>
+++ b/mercurial/win32.py<br>
@@ -25,4 +25,5 @@<br>
 # GetLastError<br>
 _ERROR_SUCCESS = 0<br>
+_ERROR_SHARING_VIOLATION = 32<br>
 _ERROR_INVALID_PARAMETER = 87<br>
 _ERROR_INSUFFICIENT_BUFFER = 122<br>
@@ -60,5 +61,7 @@<br>
 _OPEN_EXISTING = 3<br>
<br>
+_FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000<br>
 _FILE_FLAG_BACKUP_SEMANTICS = 0x02000000<br>
+_FILE_FLAG_DELETE_ON_CLOSE = 0x04000000<br>
<br>
 # SetFileAttributes<br>
@@ -345,9 +348,16 @@<br>
     '''try to implement POSIX' unlink semantics on Windows'''<br>
<br>
-    if os.path.isdir(f):<br>
-        # use EPERM because it is POSIX prescribed value, even though<br>
-        # unlink(2) on directories returns EISDIR on Linux<br>
-        raise IOError(errno.EPERM,<br>
-                      "Unlinking directory not permitted: '%s'" % f)<br>
+    # If we can open f exclusively, no other processes must have open handles<br>
+    # for it and we can expect its name will be deleted immediately when we<br>
+    # close the handle unless we have another in the same process.  We also<br>
+    # expect we shall simply fail to open f if it is a directory.<br>
+    fh = _kernel32.CreateFileA(f, 0, 0, None, _OPEN_EXISTING,<br>
+        _FILE_FLAG_OPEN_REPARSE_POINT | _FILE_FLAG_DELETE_ON_CLOSE, None)<br>
+    if fh != _INVALID_HANDLE_VALUE:<br>
+        _kernel32.CloseHandle(fh)<br>
+        return<br>
+    error = _kernel32.GetLastError()<br>
+    if error != _ERROR_SHARING_VIOLATION:<br>
+        raise ctypes.WinError(error)<br>
<br>
     # POSIX allows to unlink and rename open files. Windows has serious<br>
</blockquote></div><br></div>