Show More
@@ -1,5 +1,6 b'' | |||
|
1 | 1 | use bytes_cast::BytesCast; |
|
2 | 2 | use micro_timer::timed; |
|
3 | use std::borrow::Cow; | |
|
3 | 4 | use std::convert::TryInto; |
|
4 | 5 | use std::path::PathBuf; |
|
5 | 6 | |
@@ -28,7 +29,7 b" pub struct DirstateMap<'on_disk> {" | |||
|
28 | 29 | /// Contents of the `.hg/dirstate` file |
|
29 | 30 | on_disk: &'on_disk [u8], |
|
30 | 31 | |
|
31 | pub(super) root: ChildNodes, | |
|
32 | pub(super) root: ChildNodes<'on_disk>, | |
|
32 | 33 | |
|
33 | 34 | /// Number of nodes anywhere in the tree that have `.entry.is_some()`. |
|
34 | 35 | nodes_with_entry_count: usize, |
@@ -43,33 +44,34 b" pub struct DirstateMap<'on_disk> {" | |||
|
43 | 44 | /// path, so comparing full paths gives the same result as comparing base |
|
44 | 45 | /// names. However `BTreeMap` would waste time always re-comparing the same |
|
45 | 46 | /// string prefix. |
|
46 | pub(super) type ChildNodes = FastHashMap<WithBasename<HgPathBuf>, Node>; | |
|
47 | pub(super) type ChildNodes<'on_disk> = | |
|
48 | FastHashMap<WithBasename<HgPathBuf>, Node<'on_disk>>; | |
|
47 | 49 | |
|
48 | 50 | /// Represents a file or a directory |
|
49 | 51 | #[derive(Default)] |
|
50 | pub(super) struct Node { | |
|
52 | pub(super) struct Node<'on_disk> { | |
|
51 | 53 | /// `None` for directories |
|
52 | 54 | pub(super) entry: Option<DirstateEntry>, |
|
53 | 55 | |
|
54 |
pub(super) copy_source: Option<HgPath |
|
|
56 | pub(super) copy_source: Option<Cow<'on_disk, HgPath>>, | |
|
55 | 57 | |
|
56 | pub(super) children: ChildNodes, | |
|
58 | pub(super) children: ChildNodes<'on_disk>, | |
|
57 | 59 | |
|
58 | 60 | /// How many (non-inclusive) descendants of this node are tracked files |
|
59 | 61 | tracked_descendants_count: usize, |
|
60 | 62 | } |
|
61 | 63 | |
|
62 | impl Node { | |
|
64 | impl Node<'_> { | |
|
63 | 65 | pub(super) fn state(&self) -> Option<EntryState> { |
|
64 | 66 | self.entry.as_ref().map(|entry| entry.state) |
|
65 | 67 | } |
|
66 | 68 | } |
|
67 | 69 | |
|
68 | 70 | /// `(full_path, entry, copy_source)` |
|
69 |
type NodeDataMut<' |
|
|
70 |
&' |
|
|
71 |
&' |
|
|
72 |
&' |
|
|
71 | type NodeDataMut<'tree, 'on_disk> = ( | |
|
72 | &'tree HgPath, | |
|
73 | &'tree mut Option<DirstateEntry>, | |
|
74 | &'tree mut Option<Cow<'on_disk, HgPath>>, | |
|
73 | 75 | ); |
|
74 | 76 | |
|
75 | 77 | impl<'on_disk> DirstateMap<'on_disk> { |
@@ -115,7 +117,7 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
115 | 117 | "duplicate dirstate entry in read" |
|
116 | 118 | ); |
|
117 | 119 | node.entry = Some(*entry); |
|
118 |
node.copy_source = copy_source.map( |
|
|
120 | node.copy_source = copy_source.map(Cow::Borrowed); | |
|
119 | 121 | self.nodes_with_entry_count += 1; |
|
120 | 122 | if copy_source.is_some() { |
|
121 | 123 | self.nodes_with_copy_source_count += 1 |
@@ -147,9 +149,9 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
147 | 149 | /// This takes `root` instead of `&mut self` so that callers can mutate |
|
148 | 150 | /// other fields while the returned borrow is still valid |
|
149 | 151 | fn get_node_mut<'tree>( |
|
150 | root: &'tree mut ChildNodes, | |
|
152 | root: &'tree mut ChildNodes<'on_disk>, | |
|
151 | 153 | path: &HgPath, |
|
152 | ) -> Option<&'tree mut Node> { | |
|
154 | ) -> Option<&'tree mut Node<'on_disk>> { | |
|
153 | 155 | Self::get_node_mut_tracing_ancestors(root, path, |_| {}) |
|
154 | 156 | } |
|
155 | 157 | |
@@ -159,10 +161,10 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
159 | 161 | /// Note that `each_ancestor` may be called (with what would be ancestors) |
|
160 | 162 | /// even if it turns out there is no node at `path`. |
|
161 | 163 | fn get_node_mut_tracing_ancestors<'tree>( |
|
162 | root: &'tree mut ChildNodes, | |
|
164 | root: &'tree mut ChildNodes<'on_disk>, | |
|
163 | 165 | path: &HgPath, |
|
164 | 166 | mut each_ancestor: impl FnMut(&mut Node), |
|
165 | ) -> Option<&'tree mut Node> { | |
|
167 | ) -> Option<&'tree mut Node<'on_disk>> { | |
|
166 | 168 | let mut children = root; |
|
167 | 169 | let mut components = path.components(); |
|
168 | 170 | let mut component = |
@@ -180,17 +182,17 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
180 | 182 | } |
|
181 | 183 | |
|
182 | 184 | fn get_or_insert_node<'tree>( |
|
183 | root: &'tree mut ChildNodes, | |
|
185 | root: &'tree mut ChildNodes<'on_disk>, | |
|
184 | 186 | path: &HgPath, |
|
185 | ) -> &'tree mut Node { | |
|
187 | ) -> &'tree mut Node<'on_disk> { | |
|
186 | 188 | Self::get_or_insert_node_tracing_ancestors(root, path, |_| {}) |
|
187 | 189 | } |
|
188 | 190 | |
|
189 | 191 | fn get_or_insert_node_tracing_ancestors<'tree>( |
|
190 | root: &'tree mut ChildNodes, | |
|
192 | root: &'tree mut ChildNodes<'on_disk>, | |
|
191 | 193 | path: &HgPath, |
|
192 | 194 | mut each_ancestor: impl FnMut(&mut Node), |
|
193 | ) -> &'tree mut Node { | |
|
195 | ) -> &'tree mut Node<'on_disk> { | |
|
194 | 196 | let mut child_nodes = root; |
|
195 | 197 | let mut inclusive_ancestor_paths = |
|
196 | 198 | WithBasename::inclusive_ancestors_of(path); |
@@ -298,9 +300,9 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
298 | 300 | /// with `-> impl Iterator<Item = &mut Node>` since child nodes are |
|
299 | 301 | /// reachable from their ancestor nodes, potentially creating multiple |
|
300 | 302 | /// `&mut` references to a given node. |
|
301 |
fn iter_node_data_mut<' |
|
|
302 |
&' |
|
|
303 |
) -> impl Iterator<Item = NodeDataMut<' |
|
|
303 | fn iter_node_data_mut<'tree>( | |
|
304 | &'tree mut self, | |
|
305 | ) -> impl Iterator<Item = NodeDataMut<'tree, 'on_disk>> + 'tree { | |
|
304 | 306 | // Explict stack for pseudo-recursion, see `iter_nodes` above. |
|
305 | 307 | let mut stack = Vec::new(); |
|
306 | 308 | let mut iter = self.root.iter_mut(); |
@@ -582,7 +584,7 b" impl<'on_disk> super::dispatch::Dirstate" | |||
|
582 | 584 | if node.copy_source.is_some() { |
|
583 | 585 | *count -= 1 |
|
584 | 586 | } |
|
585 | node.copy_source.take() | |
|
587 | node.copy_source.take().map(Cow::into_owned) | |
|
586 | 588 | }) |
|
587 | 589 | } |
|
588 | 590 | |
@@ -595,7 +597,7 b" impl<'on_disk> super::dispatch::Dirstate" | |||
|
595 | 597 | if node.copy_source.is_none() { |
|
596 | 598 | self.nodes_with_copy_source_count += 1 |
|
597 | 599 | } |
|
598 | node.copy_source.replace(value) | |
|
600 | node.copy_source.replace(value.into()).map(Cow::into_owned) | |
|
599 | 601 | } |
|
600 | 602 | |
|
601 | 603 | fn len(&self) -> usize { |
General Comments 0
You need to be logged in to leave comments.
Login now