annotate rust/hg-core/src/dirstate_tree/dirstate_map.rs @ 47119:15395fd8ab28

dirstate-tree: Use HashMap instead of BTreeMap BTreeMap has the advantage of its "natural" iteration order being the one we need in the status algorithm. With HashMap however, iteration order is undefined so we need to allocate a Vec and sort it explicitly. Unfortunately many BTreeMap operations are slower than in HashMap, and skipping that extra allocation and sort is not enough to compensate. Switching to HashMap + sort makes `hg status` 17% faster in one test case, as measure with hyperfine: ``` Benchmark #1: ../hg2/hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1 Time (mean ± σ): 765.0 ms ± 8.8 ms [User: 1.352 s, System: 0.747 s] Range (min … max): 751.8 ms … 778.7 ms 10 runs Benchmark #2: ./hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1 Time (mean ± σ): 651.8 ms ± 9.9 ms [User: 1.251 s, System: 0.799 s] Range (min … max): 642.2 ms … 671.8 ms 10 runs Summary './hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1' ran 1.17 ± 0.02 times faster than '../hg2/hg status -R $REPO --config=experimental.dirstate-tree.in-memory=1' ``` * ./hg is this revision * ../hg2/hg is its parent * $REPO is an old snapshot of mozilla-central Differential Revision: https://phab.mercurial-scm.org/D10553
author Simon Sapin <simon.sapin@octobus.net>
date Thu, 29 Apr 2021 11:32:57 +0200
parents c92e63762573
children 7109a38830c9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
1 use bytes_cast::BytesCast;
47118
c92e63762573 dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents: 47116
diff changeset
2 use micro_timer::timed;
47119
15395fd8ab28 dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47118
diff changeset
3 use std::convert::TryInto;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
4 use std::path::PathBuf;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
5
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
6 use super::path_with_basename::WithBasename;
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
7 use crate::dirstate::parsers::clear_ambiguous_mtime;
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
8 use crate::dirstate::parsers::pack_entry;
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
9 use crate::dirstate::parsers::packed_entry_size;
47098
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
10 use crate::dirstate::parsers::parse_dirstate_entries;
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
11 use crate::dirstate::parsers::parse_dirstate_parents;
47101
5d62243c7732 rust: Add a Timestamp struct instead of abusing Duration
Simon Sapin <simon.sapin@octobus.net>
parents: 47100
diff changeset
12 use crate::dirstate::parsers::Timestamp;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
13 use crate::matchers::Matcher;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
14 use crate::revlog::node::NULL_NODE;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
15 use crate::utils::hg_path::{HgPath, HgPathBuf};
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
16 use crate::CopyMapIter;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
17 use crate::DirstateEntry;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
18 use crate::DirstateError;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
19 use crate::DirstateMapError;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
20 use crate::DirstateParents;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
21 use crate::DirstateStatus;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
22 use crate::EntryState;
47119
15395fd8ab28 dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47118
diff changeset
23 use crate::FastHashMap;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
24 use crate::PatternFileWarning;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
25 use crate::StateMapIter;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
26 use crate::StatusError;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
27 use crate::StatusOptions;
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
28
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
29 pub struct DirstateMap {
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
30 parents: Option<DirstateParents>,
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
31 dirty_parents: bool,
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
32 pub(super) root: ChildNodes,
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
33
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
34 /// Number of nodes anywhere in the tree that have `.entry.is_some()`.
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
35 nodes_with_entry_count: usize,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
36
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
37 /// Number of nodes anywhere in the tree that have
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
38 /// `.copy_source.is_some()`.
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
39 nodes_with_copy_source_count: usize,
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
40 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
41
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
42 /// Using a plain `HgPathBuf` of the full path from the repository root as a
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
43 /// map key would also work: all paths in a given map have the same parent
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
44 /// path, so comparing full paths gives the same result as comparing base
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
45 /// names. However `BTreeMap` would waste time always re-comparing the same
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
46 /// string prefix.
47119
15395fd8ab28 dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47118
diff changeset
47 pub(super) type ChildNodes = FastHashMap<WithBasename<HgPathBuf>, Node>;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
48
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
49 /// Represents a file or a directory
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
50 #[derive(Default)]
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
51 pub(super) struct Node {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
52 /// `None` for directories
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
53 pub(super) entry: Option<DirstateEntry>,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
54
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
55 pub(super) copy_source: Option<HgPathBuf>,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
56
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
57 pub(super) children: ChildNodes,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
58
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
59 /// How many (non-inclusive) descendants of this node are tracked files
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
60 tracked_descendants_count: usize,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
61 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
62
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
63 impl Node {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
64 /// Whether this node has a `DirstateEntry` with `.state.is_tracked()`
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
65 fn is_tracked_file(&self) -> bool {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
66 if let Some(entry) = &self.entry {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
67 entry.state.is_tracked()
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
68 } else {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
69 false
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
70 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
71 }
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
72
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
73 pub(super) fn state(&self) -> Option<EntryState> {
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
74 self.entry.as_ref().map(|entry| entry.state)
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
75 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
76 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
77
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
78 /// `(full_path, entry, copy_source)`
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
79 type NodeDataMut<'a> = (
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
80 &'a WithBasename<HgPathBuf>,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
81 &'a mut Option<DirstateEntry>,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
82 &'a mut Option<HgPathBuf>,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
83 );
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
84
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
85 impl DirstateMap {
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
86 pub fn new() -> Self {
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
87 Self {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
88 parents: None,
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
89 dirty_parents: false,
47119
15395fd8ab28 dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47118
diff changeset
90 root: ChildNodes::default(),
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
91 nodes_with_entry_count: 0,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
92 nodes_with_copy_source_count: 0,
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
93 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
94 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
95
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
96 fn get_node(&self, path: &HgPath) -> Option<&Node> {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
97 let mut children = &self.root;
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
98 let mut components = path.components();
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
99 let mut component =
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
100 components.next().expect("expected at least one components");
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
101 loop {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
102 let child = children.get(component)?;
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
103 if let Some(next_component) = components.next() {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
104 component = next_component;
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
105 children = &child.children;
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
106 } else {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
107 return Some(child);
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
108 }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
109 }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
110 }
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
111
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
112 /// Returns a mutable reference to the node at `path` if it exists
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
113 ///
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
114 /// This takes `root` instead of `&mut self` so that callers can mutate
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
115 /// other fields while the returned borrow is still valid
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
116 fn get_node_mut<'tree>(
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
117 root: &'tree mut ChildNodes,
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
118 path: &HgPath,
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
119 ) -> Option<&'tree mut Node> {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
120 Self::each_and_get(root, path, |_| {})
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
121 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
122
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
123 /// Call `each` for each ancestor node of the one at `path` (not including
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
124 /// that node itself), starting from nearest the root.
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
125 ///
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
126 /// Panics (possibly after some calls to `each`) if there is no node at
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
127 /// `path`.
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
128 fn for_each_ancestor_node<'tree>(
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
129 &mut self,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
130 path: &HgPath,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
131 each: impl FnMut(&mut Node),
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
132 ) {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
133 let parent = path.parent();
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
134 if !parent.is_empty() {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
135 Self::each_and_get(&mut self.root, parent, each)
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
136 .expect("missing dirstate node");
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
137 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
138 }
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
139
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
140 /// Common implementation detail of `get_node_mut` and
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
141 /// `for_each_ancestor_node`
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
142 fn each_and_get<'tree>(
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
143 root: &'tree mut ChildNodes,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
144 path: &HgPath,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
145 mut each: impl FnMut(&mut Node),
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
146 ) -> Option<&'tree mut Node> {
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
147 let mut children = root;
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
148 let mut components = path.components();
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
149 let mut component =
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
150 components.next().expect("expected at least one components");
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
151 loop {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
152 let child = children.get_mut(component)?;
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
153 each(child);
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
154 if let Some(next_component) = components.next() {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
155 component = next_component;
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
156 children = &mut child.children;
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
157 } else {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
158 return Some(child);
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
159 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
160 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
161 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
162
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
163 fn get_or_insert_node<'tree>(
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
164 root: &'tree mut ChildNodes,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
165 path: &HgPath,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
166 ) -> &'tree mut Node {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
167 let mut child_nodes = root;
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
168 let mut inclusive_ancestor_paths =
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
169 WithBasename::inclusive_ancestors_of(path);
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
170 let mut ancestor_path = inclusive_ancestor_paths
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
171 .next()
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
172 .expect("expected at least one inclusive ancestor");
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
173 loop {
47116
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
174 // TODO: can we avoid allocating an owned key in cases where the
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
175 // map already contains that key, without introducing double
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
176 // lookup?
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
177 let child_node =
47116
04bcba539c96 dirstate-tree: Avoid BTreeMap double-lookup when inserting a dirstate entry
Simon Sapin <simon.sapin@octobus.net>
parents: 47113
diff changeset
178 child_nodes.entry(ancestor_path.to_owned()).or_default();
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
179 if let Some(next) = inclusive_ancestor_paths.next() {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
180 ancestor_path = next;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
181 child_nodes = &mut child_node.children;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
182 } else {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
183 return child_node;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
184 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
185 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
186 }
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
187
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
188 /// The meaning of `new_copy_source` is:
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
189 ///
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
190 /// * `Some(Some(x))`: set `Node::copy_source` to `Some(x)`
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
191 /// * `Some(None)`: set `Node::copy_source` to `None`
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
192 /// * `None`: leave `Node::copy_source` unchanged
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
193 fn add_file_node(
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
194 &mut self,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
195 path: &HgPath,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
196 new_entry: DirstateEntry,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
197 new_copy_source: Option<Option<HgPathBuf>>,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
198 ) {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
199 let node = Self::get_or_insert_node(&mut self.root, path);
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
200 if node.entry.is_none() {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
201 self.nodes_with_entry_count += 1
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
202 }
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
203 if let Some(source) = &new_copy_source {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
204 if node.copy_source.is_none() && source.is_some() {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
205 self.nodes_with_copy_source_count += 1
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
206 }
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
207 if node.copy_source.is_some() && source.is_none() {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
208 self.nodes_with_copy_source_count -= 1
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
209 }
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
210 }
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
211 let tracked_count_increment =
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
212 match (node.is_tracked_file(), new_entry.state.is_tracked()) {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
213 (false, true) => 1,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
214 (true, false) => -1,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
215 _ => 0,
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
216 };
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
217
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
218 node.entry = Some(new_entry);
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
219 if let Some(source) = new_copy_source {
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
220 node.copy_source = source
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
221 }
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
222 // Borrow of `self.root` through `node` ends here
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
223
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
224 match tracked_count_increment {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
225 1 => self.for_each_ancestor_node(path, |node| {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
226 node.tracked_descendants_count += 1
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
227 }),
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
228 // We can’t use `+= -1` because the counter is unsigned
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
229 -1 => self.for_each_ancestor_node(path, |node| {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
230 node.tracked_descendants_count -= 1
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
231 }),
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
232 _ => {}
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
233 }
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
234 }
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
235
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
236 fn iter_nodes<'a>(
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
237 &'a self,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
238 ) -> impl Iterator<Item = (&'a WithBasename<HgPathBuf>, &'a Node)> + 'a
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
239 {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
240 // Depth first tree traversal.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
241 //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
242 // If we could afford internal iteration and recursion,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
243 // this would look like:
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
244 //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
245 // ```
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
246 // fn traverse_children(
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
247 // children: &ChildNodes,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
248 // each: &mut impl FnMut(&Node),
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
249 // ) {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
250 // for child in children.values() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
251 // traverse_children(&child.children, each);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
252 // each(child);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
253 // }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
254 // }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
255 // ```
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
256 //
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
257 // However we want an external iterator and therefore can’t use the
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
258 // call stack. Use an explicit stack instead:
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
259 let mut stack = Vec::new();
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
260 let mut iter = self.root.iter();
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
261 std::iter::from_fn(move || {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
262 while let Some((key, child_node)) = iter.next() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
263 // Pseudo-recursion
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
264 let new_iter = child_node.children.iter();
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
265 let old_iter = std::mem::replace(&mut iter, new_iter);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
266 stack.push((key, child_node, old_iter));
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
267 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
268 // Found the end of a `children.iter()` iterator.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
269 if let Some((key, child_node, next_iter)) = stack.pop() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
270 // "Return" from pseudo-recursion by restoring state from the
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
271 // explicit stack
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
272 iter = next_iter;
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
273
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
274 Some((key, child_node))
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
275 } else {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
276 // Reached the bottom of the stack, we’re done
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
277 None
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
278 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
279 })
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
280 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
281
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
282 /// Mutable iterator for the `(entry, copy source)` of each node.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
283 ///
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
284 /// It would not be safe to yield mutable references to nodes themeselves
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
285 /// with `-> impl Iterator<Item = &mut Node>` since child nodes are
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
286 /// reachable from their ancestor nodes, potentially creating multiple
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
287 /// `&mut` references to a given node.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
288 fn iter_node_data_mut<'a>(
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
289 &'a mut self,
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
290 ) -> impl Iterator<Item = NodeDataMut<'a>> + 'a {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
291 // Explict stack for pseudo-recursion, see `iter_nodes` above.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
292 let mut stack = Vec::new();
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
293 let mut iter = self.root.iter_mut();
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
294 std::iter::from_fn(move || {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
295 while let Some((key, child_node)) = iter.next() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
296 // Pseudo-recursion
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
297 let data =
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
298 (key, &mut child_node.entry, &mut child_node.copy_source);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
299 let new_iter = child_node.children.iter_mut();
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
300 let old_iter = std::mem::replace(&mut iter, new_iter);
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
301 stack.push((data, old_iter));
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
302 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
303 // Found the end of a `children.values_mut()` iterator.
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
304 if let Some((data, next_iter)) = stack.pop() {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
305 // "Return" from pseudo-recursion by restoring state from the
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
306 // explicit stack
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
307 iter = next_iter;
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
308
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
309 Some(data)
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
310 } else {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
311 // Reached the bottom of the stack, we’re done
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
312 None
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
313 }
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
314 })
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
315 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
316 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
317
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
318 impl super::dispatch::DirstateMapMethods for DirstateMap {
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
319 fn clear(&mut self) {
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
320 self.set_parents(&DirstateParents {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
321 p1: NULL_NODE,
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
322 p2: NULL_NODE,
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
323 });
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
324 self.root.clear();
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
325 self.nodes_with_entry_count = 0;
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
326 self.nodes_with_copy_source_count = 0;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
327 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
328
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
329 fn add_file(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
330 &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
331 filename: &HgPath,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
332 _old_state: EntryState,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
333 entry: DirstateEntry,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
334 ) -> Result<(), DirstateMapError> {
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
335 self.add_file_node(filename, entry, None);
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
336 Ok(())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
337 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
338
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
339 fn remove_file(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
340 &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
341 filename: &HgPath,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
342 _old_state: EntryState,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
343 size: i32,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
344 ) -> Result<(), DirstateMapError> {
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
345 let entry = DirstateEntry {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
346 state: EntryState::Removed,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
347 mode: 0,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
348 size,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
349 mtime: 0,
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
350 };
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
351 self.add_file_node(filename, entry, None);
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
352 Ok(())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
353 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
354
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
355 fn drop_file(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
356 &mut self,
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
357 filename: &HgPath,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
358 _old_state: EntryState,
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
359 ) -> Result<bool, DirstateMapError> {
47107
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
360 if let Some(node) = Self::get_node_mut(&mut self.root, filename) {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
361 let was_tracked = node.is_tracked_file();
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
362 let had_entry = node.entry.is_some();
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
363 let had_copy_source = node.copy_source.is_some();
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
364
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
365 // TODO: this leaves in the tree a "non-file" node. Should we
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
366 // remove the node instead, together with ancestor nodes for
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
367 // directories that become empty?
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
368 node.entry = None;
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
369 node.copy_source = None;
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
370
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
371 if had_entry {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
372 self.nodes_with_entry_count -= 1
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
373 }
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
374 if had_copy_source {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
375 self.nodes_with_copy_source_count -= 1
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
376 }
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
377 if was_tracked {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
378 self.for_each_ancestor_node(filename, |node| {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
379 node.tracked_descendants_count -= 1
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
380 })
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
381 }
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
382 Ok(had_entry)
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
383 } else {
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
384 Ok(false)
7dfc598ddcfe dirstate-tree: Add add_file, remove_file, and drop_file
Simon Sapin <simon.sapin@octobus.net>
parents: 47106
diff changeset
385 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
386 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
387
47105
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
388 fn clear_ambiguous_times(&mut self, filenames: Vec<HgPathBuf>, now: i32) {
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
389 for filename in filenames {
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
390 if let Some(node) = Self::get_node_mut(&mut self.root, &filename) {
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
391 if let Some(entry) = node.entry.as_mut() {
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
392 clear_ambiguous_mtime(entry, now);
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
393 }
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
394 }
ba17a2ee85ac dirstate-tree: Add clear_ambiguous_times in the new DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47104
diff changeset
395 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
396 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
397
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
398 fn non_normal_entries_contains(&mut self, key: &HgPath) -> bool {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
399 self.get_node(key)
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
400 .and_then(|node| node.entry.as_ref())
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
401 .map_or(false, DirstateEntry::is_non_normal)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
402 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
403
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
404 fn non_normal_entries_remove(&mut self, _key: &HgPath) {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
405 // Do nothing, this `DirstateMap` does not have a separate "non normal
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
406 // entries" set that need to be kept up to date
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
407 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
408
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
409 fn non_normal_or_other_parent_paths(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
410 &mut self,
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
411 ) -> Box<dyn Iterator<Item = &HgPathBuf> + '_> {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
412 Box::new(self.iter_nodes().filter_map(|(path, node)| {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
413 node.entry
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
414 .as_ref()
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
415 .filter(|entry| {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
416 entry.is_non_normal() || entry.is_from_other_parent()
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
417 })
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
418 .map(|_| path.full_path())
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
419 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
420 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
421
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
422 fn set_non_normal_other_parent_entries(&mut self, _force: bool) {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
423 // Do nothing, this `DirstateMap` does not have a separate "non normal
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
424 // entries" and "from other parent" sets that need to be recomputed
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
425 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
426
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
427 fn iter_non_normal_paths(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
428 &mut self,
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
429 ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
430 self.iter_non_normal_paths_panic()
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
431 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
432
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
433 fn iter_non_normal_paths_panic(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
434 &self,
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
435 ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
436 Box::new(self.iter_nodes().filter_map(|(path, node)| {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
437 node.entry
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
438 .as_ref()
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
439 .filter(|entry| entry.is_non_normal())
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
440 .map(|_| path.full_path())
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
441 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
442 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
443
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
444 fn iter_other_parent_paths(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
445 &mut self,
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
446 ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> {
47108
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
447 Box::new(self.iter_nodes().filter_map(|(path, node)| {
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
448 node.entry
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
449 .as_ref()
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
450 .filter(|entry| entry.is_from_other_parent())
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
451 .map(|_| path.full_path())
e3cebe96c0fc dirstate-tree: Add "non normal" and "from other parent" sets
Simon Sapin <simon.sapin@octobus.net>
parents: 47107
diff changeset
452 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
453 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
454
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
455 fn has_tracked_dir(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
456 &mut self,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
457 directory: &HgPath,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
458 ) -> Result<bool, DirstateMapError> {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
459 if let Some(node) = self.get_node(directory) {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
460 // A node without a `DirstateEntry` was created to hold child
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
461 // nodes, and is therefore a directory.
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
462 Ok(node.entry.is_none() && node.tracked_descendants_count > 0)
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
463 } else {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
464 Ok(false)
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
465 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
466 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
467
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
468 fn has_dir(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
469 &mut self,
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
470 directory: &HgPath,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
471 ) -> Result<bool, DirstateMapError> {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
472 if let Some(node) = self.get_node(directory) {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
473 // A node without a `DirstateEntry` was created to hold child
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
474 // nodes, and is therefore a directory.
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
475 Ok(node.entry.is_none())
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
476 } else {
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
477 Ok(false)
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
478 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
479 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
480
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
481 fn parents(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
482 &mut self,
47098
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
483 file_contents: &[u8],
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
484 ) -> Result<&DirstateParents, DirstateError> {
47098
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
485 if self.parents.is_none() {
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
486 let parents = if !file_contents.is_empty() {
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
487 parse_dirstate_parents(file_contents)?.clone()
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
488 } else {
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
489 DirstateParents {
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
490 p1: NULL_NODE,
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
491 p2: NULL_NODE,
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
492 }
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
493 };
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
494 self.parents = Some(parents);
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
495 }
d7631d55da3e dirstate-tree: Add parsing only dirstate parents from disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47097
diff changeset
496 Ok(self.parents.as_ref().unwrap())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
497 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
498
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
499 fn set_parents(&mut self, parents: &DirstateParents) {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
500 self.parents = Some(parents.clone());
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
501 self.dirty_parents = true;
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
502 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
503
47118
c92e63762573 dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents: 47116
diff changeset
504 #[timed]
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
505 fn read<'a>(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
506 &mut self,
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
507 file_contents: &'a [u8],
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
508 ) -> Result<Option<&'a DirstateParents>, DirstateError> {
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
509 if file_contents.is_empty() {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
510 return Ok(None);
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
511 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
512
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
513 let parents = parse_dirstate_entries(
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
514 file_contents,
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
515 |path, entry, copy_source| {
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
516 self.add_file_node(
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
517 path,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
518 *entry,
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
519 Some(copy_source.map(HgPath::to_owned)),
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
520 )
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
521 },
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
522 )?;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
523
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
524 if !self.dirty_parents {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
525 self.set_parents(parents);
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
526 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
527
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 47095
diff changeset
528 Ok(Some(parents))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
529 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
530
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
531 fn pack(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
532 &mut self,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
533 parents: DirstateParents,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
534 now: Timestamp,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
535 ) -> Result<Vec<u8>, DirstateError> {
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
536 // Optizimation (to be measured?): pre-compute size to avoid `Vec`
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
537 // reallocations
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
538 let mut size = parents.as_bytes().len();
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
539 for (path, node) in self.iter_nodes() {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
540 if node.entry.is_some() {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
541 size += packed_entry_size(
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
542 path.full_path(),
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
543 node.copy_source.as_ref(),
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
544 )
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
545 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
546 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
547
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
548 let mut packed = Vec::with_capacity(size);
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
549 packed.extend(parents.as_bytes());
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
550
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
551 let now: i32 = now.0.try_into().expect("time overflow");
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
552 for (path, opt_entry, copy_source) in self.iter_node_data_mut() {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
553 if let Some(entry) = opt_entry {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
554 clear_ambiguous_mtime(entry, now);
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
555 pack_entry(
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
556 path.full_path(),
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
557 entry,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
558 copy_source.as_ref(),
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
559 &mut packed,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
560 );
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
561 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
562 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
563 self.dirty_parents = false;
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
564 Ok(packed)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
565 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
566
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
567 fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
568 // Do nothing, this `DirstateMap` does not a separate `all_dirs` that
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
569 // needs to be recomputed
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
570 Ok(())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
571 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
572
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
573 fn set_dirs(&mut self) -> Result<(), DirstateMapError> {
47106
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
574 // Do nothing, this `DirstateMap` does not a separate `dirs` that needs
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
575 // to be recomputed
52906934b775 dirstate-tree: Add has_dir and has_tracked_dir
Simon Sapin <simon.sapin@octobus.net>
parents: 47105
diff changeset
576 Ok(())
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
577 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
578
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
579 fn status<'a>(
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
580 &'a mut self,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
581 matcher: &'a (dyn Matcher + Sync),
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
582 root_dir: PathBuf,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
583 ignore_files: Vec<PathBuf>,
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
584 options: StatusOptions,
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47109
diff changeset
585 ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47109
diff changeset
586 {
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
587 super::status::status(self, matcher, root_dir, ignore_files, options)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
588 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
589
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
590 fn copy_map_len(&self) -> usize {
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
591 self.nodes_with_copy_source_count
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
592 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
593
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
594 fn copy_map_iter(&self) -> CopyMapIter<'_> {
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
595 Box::new(self.iter_nodes().filter_map(|(path, node)| {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
596 node.copy_source
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
597 .as_ref()
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
598 .map(|copy_source| (path.full_path(), copy_source))
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
599 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
600 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
601
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
602 fn copy_map_contains_key(&self, key: &HgPath) -> bool {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
603 if let Some(node) = self.get_node(key) {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
604 node.copy_source.is_some()
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
605 } else {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
606 false
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
607 }
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
608 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
609
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
610 fn copy_map_get(&self, key: &HgPath) -> Option<&HgPathBuf> {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
611 self.get_node(key)?.copy_source.as_ref()
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
612 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
613
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
614 fn copy_map_remove(&mut self, key: &HgPath) -> Option<HgPathBuf> {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
615 let count = &mut self.nodes_with_copy_source_count;
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
616 Self::get_node_mut(&mut self.root, key).and_then(|node| {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
617 if node.copy_source.is_some() {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
618 *count -= 1
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
619 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
620 node.copy_source.take()
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
621 })
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
622 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
623
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
624 fn copy_map_insert(
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
625 &mut self,
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
626 key: HgPathBuf,
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
627 value: HgPathBuf,
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
628 ) -> Option<HgPathBuf> {
47104
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
629 let node = Self::get_or_insert_node(&mut self.root, &key);
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
630 if node.copy_source.is_none() {
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
631 self.nodes_with_copy_source_count += 1
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
632 }
fdf6cfa0e254 dirstate-tree: Add copy_map_insert and copy_map_remove
Simon Sapin <simon.sapin@octobus.net>
parents: 47103
diff changeset
633 node.copy_source.replace(value)
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
634 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
635
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
636 fn len(&self) -> usize {
47103
214ae40e136b dirstate-tree: Maintain a counter of DirstateEntry’s and copy sources
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
637 self.nodes_with_entry_count
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
638 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
639
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
640 fn contains_key(&self, key: &HgPath) -> bool {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
641 self.get(key).is_some()
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
642 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
643
47099
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
644 fn get(&self, key: &HgPath) -> Option<&DirstateEntry> {
3da19db33cbc dirstate-tree: Add map `get` and `contains_key` methods
Simon Sapin <simon.sapin@octobus.net>
parents: 47098
diff changeset
645 self.get_node(key)?.entry.as_ref()
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
646 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
647
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
648 fn iter(&self) -> StateMapIter<'_> {
47100
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
649 Box::new(self.iter_nodes().filter_map(|(path, node)| {
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
650 node.entry.as_ref().map(|entry| (path.full_path(), entry))
caa3031c9ed5 dirstate-tree: Add tree traversal/iteration
Simon Sapin <simon.sapin@octobus.net>
parents: 47099
diff changeset
651 }))
47095
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
652 }
473abf4728bf dirstate-tree: Empty shell for a second Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
653 }