Show More
@@ -319,7 +319,9 b' static PyObject *dirstate_item_mtime_lik' | |||||
319 | return NULL; |
|
319 | return NULL; | |
320 | } |
|
320 | } | |
321 | if ((self->flags & dirstate_flag_has_file_mtime) && |
|
321 | if ((self->flags & dirstate_flag_has_file_mtime) && | |
322 |
self->mtime_s == other_s && |
|
322 | self->mtime_s == other_s && | |
|
323 | (self->mtime_ns == other_ns || self->mtime_ns == 0 || | |||
|
324 | other_ns == 0)) { | |||
323 | Py_RETURN_TRUE; |
|
325 | Py_RETURN_TRUE; | |
324 | } else { |
|
326 | } else { | |
325 | Py_RETURN_FALSE; |
|
327 | Py_RETURN_FALSE; |
@@ -5,15 +5,17 b'' | |||||
5 |
|
5 | |||
6 | from __future__ import absolute_import |
|
6 | from __future__ import absolute_import | |
7 |
|
7 | |||
|
8 | import functools | |||
8 | import stat |
|
9 | import stat | |
9 |
|
10 | |||
10 |
|
11 | |||
11 | rangemask = 0x7FFFFFFF |
|
12 | rangemask = 0x7FFFFFFF | |
12 |
|
13 | |||
13 |
|
14 | |||
|
15 | @functools.total_ordering | |||
14 | class timestamp(tuple): |
|
16 | class timestamp(tuple): | |
15 | """ |
|
17 | """ | |
16 | A Unix timestamp with nanoseconds precision, |
|
18 | A Unix timestamp with optional nanoseconds precision, | |
17 | modulo 2**31 seconds. |
|
19 | modulo 2**31 seconds. | |
18 |
|
20 | |||
19 | A 2-tuple containing: |
|
21 | A 2-tuple containing: | |
@@ -22,6 +24,7 b' class timestamp(tuple):' | |||||
22 | truncated to its lower 31 bits |
|
24 | truncated to its lower 31 bits | |
23 |
|
25 | |||
24 | `subsecond_nanoseconds`: number of nanoseconds since `truncated_seconds`. |
|
26 | `subsecond_nanoseconds`: number of nanoseconds since `truncated_seconds`. | |
|
27 | When this is zero, the sub-second precision is considered unknown. | |||
25 | """ |
|
28 | """ | |
26 |
|
29 | |||
27 | def __new__(cls, value): |
|
30 | def __new__(cls, value): | |
@@ -29,6 +32,27 b' class timestamp(tuple):' | |||||
29 | value = (truncated_seconds & rangemask, subsec_nanos) |
|
32 | value = (truncated_seconds & rangemask, subsec_nanos) | |
30 | return super(timestamp, cls).__new__(cls, value) |
|
33 | return super(timestamp, cls).__new__(cls, value) | |
31 |
|
34 | |||
|
35 | def __eq__(self, other): | |||
|
36 | self_secs, self_subsec_nanos = self | |||
|
37 | other_secs, other_subsec_nanos = other | |||
|
38 | return self_secs == other_secs and ( | |||
|
39 | self_subsec_nanos == other_subsec_nanos | |||
|
40 | or self_subsec_nanos == 0 | |||
|
41 | or other_subsec_nanos == 0 | |||
|
42 | ) | |||
|
43 | ||||
|
44 | def __gt__(self, other): | |||
|
45 | self_secs, self_subsec_nanos = self | |||
|
46 | other_secs, other_subsec_nanos = other | |||
|
47 | if self_secs > other_secs: | |||
|
48 | return True | |||
|
49 | if self_secs < other_secs: | |||
|
50 | return False | |||
|
51 | if self_subsec_nanos == 0 or other_subsec_nanos == 0: | |||
|
52 | # they are considered equal, so not "greater than" | |||
|
53 | return False | |||
|
54 | return self_subsec_nanos > other_subsec_nanos | |||
|
55 | ||||
32 |
|
56 | |||
33 | def zero(): |
|
57 | def zero(): | |
34 | """ |
|
58 | """ |
@@ -302,7 +302,9 b' class DirstateItem(object):' | |||||
302 | return False |
|
302 | return False | |
303 | self_ns = self._mtime_ns |
|
303 | self_ns = self._mtime_ns | |
304 | other_sec, other_ns = other_mtime |
|
304 | other_sec, other_ns = other_mtime | |
305 |
return self_sec == other_sec and |
|
305 | return self_sec == other_sec and ( | |
|
306 | self_ns == other_ns or self_ns == 0 or other_ns == 0 | |||
|
307 | ) | |||
306 |
|
308 | |||
307 | @property |
|
309 | @property | |
308 | def state(self): |
|
310 | def state(self): |
@@ -120,9 +120,17 b' impl TruncatedTimestamp {' | |||||
120 | /// If someone is manipulating the modification times of some files to |
|
120 | /// If someone is manipulating the modification times of some files to | |
121 | /// intentionally make `hg status` return incorrect results, not truncating |
|
121 | /// intentionally make `hg status` return incorrect results, not truncating | |
122 | /// wouldn’t help much since they can set exactly the expected timestamp. |
|
122 | /// wouldn’t help much since they can set exactly the expected timestamp. | |
|
123 | /// | |||
|
124 | /// Sub-second precision is ignored if it is zero in either value. | |||
|
125 | /// Some APIs simply return zero when more precision is not available. | |||
|
126 | /// When comparing values from different sources, if only one is truncated | |||
|
127 | /// in that way, doing a simple comparison would cause many false | |||
|
128 | /// negatives. | |||
123 | pub fn likely_equal(self, other: Self) -> bool { |
|
129 | pub fn likely_equal(self, other: Self) -> bool { | |
124 | self.truncated_seconds == other.truncated_seconds |
|
130 | self.truncated_seconds == other.truncated_seconds | |
125 | && self.nanoseconds == other.nanoseconds |
|
131 | && (self.nanoseconds == other.nanoseconds | |
|
132 | || self.nanoseconds == 0 | |||
|
133 | || other.nanoseconds == 0) | |||
126 | } |
|
134 | } | |
127 |
|
135 | |||
128 | pub fn likely_equal_to_mtime_of( |
|
136 | pub fn likely_equal_to_mtime_of( |
General Comments 0
You need to be logged in to leave comments.
Login now