Show More
@@ -1,7 +1,9 b'' | |||||
1 | use crate::dirstate_tree::on_disk::DirstateV2ParseError; |
|
1 | use crate::dirstate_tree::on_disk::DirstateV2ParseError; | |
2 | use crate::errors::HgError; |
|
2 | use crate::errors::HgError; | |
3 | use bitflags::bitflags; |
|
3 | use bitflags::bitflags; | |
4 | use std::convert::TryFrom; |
|
4 | use std::convert::{TryFrom, TryInto}; | |
|
5 | use std::fs; | |||
|
6 | use std::io; | |||
5 | use std::time::{SystemTime, UNIX_EPOCH}; |
|
7 | use std::time::{SystemTime, UNIX_EPOCH}; | |
6 |
|
8 | |||
7 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
|
9 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | |
@@ -69,6 +71,21 b' impl TruncatedTimestamp {' | |||||
69 | } |
|
71 | } | |
70 | } |
|
72 | } | |
71 |
|
73 | |||
|
74 | pub fn for_mtime_of(metadata: &fs::Metadata) -> io::Result<Self> { | |||
|
75 | #[cfg(unix)] | |||
|
76 | { | |||
|
77 | use std::os::unix::fs::MetadataExt; | |||
|
78 | let seconds = metadata.mtime(); | |||
|
79 | // i64 -> u32 with value always in the `0 .. NSEC_PER_SEC` range | |||
|
80 | let nanoseconds = metadata.mtime_nsec().try_into().unwrap(); | |||
|
81 | Ok(Self::new_truncate(seconds, nanoseconds)) | |||
|
82 | } | |||
|
83 | #[cfg(not(unix))] | |||
|
84 | { | |||
|
85 | metadata.modified().map(Self::from) | |||
|
86 | } | |||
|
87 | } | |||
|
88 | ||||
72 | /// The lower 31 bits of the number of seconds since the epoch. |
|
89 | /// The lower 31 bits of the number of seconds since the epoch. | |
73 | pub fn truncated_seconds(&self) -> u32 { |
|
90 | pub fn truncated_seconds(&self) -> u32 { | |
74 | self.truncated_seconds |
|
91 | self.truncated_seconds | |
@@ -93,10 +110,17 b' impl TruncatedTimestamp {' | |||||
93 | /// If someone is manipulating the modification times of some files to |
|
110 | /// If someone is manipulating the modification times of some files to | |
94 | /// intentionally make `hg status` return incorrect results, not truncating |
|
111 | /// intentionally make `hg status` return incorrect results, not truncating | |
95 | /// wouldn’t help much since they can set exactly the expected timestamp. |
|
112 | /// wouldn’t help much since they can set exactly the expected timestamp. | |
96 |
pub fn very_likely_equal( |
|
113 | pub fn very_likely_equal(self, other: Self) -> bool { | |
97 | self.truncated_seconds == other.truncated_seconds |
|
114 | self.truncated_seconds == other.truncated_seconds | |
98 | && self.nanoseconds == other.nanoseconds |
|
115 | && self.nanoseconds == other.nanoseconds | |
99 | } |
|
116 | } | |
|
117 | ||||
|
118 | pub fn very_likely_equal_to_mtime_of( | |||
|
119 | self, | |||
|
120 | metadata: &fs::Metadata, | |||
|
121 | ) -> io::Result<bool> { | |||
|
122 | Ok(self.very_likely_equal(Self::for_mtime_of(metadata)?)) | |||
|
123 | } | |||
100 | } |
|
124 | } | |
101 |
|
125 | |||
102 | impl From<SystemTime> for TruncatedTimestamp { |
|
126 | impl From<SystemTime> for TruncatedTimestamp { |
@@ -199,15 +199,14 b" impl<'a, 'tree, 'on_disk> StatusCommon<'" | |||||
199 | // by a previous run of the `status` algorithm which found this |
|
199 | // by a previous run of the `status` algorithm which found this | |
200 | // directory eligible for `read_dir` caching. |
|
200 | // directory eligible for `read_dir` caching. | |
201 | if let Some(meta) = directory_metadata { |
|
201 | if let Some(meta) = directory_metadata { | |
202 |
if |
|
202 | if cached_mtime | |
203 | let truncated = |
|
203 | .very_likely_equal_to_mtime_of(meta) | |
204 | TruncatedTimestamp::from(current_mtime); |
|
204 | .unwrap_or(false) | |
205 | if truncated.very_likely_equal(&cached_mtime) { |
|
205 | { | |
206 |
|
|
206 | // The mtime of that directory has not changed | |
207 |
|
|
207 | // since then, which means that the results of | |
208 |
|
|
208 | // `read_dir` should also be unchanged. | |
209 |
|
|
209 | return true; | |
210 | } |
|
|||
211 | } |
|
210 | } | |
212 | } |
|
211 | } | |
213 | } |
|
212 | } | |
@@ -472,7 +471,7 b" impl<'a, 'tree, 'on_disk> StatusCommon<'" | |||||
472 | let is_up_to_date = if let Some(cached) = |
|
471 | let is_up_to_date = if let Some(cached) = | |
473 | dirstate_node.cached_directory_mtime()? |
|
472 | dirstate_node.cached_directory_mtime()? | |
474 | { |
|
473 | { | |
475 |
cached.very_likely_equal( |
|
474 | cached.very_likely_equal(truncated) | |
476 | } else { |
|
475 | } else { | |
477 | false |
|
476 | false | |
478 | }; |
|
477 | }; |
General Comments 0
You need to be logged in to leave comments.
Login now