Mercurial > hg
view mercurial/dirstateutils/timestamp.py @ 48262:68bb472aee9c
dirstate: ignore sub-second component when either is zero in mtime
When comparing mtimes for equality.
Some APIs simply return zero when more precision is not available.
When comparing values from different sources, if only one is truncated in
that way, doing a simple comparison would cause many false negatives.
Differential Revision: https://phab.mercurial-scm.org/D11701
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 14 Oct 2021 13:54:39 +0200 |
parents | 269ff8978086 |
children | 83d0bd45b662 |
line wrap: on
line source
# Copyright Mercurial Contributors # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import import functools import stat rangemask = 0x7FFFFFFF @functools.total_ordering class timestamp(tuple): """ A Unix timestamp with optional nanoseconds precision, modulo 2**31 seconds. A 2-tuple containing: `truncated_seconds`: seconds since the Unix epoch, truncated to its lower 31 bits `subsecond_nanoseconds`: number of nanoseconds since `truncated_seconds`. When this is zero, the sub-second precision is considered unknown. """ def __new__(cls, value): truncated_seconds, subsec_nanos = value value = (truncated_seconds & rangemask, subsec_nanos) return super(timestamp, cls).__new__(cls, value) def __eq__(self, other): self_secs, self_subsec_nanos = self other_secs, other_subsec_nanos = other return self_secs == other_secs and ( self_subsec_nanos == other_subsec_nanos or self_subsec_nanos == 0 or other_subsec_nanos == 0 ) def __gt__(self, other): self_secs, self_subsec_nanos = self other_secs, other_subsec_nanos = other if self_secs > other_secs: return True if self_secs < other_secs: return False if self_subsec_nanos == 0 or other_subsec_nanos == 0: # they are considered equal, so not "greater than" return False return self_subsec_nanos > other_subsec_nanos def zero(): """ Returns the `timestamp` at the Unix epoch. """ return tuple.__new__(timestamp, (0, 0)) def mtime_of(stat_result): """ Takes an `os.stat_result`-like object and returns a `timestamp` object for its modification time. """ # https://docs.python.org/2/library/os.html#os.stat_float_times # "For compatibility with older Python versions, # accessing stat_result as a tuple always returns integers." secs = stat_result[stat.ST_MTIME] # For now subsec_nanos = 0 return timestamp((secs, subsec_nanos))