##// END OF EJS Templates
dirstate: ignore sub-second component when either is zero in mtime...
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

File last commit:

r49081:68bb472a default
r49081:68bb472a default
Show More
timestamp.py
77 lines | 2.2 KiB | text/x-python | PythonLexer
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 # 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
Simon Sapin
dirstate: ignore sub-second component when either is zero in mtime...
r49081 import functools
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 import stat
rangemask = 0x7FFFFFFF
Simon Sapin
dirstate: ignore sub-second component when either is zero in mtime...
r49081 @functools.total_ordering
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 class timestamp(tuple):
"""
Simon Sapin
dirstate: ignore sub-second component when either is zero in mtime...
r49081 A Unix timestamp with optional nanoseconds precision,
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 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`.
Simon Sapin
dirstate: ignore sub-second component when either is zero in mtime...
r49081 When this is zero, the sub-second precision is considered unknown.
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 """
def __new__(cls, value):
truncated_seconds, subsec_nanos = value
value = (truncated_seconds & rangemask, subsec_nanos)
return super(timestamp, cls).__new__(cls, value)
Simon Sapin
dirstate: ignore sub-second component when either is zero in mtime...
r49081 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
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079
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))