Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/dirstate_tree/status.rs @ 48205:320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
? instead of 64 bits, while keeping the sub-second presision.
This brings the size of one timestamp from 12 bytes to 8 bytes.
31 bits is chosen instead of 32 because that?s already what happens for the
mtime of files and symlinks, because dirstate-v1 uses negative i32 values as
markers.
Later we?ll add sub-second precision for file/symlink mtimes, making their
dirstate-v2 representation the same as for directories.
Differential Revision: https://phab.mercurial-scm.org/D11633
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Tue, 12 Oct 2021 16:38:13 +0200 |
parents | d2f760c2c91c |
children | 15dedc0c5c35 |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/status.rs Tue Oct 12 16:20:05 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/status.rs Tue Oct 12 16:38:13 2021 +0200 @@ -1,4 +1,4 @@ -use crate::dirstate::entry::Timestamp; +use crate::dirstate::entry::TruncatedTimestamp; use crate::dirstate::status::IgnoreFnType; use crate::dirstate_tree::dirstate_map::BorrowedPath; use crate::dirstate_tree::dirstate_map::ChildNodesRef; @@ -126,7 +126,8 @@ matcher: &'a (dyn Matcher + Sync), ignore_fn: IgnoreFnType<'a>, outcome: Mutex<DirstateStatus<'on_disk>>, - new_cachable_directories: Mutex<Vec<(Cow<'on_disk, HgPath>, Timestamp)>>, + new_cachable_directories: + Mutex<Vec<(Cow<'on_disk, HgPath>, TruncatedTimestamp)>>, outated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>, /// Whether ignore files like `.hgignore` have changed since the previous @@ -165,7 +166,7 @@ dirstate_node: &NodeRef<'tree, 'on_disk>, ) -> Result<(), DirstateV2ParseError> { if self.ignore_patterns_have_changed == Some(true) - && dirstate_node.cached_directory_mtime().is_some() + && dirstate_node.cached_directory_mtime()?.is_some() { self.outated_cached_directories.lock().unwrap().push( dirstate_node @@ -182,7 +183,7 @@ fn can_skip_fs_readdir( &self, directory_metadata: Option<&std::fs::Metadata>, - cached_directory_mtime: Option<Timestamp>, + cached_directory_mtime: Option<TruncatedTimestamp>, ) -> bool { if !self.options.list_unknown && !self.options.list_ignored { // All states that we care about listing have corresponding @@ -199,8 +200,9 @@ // directory eligible for `read_dir` caching. if let Some(meta) = directory_metadata { if let Ok(current_mtime) = meta.modified() { - let current_mtime = Timestamp::from(current_mtime); - if current_mtime == cached_mtime { + let truncated = + TruncatedTimestamp::from(current_mtime); + if truncated.very_likely_equal(&cached_mtime) { // The mtime of that directory has not changed // since then, which means that the results of // `read_dir` should also be unchanged. @@ -222,7 +224,7 @@ directory_hg_path: &BorrowedPath<'tree, 'on_disk>, directory_fs_path: &Path, directory_metadata: Option<&std::fs::Metadata>, - cached_directory_mtime: Option<Timestamp>, + cached_directory_mtime: Option<TruncatedTimestamp>, is_at_repo_root: bool, ) -> Result<bool, DirstateV2ParseError> { if self.can_skip_fs_readdir(directory_metadata, cached_directory_mtime) @@ -363,7 +365,7 @@ hg_path, fs_path, Some(fs_metadata), - dirstate_node.cached_directory_mtime(), + dirstate_node.cached_directory_mtime()?, is_at_repo_root, )?; self.maybe_save_directory_mtime( @@ -466,16 +468,22 @@ // // We deem this scenario (unlike the previous one) to be // unlikely enough in practice. - let timestamp = directory_mtime.into(); - let cached = dirstate_node.cached_directory_mtime(); - if cached != Some(timestamp) { + let truncated = TruncatedTimestamp::from(directory_mtime); + let is_up_to_date = if let Some(cached) = + dirstate_node.cached_directory_mtime()? + { + cached.very_likely_equal(&truncated) + } else { + false + }; + if !is_up_to_date { let hg_path = dirstate_node .full_path_borrowed(self.dmap.on_disk)? .detach_from_tree(); self.new_cachable_directories .lock() .unwrap() - .push((hg_path, timestamp)) + .push((hg_path, truncated)) } } }