[PATCH 3 of 3] util: get rid of statmtimesec

Bryan O'Sullivan bos at serpentine.com
Wed Nov 18 10:18:56 CST 2015


# HG changeset patch
# User Bryan O'Sullivan <bos at serpentine.com>
# Date 1447863394 18000
#      Wed Nov 18 11:16:34 2015 -0500
# Node ID 220904f144652a738557a9a8c470ce9cbd8e62f2
# Parent  d2569b9eab3d2cfa6cad3cafcec60a66634412af
util: get rid of statmtimesec

We can now use the sequence protocol implemented by osutil.listdir instead.

On a large repo, this improves the performance of diff by almost 15%:

time hg-before diff --stat -r .^
7.18

time hg-after diff --stat -r .^
6.16

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1694,7 +1694,7 @@ class workingfilectx(committablefilectx)
     def date(self):
         t, tz = self._changectx.date()
         try:
-            return (util.statmtimesec(self._repo.wvfs.lstat(self._path)), tz)
+            return (self._repo.wvfs.lstat(self._path)[stat.ST_MTIME], tz)
         except OSError as err:
             if err.errno != errno.ENOENT:
                 raise
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -31,7 +31,7 @@ def _getfsnow(vfs):
     '''Get "now" timestamp on filesystem'''
     tmpfd, tmpname = vfs.mkstemp()
     try:
-        return util.statmtimesec(os.fstat(tmpfd))
+        return os.fstat(tmpfd)[stat.ST_MTIME]
     finally:
         os.close(tmpfd)
         vfs.unlink(tmpname)
@@ -466,7 +466,7 @@ class dirstate(object):
     def normal(self, f):
         '''Mark a file normal and clean.'''
         s = os.lstat(self._join(f))
-        mtime = util.statmtimesec(s)
+        mtime = s[stat.ST_MTIME]
         self._addpath(f, 'n', s.st_mode,
                       s.st_size & _rangemask, mtime & _rangemask)
         if f in self._copymap:
@@ -699,7 +699,7 @@ class dirstate(object):
     def _writedirstate(self, st):
         # use the modification time of the newly created temporary file as the
         # filesystem's notion of 'now'
-        now = util.statmtimesec(util.fstat(st)) & _rangemask
+        now = util.fstat(st)[stat.ST_MTIME] & _rangemask
         st.write(parsers.pack_dirstate(self._map, self._copymap, self._pl, now))
         st.close()
         self._lastnormaltime = 0
@@ -1041,6 +1041,7 @@ class dirstate(object):
         checkexec = self._checkexec
         copymap = self._copymap
         lastnormaltime = self._lastnormaltime
+        ST_MTIME = stat.ST_MTIME
 
         # We need to do full walks when either
         # - we're listing all clean files, or
@@ -1073,7 +1074,7 @@ class dirstate(object):
             if not st and state in "nma":
                 dadd(fn)
             elif state == 'n':
-                mtime = util.statmtimesec(st)
+                mtime = st[ST_MTIME]
                 if (size >= 0 and
                     ((size != st.st_size and size != st.st_size & _rangemask)
                      or ((mode ^ st.st_mode) & 0o100 and checkexec))
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -921,20 +921,6 @@ def fstat(fp):
     except AttributeError:
         return os.stat(fp.name)
 
-def statmtimesec(st):
-    """Get mtime as integer of seconds
-
-    'int(st.st_mtime)' cannot be used because st.st_mtime is computed as
-    'sec + 1e-9 * nsec' and double-precision floating-point type is too narrow
-    to represent nanoseconds. If 'nsec' is close to 1 sec, 'int(st.st_mtime)'
-    can be 'sec + 1'. (issue4836)
-    """
-    try:
-        return st[stat.ST_MTIME]
-    except (TypeError, IndexError):
-        # osutil.stat doesn't allow index access and its st_mtime is int
-        return st.st_mtime
-
 # File system features
 
 def checkcase(path):


More information about the Mercurial-devel mailing list