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<