Mercurial > public > mercurial-scm > hg
comparison rust/hg-core/src/dirstate_tree/dispatch.rs @ 47491:8851acad5906
rust: Document the DirstateMapMethods trait
Differential Revision: https://phab.mercurial-scm.org/D10919
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 01 Jul 2021 18:51:18 +0200 |
parents | eb416759af7e |
children | eaae39894312 |
comparison
equal
deleted
inserted
replaced
47490:084ed6a7c6fd | 47491:8851acad5906 |
---|---|
14 use crate::PatternFileWarning; | 14 use crate::PatternFileWarning; |
15 use crate::StateMapIter; | 15 use crate::StateMapIter; |
16 use crate::StatusError; | 16 use crate::StatusError; |
17 use crate::StatusOptions; | 17 use crate::StatusOptions; |
18 | 18 |
19 /// `rust/hg-cpython/src/dirstate/dirstate_map.rs` implements in Rust a | |
20 /// `DirstateMap` Python class that wraps `Box<dyn DirstateMapMethods + Send>`, | |
21 /// a trait object of this trait. Except for constructors, this trait defines | |
22 /// all APIs that the class needs to interact with its inner dirstate map. | |
23 /// | |
24 /// A trait object is used to support two different concrete types: | |
25 /// | |
26 /// * `rust/hg-core/src/dirstate/dirstate_map.rs` defines the "flat dirstate | |
27 /// map" which is based on a few large `HgPath`-keyed `HashMap` and `HashSet` | |
28 /// fields. | |
29 /// * `rust/hg-core/src/dirstate_tree/dirstate_map.rs` defines the "tree | |
30 /// dirstate map" based on a tree data struture with nodes for directories | |
31 /// containing child nodes for their files and sub-directories. This tree | |
32 /// enables a more efficient algorithm for `hg status`, but its details are | |
33 /// abstracted in this trait. | |
34 /// | |
35 /// The dirstate map associates paths of files in the working directory to | |
36 /// various information about the state of those files. | |
19 pub trait DirstateMapMethods { | 37 pub trait DirstateMapMethods { |
38 /// Remove information about all files in this map | |
20 fn clear(&mut self); | 39 fn clear(&mut self); |
21 | 40 |
41 /// Add or change the information associated to a given file. | |
42 /// | |
43 /// `old_state` is the state in the entry that `get` would have returned | |
44 /// before this call, or `EntryState::Unknown` if there was no such entry. | |
45 /// | |
46 /// `entry.state` should never be `EntryState::Unknown`. | |
22 fn add_file( | 47 fn add_file( |
23 &mut self, | 48 &mut self, |
24 filename: &HgPath, | 49 filename: &HgPath, |
25 old_state: EntryState, | 50 old_state: EntryState, |
26 entry: DirstateEntry, | 51 entry: DirstateEntry, |
27 ) -> Result<(), DirstateError>; | 52 ) -> Result<(), DirstateError>; |
28 | 53 |
54 /// Mark a file as "removed" (as in `hg rm`). | |
55 /// | |
56 /// `old_state` is the state in the entry that `get` would have returned | |
57 /// before this call, or `EntryState::Unknown` if there was no such entry. | |
58 /// | |
59 /// `size` is not actually a size but the 0 or -1 or -2 value that would be | |
60 /// put in the size field in the dirstate-v1 format. | |
29 fn remove_file( | 61 fn remove_file( |
30 &mut self, | 62 &mut self, |
31 filename: &HgPath, | 63 filename: &HgPath, |
32 old_state: EntryState, | 64 old_state: EntryState, |
33 size: i32, | 65 size: i32, |
34 ) -> Result<(), DirstateError>; | 66 ) -> Result<(), DirstateError>; |
35 | 67 |
68 /// Drop information about this file from the map if any, and return | |
69 /// whether there was any. | |
70 /// | |
71 /// `get` will now return `None` for this filename. | |
72 /// | |
73 /// `old_state` is the state in the entry that `get` would have returned | |
74 /// before this call, or `EntryState::Unknown` if there was no such entry. | |
36 fn drop_file( | 75 fn drop_file( |
37 &mut self, | 76 &mut self, |
38 filename: &HgPath, | 77 filename: &HgPath, |
39 old_state: EntryState, | 78 old_state: EntryState, |
40 ) -> Result<bool, DirstateError>; | 79 ) -> Result<bool, DirstateError>; |
41 | 80 |
81 /// Among given files, mark the stored `mtime` as ambiguous if there is one | |
82 /// (if `state == EntryState::Normal`) equal to the given current Unix | |
83 /// timestamp. | |
42 fn clear_ambiguous_times( | 84 fn clear_ambiguous_times( |
43 &mut self, | 85 &mut self, |
44 filenames: Vec<HgPathBuf>, | 86 filenames: Vec<HgPathBuf>, |
45 now: i32, | 87 now: i32, |
46 ) -> Result<(), DirstateV2ParseError>; | 88 ) -> Result<(), DirstateV2ParseError>; |
47 | 89 |
90 /// Return whether the map has an "non-normal" entry for the given | |
91 /// filename. That is, any entry with a `state` other than | |
92 /// `EntryState::Normal` or with an ambiguous `mtime`. | |
48 fn non_normal_entries_contains( | 93 fn non_normal_entries_contains( |
49 &mut self, | 94 &mut self, |
50 key: &HgPath, | 95 key: &HgPath, |
51 ) -> Result<bool, DirstateV2ParseError>; | 96 ) -> Result<bool, DirstateV2ParseError>; |
52 | 97 |
98 /// Mark the given path as "normal" file. This is only relevant in the flat | |
99 /// dirstate map where there is a separate `HashSet` that needs to be kept | |
100 /// up to date. | |
53 fn non_normal_entries_remove(&mut self, key: &HgPath); | 101 fn non_normal_entries_remove(&mut self, key: &HgPath); |
54 | 102 |
103 /// Return an iterator of paths whose respective entry are either | |
104 /// "non-normal" (see `non_normal_entries_contains`) or "from other | |
105 /// parent". | |
106 /// | |
107 /// If that information is cached, create the cache as needed. | |
108 /// | |
109 /// "From other parent" is defined as `state == Normal && size == -2`. | |
110 /// | |
111 /// Because parse errors can happen during iteration, the iterated items | |
112 /// are `Result`s. | |
55 fn non_normal_or_other_parent_paths( | 113 fn non_normal_or_other_parent_paths( |
56 &mut self, | 114 &mut self, |
57 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>; | 115 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>; |
58 | 116 |
117 /// Create the cache for `non_normal_or_other_parent_paths` if needed. | |
118 /// | |
119 /// If `force` is true, the cache is re-created even if it already exists. | |
59 fn set_non_normal_other_parent_entries(&mut self, force: bool); | 120 fn set_non_normal_other_parent_entries(&mut self, force: bool); |
60 | 121 |
122 /// Return an iterator of paths whose respective entry are "non-normal" | |
123 /// (see `non_normal_entries_contains`). | |
124 /// | |
125 /// If that information is cached, create the cache as needed. | |
126 /// | |
127 /// Because parse errors can happen during iteration, the iterated items | |
128 /// are `Result`s. | |
61 fn iter_non_normal_paths( | 129 fn iter_non_normal_paths( |
62 &mut self, | 130 &mut self, |
63 ) -> Box< | 131 ) -> Box< |
64 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | 132 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, |
65 >; | 133 >; |
66 | 134 |
135 /// Same as `iter_non_normal_paths`, but takes `&self` instead of `&mut | |
136 /// self`. | |
137 /// | |
138 /// Panics if a cache is necessary but does not exist yet. | |
67 fn iter_non_normal_paths_panic( | 139 fn iter_non_normal_paths_panic( |
68 &self, | 140 &self, |
69 ) -> Box< | 141 ) -> Box< |
70 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | 142 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, |
71 >; | 143 >; |
72 | 144 |
145 /// Return an iterator of paths whose respective entry are "from other | |
146 /// parent". | |
147 /// | |
148 /// If that information is cached, create the cache as needed. | |
149 /// | |
150 /// "From other parent" is defined as `state == Normal && size == -2`. | |
151 /// | |
152 /// Because parse errors can happen during iteration, the iterated items | |
153 /// are `Result`s. | |
73 fn iter_other_parent_paths( | 154 fn iter_other_parent_paths( |
74 &mut self, | 155 &mut self, |
75 ) -> Box< | 156 ) -> Box< |
76 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, | 157 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_, |
77 >; | 158 >; |
78 | 159 |
160 /// Returns whether the sub-tree rooted at the given directory contains any | |
161 /// tracked file. | |
162 /// | |
163 /// A file is tracked if it has a `state` other than `EntryState::Removed`. | |
79 fn has_tracked_dir( | 164 fn has_tracked_dir( |
80 &mut self, | 165 &mut self, |
81 directory: &HgPath, | 166 directory: &HgPath, |
82 ) -> Result<bool, DirstateError>; | 167 ) -> Result<bool, DirstateError>; |
83 | 168 |
169 /// Returns whether the sub-tree rooted at the given directory contains any | |
170 /// file with a dirstate entry. | |
84 fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError>; | 171 fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError>; |
85 | 172 |
173 /// Clear mtimes that are ambigous with `now` (similar to | |
174 /// `clear_ambiguous_times` but for all files in the dirstate map), and | |
175 /// serialize bytes to write the `.hg/dirstate` file to disk in dirstate-v1 | |
176 /// format. | |
86 fn pack_v1( | 177 fn pack_v1( |
87 &mut self, | 178 &mut self, |
88 parents: DirstateParents, | 179 parents: DirstateParents, |
89 now: Timestamp, | 180 now: Timestamp, |
90 ) -> Result<Vec<u8>, DirstateError>; | 181 ) -> Result<Vec<u8>, DirstateError>; |
91 | 182 |
183 /// Clear mtimes that are ambigous with `now` (similar to | |
184 /// `clear_ambiguous_times` but for all files in the dirstate map), and | |
185 /// serialize bytes to write the `.hg/dirstate` file to disk in dirstate-v2 | |
186 /// format. | |
187 /// | |
188 /// Note: this is only supported by the tree dirstate map. | |
92 fn pack_v2( | 189 fn pack_v2( |
93 &mut self, | 190 &mut self, |
94 parents: DirstateParents, | 191 parents: DirstateParents, |
95 now: Timestamp, | 192 now: Timestamp, |
96 ) -> Result<Vec<u8>, DirstateError>; | 193 ) -> Result<Vec<u8>, DirstateError>; |
97 | 194 |
195 /// Run the status algorithm. | |
196 /// | |
197 /// This is not sematically a method of the dirstate map, but a different | |
198 /// algorithm is used for the flat v.s. tree dirstate map so having it in | |
199 /// this trait enables the same dynamic dispatch as with other methods. | |
98 fn status<'a>( | 200 fn status<'a>( |
99 &'a mut self, | 201 &'a mut self, |
100 matcher: &'a (dyn Matcher + Sync), | 202 matcher: &'a (dyn Matcher + Sync), |
101 root_dir: PathBuf, | 203 root_dir: PathBuf, |
102 ignore_files: Vec<PathBuf>, | 204 ignore_files: Vec<PathBuf>, |
103 options: StatusOptions, | 205 options: StatusOptions, |
104 ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>; | 206 ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>; |
105 | 207 |
208 /// Returns how many files in the dirstate map have a recorded copy source. | |
106 fn copy_map_len(&self) -> usize; | 209 fn copy_map_len(&self) -> usize; |
107 | 210 |
211 /// Returns an iterator of `(path, copy_source)` for all files that have a | |
212 /// copy source. | |
108 fn copy_map_iter(&self) -> CopyMapIter<'_>; | 213 fn copy_map_iter(&self) -> CopyMapIter<'_>; |
109 | 214 |
215 /// Returns whether the givef file has a copy source. | |
110 fn copy_map_contains_key( | 216 fn copy_map_contains_key( |
111 &self, | 217 &self, |
112 key: &HgPath, | 218 key: &HgPath, |
113 ) -> Result<bool, DirstateV2ParseError>; | 219 ) -> Result<bool, DirstateV2ParseError>; |
114 | 220 |
221 /// Returns the copy source for the given file. | |
115 fn copy_map_get( | 222 fn copy_map_get( |
116 &self, | 223 &self, |
117 key: &HgPath, | 224 key: &HgPath, |
118 ) -> Result<Option<&HgPath>, DirstateV2ParseError>; | 225 ) -> Result<Option<&HgPath>, DirstateV2ParseError>; |
119 | 226 |
227 /// Removes the recorded copy source if any for the given file, and returns | |
228 /// it. | |
120 fn copy_map_remove( | 229 fn copy_map_remove( |
121 &mut self, | 230 &mut self, |
122 key: &HgPath, | 231 key: &HgPath, |
123 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; | 232 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; |
124 | 233 |
234 /// Set the given `value` copy source for the given `key` file. | |
125 fn copy_map_insert( | 235 fn copy_map_insert( |
126 &mut self, | 236 &mut self, |
127 key: HgPathBuf, | 237 key: HgPathBuf, |
128 value: HgPathBuf, | 238 value: HgPathBuf, |
129 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; | 239 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>; |
130 | 240 |
241 /// Returns the number of files that have an entry. | |
131 fn len(&self) -> usize; | 242 fn len(&self) -> usize; |
132 | 243 |
244 /// Returns whether the given file has an entry. | |
133 fn contains_key(&self, key: &HgPath) | 245 fn contains_key(&self, key: &HgPath) |
134 -> Result<bool, DirstateV2ParseError>; | 246 -> Result<bool, DirstateV2ParseError>; |
135 | 247 |
248 /// Returns the entry, if any, for the given file. | |
136 fn get( | 249 fn get( |
137 &self, | 250 &self, |
138 key: &HgPath, | 251 key: &HgPath, |
139 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError>; | 252 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError>; |
140 | 253 |
254 /// Returns a `(path, entry)` iterator of files that have an entry. | |
255 /// | |
256 /// Because parse errors can happen during iteration, the iterated items | |
257 /// are `Result`s. | |
141 fn iter(&self) -> StateMapIter<'_>; | 258 fn iter(&self) -> StateMapIter<'_>; |
142 | 259 |
260 /// In the tree dirstate, return an iterator of "directory" (entry-less) | |
261 /// nodes with the data stored for them. This is for `hg debugdirstate | |
262 /// --dirs`. | |
263 /// | |
264 /// In the flat dirstate, returns an empty iterator. | |
265 /// | |
266 /// Because parse errors can happen during iteration, the iterated items | |
267 /// are `Result`s. | |
143 fn iter_directories( | 268 fn iter_directories( |
144 &self, | 269 &self, |
145 ) -> Box< | 270 ) -> Box< |
146 dyn Iterator< | 271 dyn Iterator< |
147 Item = Result< | 272 Item = Result< |