Show More
@@ -30,6 +30,13 b' pub struct DirstateMap {' | |||||
30 | parents: Option<DirstateParents>, |
|
30 | parents: Option<DirstateParents>, | |
31 | dirty_parents: bool, |
|
31 | dirty_parents: bool, | |
32 | root: ChildNodes, |
|
32 | root: ChildNodes, | |
|
33 | ||||
|
34 | /// Number of nodes anywhere in the tree that have `.entry.is_some()`. | |||
|
35 | nodes_with_entry_count: usize, | |||
|
36 | ||||
|
37 | /// Number of nodes anywhere in the tree that have | |||
|
38 | /// `.copy_source.is_some()`. | |||
|
39 | nodes_with_copy_source_count: usize, | |||
33 | } |
|
40 | } | |
34 |
|
41 | |||
35 | /// Using a plain `HgPathBuf` of the full path from the repository root as a |
|
42 | /// Using a plain `HgPathBuf` of the full path from the repository root as a | |
@@ -59,6 +66,8 b' impl DirstateMap {' | |||||
59 | parents: None, |
|
66 | parents: None, | |
60 | dirty_parents: false, |
|
67 | dirty_parents: false, | |
61 | root: ChildNodes::new(), |
|
68 | root: ChildNodes::new(), | |
|
69 | nodes_with_entry_count: 0, | |||
|
70 | nodes_with_copy_source_count: 0, | |||
62 | } |
|
71 | } | |
63 | } |
|
72 | } | |
64 |
|
73 | |||
@@ -78,8 +87,13 b' impl DirstateMap {' | |||||
78 | } |
|
87 | } | |
79 | } |
|
88 | } | |
80 |
|
89 | |||
81 | fn get_or_insert_node(&mut self, path: &HgPath) -> &mut Node { |
|
90 | /// This takes `root` instead of `&mut self` so that callers can mutate | |
82 | let mut child_nodes = &mut self.root; |
|
91 | /// other fields while the returned borrow is still valid | |
|
92 | fn get_or_insert_node<'tree>( | |||
|
93 | root: &'tree mut ChildNodes, | |||
|
94 | path: &HgPath, | |||
|
95 | ) -> &'tree mut Node { | |||
|
96 | let mut child_nodes = root; | |||
83 | let mut inclusive_ancestor_paths = |
|
97 | let mut inclusive_ancestor_paths = | |
84 | WithBasename::inclusive_ancestors_of(path); |
|
98 | WithBasename::inclusive_ancestors_of(path); | |
85 | let mut ancestor_path = inclusive_ancestor_paths |
|
99 | let mut ancestor_path = inclusive_ancestor_paths | |
@@ -106,6 +120,35 b' impl DirstateMap {' | |||||
106 | } |
|
120 | } | |
107 | } |
|
121 | } | |
108 |
|
122 | |||
|
123 | /// The meaning of `new_copy_source` is: | |||
|
124 | /// | |||
|
125 | /// * `Some(Some(x))`: set `Node::copy_source` to `Some(x)` | |||
|
126 | /// * `Some(None)`: set `Node::copy_source` to `None` | |||
|
127 | /// * `None`: leave `Node::copy_source` unchanged | |||
|
128 | fn add_file_node( | |||
|
129 | &mut self, | |||
|
130 | path: &HgPath, | |||
|
131 | new_entry: DirstateEntry, | |||
|
132 | new_copy_source: Option<Option<HgPathBuf>>, | |||
|
133 | ) { | |||
|
134 | let node = Self::get_or_insert_node(&mut self.root, path); | |||
|
135 | if node.entry.is_none() { | |||
|
136 | self.nodes_with_entry_count += 1 | |||
|
137 | } | |||
|
138 | if let Some(source) = &new_copy_source { | |||
|
139 | if node.copy_source.is_none() && source.is_some() { | |||
|
140 | self.nodes_with_copy_source_count += 1 | |||
|
141 | } | |||
|
142 | if node.copy_source.is_some() && source.is_none() { | |||
|
143 | self.nodes_with_copy_source_count -= 1 | |||
|
144 | } | |||
|
145 | } | |||
|
146 | node.entry = Some(new_entry); | |||
|
147 | if let Some(source) = new_copy_source { | |||
|
148 | node.copy_source = source | |||
|
149 | } | |||
|
150 | } | |||
|
151 | ||||
109 | fn iter_nodes<'a>( |
|
152 | fn iter_nodes<'a>( | |
110 | &'a self, |
|
153 | &'a self, | |
111 | ) -> impl Iterator<Item = (&'a WithBasename<HgPathBuf>, &'a Node)> + 'a |
|
154 | ) -> impl Iterator<Item = (&'a WithBasename<HgPathBuf>, &'a Node)> + 'a | |
@@ -194,7 +237,9 b' impl super::dispatch::DirstateMapMethods' | |||||
194 | p1: NULL_NODE, |
|
237 | p1: NULL_NODE, | |
195 | p2: NULL_NODE, |
|
238 | p2: NULL_NODE, | |
196 | }); |
|
239 | }); | |
197 | self.root.clear() |
|
240 | self.root.clear(); | |
|
241 | self.nodes_with_entry_count = 0; | |||
|
242 | self.nodes_with_copy_source_count = 0; | |||
198 | } |
|
243 | } | |
199 |
|
244 | |||
200 | fn add_file( |
|
245 | fn add_file( | |
@@ -315,9 +360,11 b' impl super::dispatch::DirstateMapMethods' | |||||
315 | let parents = parse_dirstate_entries( |
|
360 | let parents = parse_dirstate_entries( | |
316 | file_contents, |
|
361 | file_contents, | |
317 | |path, entry, copy_source| { |
|
362 | |path, entry, copy_source| { | |
318 |
|
|
363 | self.add_file_node( | |
319 | node.entry = Some(*entry); |
|
364 | path, | |
320 | node.copy_source = copy_source.map(HgPath::to_owned); |
|
365 | *entry, | |
|
366 | Some(copy_source.map(HgPath::to_owned)), | |||
|
367 | ) | |||
321 | }, |
|
368 | }, | |
322 | )?; |
|
369 | )?; | |
323 |
|
370 | |||
@@ -393,7 +440,7 b' impl super::dispatch::DirstateMapMethods' | |||||
393 | } |
|
440 | } | |
394 |
|
441 | |||
395 | fn copy_map_len(&self) -> usize { |
|
442 | fn copy_map_len(&self) -> usize { | |
396 | todo!() |
|
443 | self.nodes_with_copy_source_count | |
397 | } |
|
444 | } | |
398 |
|
445 | |||
399 | fn copy_map_iter(&self) -> CopyMapIter<'_> { |
|
446 | fn copy_map_iter(&self) -> CopyMapIter<'_> { | |
@@ -429,7 +476,7 b' impl super::dispatch::DirstateMapMethods' | |||||
429 | } |
|
476 | } | |
430 |
|
477 | |||
431 | fn len(&self) -> usize { |
|
478 | fn len(&self) -> usize { | |
432 | todo!() |
|
479 | self.nodes_with_entry_count | |
433 | } |
|
480 | } | |
434 |
|
481 | |||
435 | fn contains_key(&self, key: &HgPath) -> bool { |
|
482 | fn contains_key(&self, key: &HgPath) -> bool { |
General Comments 0
You need to be logged in to leave comments.
Login now