--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Apr 05 10:55:27 2022 +0200
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Apr 05 10:55:28 2022 +0200
@@ -725,10 +725,11 @@
impl OwningDirstateMap {
pub fn clear(&mut self) {
- let map = self.get_map_mut();
- map.root = Default::default();
- map.nodes_with_entry_count = 0;
- map.nodes_with_copy_source_count = 0;
+ self.with_dmap_mut(|map| {
+ map.root = Default::default();
+ map.nodes_with_entry_count = 0;
+ map.nodes_with_copy_source_count = 0;
+ });
}
pub fn set_entry(
@@ -736,9 +737,10 @@
filename: &HgPath,
entry: DirstateEntry,
) -> Result<(), DirstateV2ParseError> {
- let map = self.get_map_mut();
- map.get_or_insert(&filename)?.data = NodeData::Entry(entry);
- Ok(())
+ self.with_dmap_mut(|map| {
+ map.get_or_insert(&filename)?.data = NodeData::Entry(entry);
+ Ok(())
+ })
}
pub fn add_file(
@@ -747,8 +749,9 @@
entry: DirstateEntry,
) -> Result<(), DirstateError> {
let old_state = self.get(filename)?.map(|e| e.state());
- let map = self.get_map_mut();
- Ok(map.add_or_remove_file(filename, old_state, entry)?)
+ self.with_dmap_mut(|map| {
+ Ok(map.add_or_remove_file(filename, old_state, entry)?)
+ })
}
pub fn remove_file(
@@ -779,9 +782,10 @@
if size == 0 {
self.copy_map_remove(filename)?;
}
- let map = self.get_map_mut();
- let entry = DirstateEntry::new_removed(size);
- Ok(map.add_or_remove_file(filename, old_state, entry)?)
+ self.with_dmap_mut(|map| {
+ let entry = DirstateEntry::new_removed(size);
+ Ok(map.add_or_remove_file(filename, old_state, entry)?)
+ })
}
pub fn drop_entry_and_copy_source(
@@ -791,7 +795,6 @@
let was_tracked = self
.get(filename)?
.map_or(false, |e| e.state().is_tracked());
- let map = self.get_map_mut();
struct Dropped {
was_tracked: bool,
had_entry: bool,
@@ -878,52 +881,56 @@
Ok(Some((dropped, remove)))
}
- if let Some((dropped, _removed)) = recur(
- map.on_disk,
- &mut map.unreachable_bytes,
- &mut map.root,
- filename,
- )? {
- if dropped.had_entry {
- map.nodes_with_entry_count -= 1
+ self.with_dmap_mut(|map| {
+ if let Some((dropped, _removed)) = recur(
+ map.on_disk,
+ &mut map.unreachable_bytes,
+ &mut map.root,
+ filename,
+ )? {
+ if dropped.had_entry {
+ map.nodes_with_entry_count -= 1
+ }
+ if dropped.had_copy_source {
+ map.nodes_with_copy_source_count -= 1
+ }
+ } else {
+ debug_assert!(!was_tracked);
}
- if dropped.had_copy_source {
- map.nodes_with_copy_source_count -= 1
- }
- } else {
- debug_assert!(!was_tracked);
- }
- Ok(())
+ Ok(())
+ })
}
pub fn has_tracked_dir(
&mut self,
directory: &HgPath,
) -> Result<bool, DirstateError> {
- let map = self.get_map_mut();
- if let Some(node) = map.get_node(directory)? {
- // A node without a `DirstateEntry` was created to hold child
- // nodes, and is therefore a directory.
- let state = node.state()?;
- Ok(state.is_none() && node.tracked_descendants_count() > 0)
- } else {
- Ok(false)
- }
+ self.with_dmap_mut(|map| {
+ if let Some(node) = map.get_node(directory)? {
+ // A node without a `DirstateEntry` was created to hold child
+ // nodes, and is therefore a directory.
+ let state = node.state()?;
+ Ok(state.is_none() && node.tracked_descendants_count() > 0)
+ } else {
+ Ok(false)
+ }
+ })
}
pub fn has_dir(
&mut self,
directory: &HgPath,
) -> Result<bool, DirstateError> {
- let map = self.get_map_mut();
- if let Some(node) = map.get_node(directory)? {
- // A node without a `DirstateEntry` was created to hold child
- // nodes, and is therefore a directory.
- let state = node.state()?;
- Ok(state.is_none() && node.descendants_with_entry_count() > 0)
- } else {
- Ok(false)
- }
+ self.with_dmap_mut(|map| {
+ if let Some(node) = map.get_node(directory)? {
+ // A node without a `DirstateEntry` was created to hold child
+ // nodes, and is therefore a directory.
+ let state = node.state()?;
+ Ok(state.is_none() && node.descendants_with_entry_count() > 0)
+ } else {
+ Ok(false)
+ }
+ })
}
#[timed]
@@ -975,16 +982,29 @@
on_disk::write(map, can_append)
}
- pub fn status<'a>(
- &'a mut self,
- matcher: &'a (dyn Matcher + Sync),
+ /// `callback` allows the caller to process and do something with the
+ /// results of the status. This is needed to do so efficiently (i.e.
+ /// without cloning the `DirstateStatus` object with its paths) because
+ /// we need to borrow from `Self`.
+ pub fn with_status<R>(
+ &mut self,
+ matcher: &(dyn Matcher + Sync),
root_dir: PathBuf,
ignore_files: Vec<PathBuf>,
options: StatusOptions,
- ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
- {
- let map = self.get_map_mut();
- super::status::status(map, matcher, root_dir, ignore_files, options)
+ callback: impl for<'r> FnOnce(
+ Result<(DirstateStatus<'r>, Vec<PatternFileWarning>), StatusError>,
+ ) -> R,
+ ) -> R {
+ self.with_dmap_mut(|map| {
+ callback(super::status::status(
+ map,
+ matcher,
+ root_dir,
+ ignore_files,
+ options,
+ ))
+ })
}
pub fn copy_map_len(&self) -> usize {
@@ -1032,22 +1052,23 @@
&mut self,
key: &HgPath,
) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
- let map = self.get_map_mut();
- let count = &mut map.nodes_with_copy_source_count;
- let unreachable_bytes = &mut map.unreachable_bytes;
- Ok(DirstateMap::get_node_mut(
- map.on_disk,
- unreachable_bytes,
- &mut map.root,
- key,
- )?
- .and_then(|node| {
- if let Some(source) = &node.copy_source {
- *count -= 1;
- DirstateMap::count_dropped_path(unreachable_bytes, source);
- }
- node.copy_source.take().map(Cow::into_owned)
- }))
+ self.with_dmap_mut(|map| {
+ let count = &mut map.nodes_with_copy_source_count;
+ let unreachable_bytes = &mut map.unreachable_bytes;
+ Ok(DirstateMap::get_node_mut(
+ map.on_disk,
+ unreachable_bytes,
+ &mut map.root,
+ key,
+ )?
+ .and_then(|node| {
+ if let Some(source) = &node.copy_source {
+ *count -= 1;
+ DirstateMap::count_dropped_path(unreachable_bytes, source);
+ }
+ node.copy_source.take().map(Cow::into_owned)
+ }))
+ })
}
pub fn copy_map_insert(
@@ -1055,19 +1076,20 @@
key: HgPathBuf,
value: HgPathBuf,
) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
- let map = self.get_map_mut();
- let node = DirstateMap::get_or_insert_node(
- map.on_disk,
- &mut map.unreachable_bytes,
- &mut map.root,
- &key,
- WithBasename::to_cow_owned,
- |_ancestor| {},
- )?;
- if node.copy_source.is_none() {
- map.nodes_with_copy_source_count += 1
- }
- Ok(node.copy_source.replace(value.into()).map(Cow::into_owned))
+ self.with_dmap_mut(|map| {
+ let node = DirstateMap::get_or_insert_node(
+ map.on_disk,
+ &mut map.unreachable_bytes,
+ &mut map.root,
+ &key,
+ WithBasename::to_cow_owned,
+ |_ancestor| {},
+ )?;
+ if node.copy_source.is_none() {
+ map.nodes_with_copy_source_count += 1
+ }
+ Ok(node.copy_source.replace(value.into()).map(Cow::into_owned))
+ })
}
pub fn len(&self) -> usize {
@@ -1115,7 +1137,7 @@
>,
DirstateError,
> {
- let map = self.get_map_mut();
+ let map = self.get_map();
let on_disk = map.on_disk;
Ok(Box::new(filter_map_results(
map.iter_nodes(),