Mercurial > hg-stable
changeset 47122:e3cebe96c0fc
dirstate-tree: Add "non normal" and "from other parent" sets
Unlike the other DirstateMap implementation, these sets are not materialized
separately in memory. Instead we traverse the main tree.
Differential Revision: https://phab.mercurial-scm.org/D10492
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 09 Apr 2021 13:13:19 +0200 |
parents | 7dfc598ddcfe |
children | 33e5511b571a |
files | rust/hg-core/src/dirstate.rs rust/hg-core/src/dirstate/dirstate_map.rs rust/hg-core/src/dirstate_tree/dirstate_map.rs rust/hg-core/src/dirstate_tree/dispatch.rs |
diffstat | 4 files changed, 53 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate.rs Fri Apr 09 12:55:35 2021 +0200 +++ b/rust/hg-core/src/dirstate.rs Fri Apr 09 13:13:19 2021 +0200 @@ -34,6 +34,16 @@ pub size: i32, } +impl DirstateEntry { + pub fn is_non_normal(&self) -> bool { + self.state != EntryState::Normal || self.mtime == MTIME_UNSET + } + + pub fn is_from_other_parent(&self) -> bool { + self.state == EntryState::Normal && self.size == SIZE_FROM_OTHER_PARENT + } +} + #[derive(BytesCast)] #[repr(C)] struct RawEntry { @@ -44,6 +54,8 @@ length: unaligned::I32Be, } +const MTIME_UNSET: i32 = -1; + /// A `DirstateEntry` with a size of `-2` means that it was merged from the /// other parent. This allows revert to pick the right status back during a /// merge.
--- a/rust/hg-core/src/dirstate/dirstate_map.rs Fri Apr 09 12:55:35 2021 +0200 +++ b/rust/hg-core/src/dirstate/dirstate_map.rs Fri Apr 09 13:13:19 2021 +0200 @@ -10,7 +10,7 @@ use crate::errors::HgError; use crate::revlog::node::NULL_NODE; use crate::{ - dirstate::{parsers::PARENT_SIZE, EntryState, SIZE_FROM_OTHER_PARENT}, + dirstate::{parsers::PARENT_SIZE, EntryState}, pack_dirstate, parse_dirstate, utils::{ files::normalize_case, @@ -27,8 +27,6 @@ pub type FileFoldMap = FastHashMap<HgPathBuf, HgPathBuf>; -const MTIME_UNSET: i32 = -1; - #[derive(Default)] pub struct DirstateMap { state_map: StateMap, @@ -99,13 +97,13 @@ } self.state_map.insert(filename.to_owned(), entry.to_owned()); - if entry.state != EntryState::Normal || entry.mtime == MTIME_UNSET { + if entry.is_non_normal() { self.get_non_normal_other_parent_entries() .0 .insert(filename.to_owned()); } - if entry.size == SIZE_FROM_OTHER_PARENT { + if entry.is_from_other_parent() { self.get_non_normal_other_parent_entries() .1 .insert(filename.to_owned()); @@ -199,14 +197,12 @@ } } - pub fn non_normal_entries_remove( - &mut self, - key: impl AsRef<HgPath>, - ) -> bool { + pub fn non_normal_entries_remove(&mut self, key: impl AsRef<HgPath>) { self.get_non_normal_other_parent_entries() .0 - .remove(key.as_ref()) + .remove(key.as_ref()); } + pub fn non_normal_entries_union( &mut self, other: HashSet<HgPathBuf>, @@ -257,18 +253,11 @@ let mut non_normal = HashSet::new(); let mut other_parent = HashSet::new(); - for ( - filename, - DirstateEntry { - state, size, mtime, .. - }, - ) in self.state_map.iter() - { - if *state != EntryState::Normal || *mtime == MTIME_UNSET { + for (filename, entry) in self.state_map.iter() { + if entry.is_non_normal() { non_normal.insert(filename.to_owned()); } - if *state == EntryState::Normal && *size == SIZE_FROM_OTHER_PARENT - { + if entry.is_from_other_parent() { other_parent.insert(filename.to_owned()); } }
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Apr 09 12:55:35 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Apr 09 13:13:19 2021 +0200 @@ -397,40 +397,61 @@ } } - fn non_normal_entries_contains(&mut self, _key: &HgPath) -> bool { - todo!() + fn non_normal_entries_contains(&mut self, key: &HgPath) -> bool { + self.get_node(key) + .and_then(|node| node.entry.as_ref()) + .map_or(false, DirstateEntry::is_non_normal) } - fn non_normal_entries_remove(&mut self, _key: &HgPath) -> bool { - todo!() + fn non_normal_entries_remove(&mut self, _key: &HgPath) { + // Do nothing, this `DirstateMap` does not have a separate "non normal + // entries" set that need to be kept up to date } fn non_normal_or_other_parent_paths( &mut self, ) -> Box<dyn Iterator<Item = &HgPathBuf> + '_> { - todo!() + Box::new(self.iter_nodes().filter_map(|(path, node)| { + node.entry + .as_ref() + .filter(|entry| { + entry.is_non_normal() || entry.is_from_other_parent() + }) + .map(|_| path.full_path()) + })) } fn set_non_normal_other_parent_entries(&mut self, _force: bool) { - todo!() + // Do nothing, this `DirstateMap` does not have a separate "non normal + // entries" and "from other parent" sets that need to be recomputed } fn iter_non_normal_paths( &mut self, ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> { - todo!() + self.iter_non_normal_paths_panic() } fn iter_non_normal_paths_panic( &self, ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> { - todo!() + Box::new(self.iter_nodes().filter_map(|(path, node)| { + node.entry + .as_ref() + .filter(|entry| entry.is_non_normal()) + .map(|_| path.full_path()) + })) } fn iter_other_parent_paths( &mut self, ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> { - todo!() + Box::new(self.iter_nodes().filter_map(|(path, node)| { + node.entry + .as_ref() + .filter(|entry| entry.is_from_other_parent()) + .map(|_| path.full_path()) + })) } fn has_tracked_dir(
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs Fri Apr 09 12:55:35 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/dispatch.rs Fri Apr 09 13:13:19 2021 +0200 @@ -45,7 +45,7 @@ fn non_normal_entries_contains(&mut self, key: &HgPath) -> bool; - fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool; + fn non_normal_entries_remove(&mut self, key: &HgPath); fn non_normal_or_other_parent_paths( &mut self, @@ -179,7 +179,7 @@ non_normal.contains(key) } - fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool { + fn non_normal_entries_remove(&mut self, key: &HgPath) { self.non_normal_entries_remove(key) }