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