Mercurial > hg
diff mercurial/pure/parsers.py @ 48260:269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Keep integer seconds since the Unix epoch,
together with integer nanoseconds in the `0 <= n < 1e9` range.
For now, nanoseconds are still always zero.
This commit is about data structure changes.
Differential Revision: https://phab.mercurial-scm.org/D11684
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 18 Oct 2021 11:23:07 +0200 |
parents | b874e8d81a98 |
children | 9205d9be8b41 |
line wrap: on
line diff
--- a/mercurial/pure/parsers.py Tue Oct 19 21:03:13 2021 +0200 +++ b/mercurial/pure/parsers.py Mon Oct 18 11:23:07 2021 +0200 @@ -99,7 +99,8 @@ _p2_info = attr.ib() _mode = attr.ib() _size = attr.ib() - _mtime = attr.ib() + _mtime_s = attr.ib() + _mtime_ns = attr.ib() _fallback_exec = attr.ib() _fallback_symlink = attr.ib() @@ -123,7 +124,8 @@ self._mode = None self._size = None - self._mtime = None + self._mtime_s = None + self._mtime_ns = None if parentfiledata is None: has_meaningful_mtime = False has_meaningful_data = False @@ -131,10 +133,10 @@ self._mode = parentfiledata[0] self._size = parentfiledata[1] if has_meaningful_mtime: - self._mtime = parentfiledata[2] + self._mtime_s, self._mtime_ns = parentfiledata[2] @classmethod - def from_v2_data(cls, flags, size, mtime): + def from_v2_data(cls, flags, size, mtime_s, mtime_ns): """Build a new DirstateItem object from V2 data""" has_mode_size = bool(flags & DIRSTATE_V2_HAS_MODE_AND_SIZE) has_meaningful_mtime = bool(flags & DIRSTATE_V2_HAS_FILE_MTIME) @@ -170,7 +172,7 @@ p2_info=bool(flags & DIRSTATE_V2_P2_INFO), has_meaningful_data=has_mode_size, has_meaningful_mtime=has_meaningful_mtime, - parentfiledata=(mode, size, mtime), + parentfiledata=(mode, size, (mtime_s, mtime_ns)), fallback_exec=fallback_exec, fallback_symlink=fallback_symlink, ) @@ -207,13 +209,13 @@ wc_tracked=True, p1_tracked=True, has_meaningful_mtime=False, - parentfiledata=(mode, size, 42), + parentfiledata=(mode, size, (42, 0)), ) else: return cls( wc_tracked=True, p1_tracked=True, - parentfiledata=(mode, size, mtime), + parentfiledata=(mode, size, (mtime, 0)), ) else: raise RuntimeError(b'unknown state: %s' % state) @@ -224,7 +226,8 @@ This means the next status call will have to actually check its content to make sure it is correct. """ - self._mtime = None + self._mtime_s = None + self._mtime_ns = None def set_clean(self, mode, size, mtime): """mark a file as "clean" cancelling potential "possibly dirty call" @@ -238,7 +241,7 @@ self._p1_tracked = True self._mode = mode self._size = size - self._mtime = mtime + self._mtime_s, self._mtime_ns = mtime def set_tracked(self): """mark a file as tracked in the working copy @@ -250,7 +253,8 @@ # the files as needing lookup # # Consider dropping this in the future in favor of something less broad. - self._mtime = None + self._mtime_s = None + self._mtime_ns = None def set_untracked(self): """mark a file as untracked in the working copy @@ -260,7 +264,8 @@ self._wc_tracked = False self._mode = None self._size = None - self._mtime = None + self._mtime_s = None + self._mtime_ns = None def drop_merge_data(self): """remove all "merge-only" from a DirstateItem @@ -271,7 +276,8 @@ self._p2_info = False self._mode = None self._size = None - self._mtime = None + self._mtime_s = None + self._mtime_ns = None @property def mode(self): @@ -285,6 +291,14 @@ def mtime(self): return self.v1_mtime() + def mtime_likely_equal_to(self, other_mtime): + self_sec = self._mtime_s + if self_sec is None: + return False + self_ns = self._mtime_ns + other_sec, other_ns = other_mtime + return self_sec == other_sec and self_ns == other_ns + @property def state(self): """ @@ -440,7 +454,7 @@ flags |= DIRSTATE_V2_MODE_EXEC_PERM if stat.S_ISLNK(self.mode): flags |= DIRSTATE_V2_MODE_IS_SYMLINK - if self._mtime is not None: + if self._mtime_s is not None: flags |= DIRSTATE_V2_HAS_FILE_MTIME if self._fallback_exec is not None: @@ -456,7 +470,7 @@ # Note: we do not need to do anything regarding # DIRSTATE_V2_ALL_UNKNOWN_RECORDED and DIRSTATE_V2_ALL_IGNORED_RECORDED # since we never set _DIRSTATE_V2_HAS_DIRCTORY_MTIME - return (flags, self._size or 0, self._mtime or 0) + return (flags, self._size or 0, self._mtime_s or 0, self._mtime_ns or 0) def v1_state(self): """return a "state" suitable for v1 serialization""" @@ -504,18 +518,18 @@ raise RuntimeError('untracked item') elif self.removed: return 0 - elif self._mtime is None: + elif self._mtime_s is None: return AMBIGUOUS_TIME elif self._p2_info: return AMBIGUOUS_TIME elif not self._p1_tracked: return AMBIGUOUS_TIME else: - return self._mtime + return self._mtime_s def need_delay(self, now): """True if the stored mtime would be ambiguous with the current time""" - return self.v1_state() == b'n' and self.v1_mtime() == now + return self.v1_state() == b'n' and self._mtime_s == now[0] def gettype(q): @@ -883,7 +897,6 @@ def pack_dirstate(dmap, copymap, pl, now): - now = int(now) cs = stringio() write = cs.write write(b"".join(pl))