mercurial/dirstateutils/timestamp.py
author Simon Sapin <simon.sapin@octobus.net>
Thu, 14 Oct 2021 13:54:39 +0200
changeset 48262 68bb472aee9c
parent 48260 269ff8978086
child 48263 83d0bd45b662
permissions -rw-r--r--
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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48260
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     1
# Copyright Mercurial Contributors
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     2
#
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     3
# This software may be used and distributed according to the terms of the
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     4
# GNU General Public License version 2 or any later version.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     5
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     6
from __future__ import absolute_import
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     7
48262
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
     8
import functools
48260
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     9
import stat
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    10
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    11
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    12
rangemask = 0x7FFFFFFF
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    13
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    14
48262
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    15
@functools.total_ordering
48260
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    16
class timestamp(tuple):
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    17
    """
48262
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    18
    A Unix timestamp with optional nanoseconds precision,
48260
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    19
    modulo 2**31 seconds.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    20
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    21
    A 2-tuple containing:
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    22
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    23
    `truncated_seconds`: seconds since the Unix epoch,
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    24
    truncated to its lower 31 bits
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    25
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    26
    `subsecond_nanoseconds`: number of nanoseconds since `truncated_seconds`.
48262
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    27
    When this is zero, the sub-second precision is considered unknown.
48260
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    28
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    29
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    30
    def __new__(cls, value):
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    31
        truncated_seconds, subsec_nanos = value
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    32
        value = (truncated_seconds & rangemask, subsec_nanos)
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    33
        return super(timestamp, cls).__new__(cls, value)
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    34
48262
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    35
    def __eq__(self, other):
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    36
        self_secs, self_subsec_nanos = self
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    37
        other_secs, other_subsec_nanos = other
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    38
        return self_secs == other_secs and (
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    39
            self_subsec_nanos == other_subsec_nanos
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    40
            or self_subsec_nanos == 0
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    41
            or other_subsec_nanos == 0
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    42
        )
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    43
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    44
    def __gt__(self, other):
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    45
        self_secs, self_subsec_nanos = self
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    46
        other_secs, other_subsec_nanos = other
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    47
        if self_secs > other_secs:
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    48
            return True
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    49
        if self_secs < other_secs:
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    50
            return False
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    51
        if self_subsec_nanos == 0 or other_subsec_nanos == 0:
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    52
            # they are considered equal, so not "greater than"
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    53
            return False
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    54
        return self_subsec_nanos > other_subsec_nanos
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48260
diff changeset
    55
48260
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    56
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    57
def zero():
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    58
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    59
    Returns the `timestamp` at the Unix epoch.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    60
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    61
    return tuple.__new__(timestamp, (0, 0))
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    62
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    63
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    64
def mtime_of(stat_result):
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    65
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    66
    Takes an `os.stat_result`-like object and returns a `timestamp` object
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    67
    for its modification time.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    68
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    69
    # https://docs.python.org/2/library/os.html#os.stat_float_times
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    70
    # "For compatibility with older Python versions,
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    71
    #  accessing stat_result as a tuple always returns integers."
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    72
    secs = stat_result[stat.ST_MTIME]
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    73
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    74
    # For now
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    75
    subsec_nanos = 0
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    76
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    77
    return timestamp((secs, subsec_nanos))