Mercurial > hg
diff rust/hg-core/src/dirstate_tree/dirstate_map.rs @ 47126:ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Use std::borrow::Cow to avoid some memory allocations and copying.
Differential Revision: https://phab.mercurial-scm.org/D10560
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 30 Apr 2021 20:21:56 +0200 |
parents | 9be618452c3b |
children | 1249eb9cc332 |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Apr 30 19:33:04 2021 +0200 +++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Apr 30 20:21:56 2021 +0200 @@ -45,7 +45,7 @@ /// names. However `BTreeMap` would waste time always re-comparing the same /// string prefix. pub(super) type ChildNodes<'on_disk> = - FastHashMap<WithBasename<HgPathBuf>, Node<'on_disk>>; + FastHashMap<WithBasename<Cow<'on_disk, HgPath>>, Node<'on_disk>>; /// Represents a file or a directory #[derive(Default)] @@ -99,9 +99,10 @@ self.on_disk, |path, entry, copy_source| { let tracked = entry.state.is_tracked(); - let node = Self::get_or_insert_node_tracing_ancestors( + let node = Self::get_or_insert_node( &mut self.root, path, + WithBasename::to_cow_borrowed, |ancestor| { if tracked { ancestor.tracked_descendants_count += 1 @@ -181,16 +182,12 @@ } } - fn get_or_insert_node<'tree>( + fn get_or_insert_node<'tree, 'path>( root: &'tree mut ChildNodes<'on_disk>, - path: &HgPath, - ) -> &'tree mut Node<'on_disk> { - Self::get_or_insert_node_tracing_ancestors(root, path, |_| {}) - } - - fn get_or_insert_node_tracing_ancestors<'tree>( - root: &'tree mut ChildNodes<'on_disk>, - path: &HgPath, + path: &'path HgPath, + to_cow: impl Fn( + WithBasename<&'path HgPath>, + ) -> WithBasename<Cow<'on_disk, HgPath>>, mut each_ancestor: impl FnMut(&mut Node), ) -> &'tree mut Node<'on_disk> { let mut child_nodes = root; @@ -204,7 +201,7 @@ // map already contains that key, without introducing double // lookup? let child_node = - child_nodes.entry(ancestor_path.to_owned()).or_default(); + child_nodes.entry(to_cow(ancestor_path)).or_default(); if let Some(next) = inclusive_ancestor_paths.next() { each_ancestor(child_node); ancestor_path = next; @@ -228,9 +225,10 @@ _ => 0, }; - let node = Self::get_or_insert_node_tracing_ancestors( + let node = Self::get_or_insert_node( &mut self.root, path, + WithBasename::to_cow_owned, |ancestor| { // We can’t use `+= increment` because the counter is unsigned, // and we want debug builds to detect accidental underflow @@ -593,7 +591,12 @@ key: HgPathBuf, value: HgPathBuf, ) -> Option<HgPathBuf> { - let node = Self::get_or_insert_node(&mut self.root, &key); + let node = Self::get_or_insert_node( + &mut self.root, + &key, + WithBasename::to_cow_owned, + |_ancestor| {}, + ); if node.copy_source.is_none() { self.nodes_with_copy_source_count += 1 }