97 Ok(Self::new_truncate(seconds, nanoseconds, false)) |
97 Ok(Self::new_truncate(seconds, nanoseconds, false)) |
98 } |
98 } |
99 #[cfg(not(unix))] |
99 #[cfg(not(unix))] |
100 { |
100 { |
101 metadata.modified().map(Self::from) |
101 metadata.modified().map(Self::from) |
|
102 } |
|
103 } |
|
104 |
|
105 /// Returns whether this timestamp is reliable as the "mtime" of a file. |
|
106 /// |
|
107 /// A modification time is reliable if it is older than `boundary` (or |
|
108 /// sufficiently in the future). |
|
109 /// |
|
110 /// Otherwise a concurrent modification might happens with the same mtime. |
|
111 pub fn is_reliable_mtime(&self, boundary: &Self) -> bool { |
|
112 // If the mtime of the ambiguous file is younger (or equal) to the |
|
113 // starting point of the `status` walk, we cannot garantee that |
|
114 // another, racy, write will not happen right after with the same mtime |
|
115 // and we cannot cache the information. |
|
116 // |
|
117 // However if the mtime is far away in the future, this is likely some |
|
118 // mismatch between the current clock and previous file system |
|
119 // operation. So mtime more than one days in the future are considered |
|
120 // fine. |
|
121 if self.truncated_seconds == boundary.truncated_seconds { |
|
122 self.nanoseconds != 0 |
|
123 && boundary.nanoseconds != 0 |
|
124 && self.nanoseconds < boundary.nanoseconds |
|
125 } else { |
|
126 // `truncated_seconds` is less than 2**31, |
|
127 // so this does not overflow `u32`: |
|
128 let one_day_later = boundary.truncated_seconds + 24 * 3600; |
|
129 self.truncated_seconds < boundary.truncated_seconds |
|
130 || self.truncated_seconds > one_day_later |
102 } |
131 } |
103 } |
132 } |
104 |
133 |
105 /// The lower 31 bits of the number of seconds since the epoch. |
134 /// The lower 31 bits of the number of seconds since the epoch. |
106 pub fn truncated_seconds(&self) -> u32 { |
135 pub fn truncated_seconds(&self) -> u32 { |
189 Self::new_truncate(seconds, nanoseconds, false) |
218 Self::new_truncate(seconds, nanoseconds, false) |
190 } |
219 } |
191 } |
220 } |
192 |
221 |
193 const NSEC_PER_SEC: u32 = 1_000_000_000; |
222 const NSEC_PER_SEC: u32 = 1_000_000_000; |
194 const RANGE_MASK_31BIT: u32 = 0x7FFF_FFFF; |
223 pub const RANGE_MASK_31BIT: u32 = 0x7FFF_FFFF; |
195 |
224 |
196 pub const MTIME_UNSET: i32 = -1; |
225 pub const MTIME_UNSET: i32 = -1; |
197 |
226 |
198 /// A `DirstateEntry` with a size of `-2` means that it was merged from the |
227 /// A `DirstateEntry` with a size of `-2` means that it was merged from the |
199 /// other parent. This allows revert to pick the right status back during a |
228 /// other parent. This allows revert to pick the right status back during a |