comparison rust/hg-core/src/dirstate_tree/dispatch.rs @ 48061:060cd909439f

dirstate: drop all logic around the "non-normal" sets The dirstate has a lot of code to compute a set of all "non-normal" and "from_other_parent" entries. This is all used in one, unique, location, when `setparent` is called and moved from a merge to a non merge. At that time, any "merge related" information has to be dropped. This is mostly useful for command like `graft` or `shelve` that move to a single-parent state -before- the commit. Otherwise the commit will already have removed all traces of the merge information in the dirstate (e.g. for a regular merges). The bookkeeping for these sets is quite invasive. And it seems simpler to just drop it and do the full computation in the single location where we actually use it (since we have to do the computation at least once anyway). This simplify the code a lot, and clarify why this kind of computation is needed. The possible drawback compared to the previous code are: - if the operation happens in a loop, we will end up doing it multiple time, - the C code to detect entry of interest have been dropped, for now. It will be re-introduced later, with a processing code directly in C for even faster operation. Differential Revision: https://phab.mercurial-scm.org/D11507
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 28 Sep 2021 20:05:37 +0200
parents cd13d3c2ad2e
children bf8837e3d7ce
comparison
equal deleted inserted replaced
48060:a660d8a53267 48061:060cd909439f
65 fn drop_entry_and_copy_source( 65 fn drop_entry_and_copy_source(
66 &mut self, 66 &mut self,
67 filename: &HgPath, 67 filename: &HgPath,
68 ) -> Result<(), DirstateError>; 68 ) -> Result<(), DirstateError>;
69 69
70 /// Return whether the map has an "non-normal" entry for the given
71 /// filename. That is, any entry with a `state` other than
72 /// `EntryState::Normal` or with an ambiguous `mtime`.
73 fn non_normal_entries_contains(
74 &mut self,
75 key: &HgPath,
76 ) -> Result<bool, DirstateV2ParseError>;
77
78 /// Mark the given path as "normal" file. This is only relevant in the flat
79 /// dirstate map where there is a separate `HashSet` that needs to be kept
80 /// up to date.
81 /// Returns whether the key was present in the set.
82 fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool;
83
84 /// Mark the given path as "non-normal" file.
85 /// This is only relevant in the flat dirstate map where there is a
86 /// separate `HashSet` that needs to be kept up to date.
87 fn non_normal_entries_add(&mut self, key: &HgPath);
88
89 /// Return an iterator of paths whose respective entry are either
90 /// "non-normal" (see `non_normal_entries_contains`) or "from other
91 /// parent".
92 ///
93 /// If that information is cached, create the cache as needed.
94 ///
95 /// "From other parent" is defined as `state == Normal && size == -2`.
96 ///
97 /// Because parse errors can happen during iteration, the iterated items
98 /// are `Result`s.
99 fn non_normal_or_other_parent_paths(
100 &mut self,
101 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>;
102
103 /// Create the cache for `non_normal_or_other_parent_paths` if needed.
104 ///
105 /// If `force` is true, the cache is re-created even if it already exists.
106 fn set_non_normal_other_parent_entries(&mut self, force: bool);
107
108 /// Return an iterator of paths whose respective entry are "non-normal"
109 /// (see `non_normal_entries_contains`).
110 ///
111 /// If that information is cached, create the cache as needed.
112 ///
113 /// Because parse errors can happen during iteration, the iterated items
114 /// are `Result`s.
115 fn iter_non_normal_paths(
116 &mut self,
117 ) -> Box<
118 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
119 >;
120
121 /// Same as `iter_non_normal_paths`, but takes `&self` instead of `&mut
122 /// self`.
123 ///
124 /// Panics if a cache is necessary but does not exist yet.
125 fn iter_non_normal_paths_panic(
126 &self,
127 ) -> Box<
128 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
129 >;
130
131 /// Return an iterator of paths whose respective entry are "from other
132 /// parent".
133 ///
134 /// If that information is cached, create the cache as needed.
135 ///
136 /// "From other parent" is defined as `state == Normal && size == -2`.
137 ///
138 /// Because parse errors can happen during iteration, the iterated items
139 /// are `Result`s.
140 fn iter_other_parent_paths(
141 &mut self,
142 ) -> Box<
143 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
144 >;
145
146 /// Returns whether the sub-tree rooted at the given directory contains any 70 /// Returns whether the sub-tree rooted at the given directory contains any
147 /// tracked file. 71 /// tracked file.
148 /// 72 ///
149 /// A file is tracked if it has a `state` other than `EntryState::Removed`. 73 /// A file is tracked if it has a `state` other than `EntryState::Removed`.
150 fn has_tracked_dir( 74 fn has_tracked_dir(
328 filename: &HgPath, 252 filename: &HgPath,
329 ) -> Result<(), DirstateError> { 253 ) -> Result<(), DirstateError> {
330 self.drop_entry_and_copy_source(filename) 254 self.drop_entry_and_copy_source(filename)
331 } 255 }
332 256
333 fn non_normal_entries_contains(
334 &mut self,
335 key: &HgPath,
336 ) -> Result<bool, DirstateV2ParseError> {
337 let (non_normal, _other_parent) =
338 self.get_non_normal_other_parent_entries();
339 Ok(non_normal.contains(key))
340 }
341
342 fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool {
343 self.non_normal_entries_remove(key)
344 }
345
346 fn non_normal_entries_add(&mut self, key: &HgPath) {
347 self.non_normal_entries_add(key)
348 }
349
350 fn non_normal_or_other_parent_paths(
351 &mut self,
352 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>
353 {
354 let (non_normal, other_parent) =
355 self.get_non_normal_other_parent_entries();
356 Box::new(non_normal.union(other_parent).map(|p| Ok(&**p)))
357 }
358
359 fn set_non_normal_other_parent_entries(&mut self, force: bool) {
360 self.set_non_normal_other_parent_entries(force)
361 }
362
363 fn iter_non_normal_paths(
364 &mut self,
365 ) -> Box<
366 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
367 > {
368 let (non_normal, _other_parent) =
369 self.get_non_normal_other_parent_entries();
370 Box::new(non_normal.iter().map(|p| Ok(&**p)))
371 }
372
373 fn iter_non_normal_paths_panic(
374 &self,
375 ) -> Box<
376 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
377 > {
378 let (non_normal, _other_parent) =
379 self.get_non_normal_other_parent_entries_panic();
380 Box::new(non_normal.iter().map(|p| Ok(&**p)))
381 }
382
383 fn iter_other_parent_paths(
384 &mut self,
385 ) -> Box<
386 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
387 > {
388 let (_non_normal, other_parent) =
389 self.get_non_normal_other_parent_entries();
390 Box::new(other_parent.iter().map(|p| Ok(&**p)))
391 }
392
393 fn has_tracked_dir( 257 fn has_tracked_dir(
394 &mut self, 258 &mut self,
395 directory: &HgPath, 259 directory: &HgPath,
396 ) -> Result<bool, DirstateError> { 260 ) -> Result<bool, DirstateError> {
397 self.has_tracked_dir(directory) 261 self.has_tracked_dir(directory)
404 fn pack_v1( 268 fn pack_v1(
405 &mut self, 269 &mut self,
406 parents: DirstateParents, 270 parents: DirstateParents,
407 now: Timestamp, 271 now: Timestamp,
408 ) -> Result<Vec<u8>, DirstateError> { 272 ) -> Result<Vec<u8>, DirstateError> {
409 self.pack(parents, now) 273 Ok(self.pack(parents, now)?)
410 } 274 }
411 275
412 fn pack_v2( 276 fn pack_v2(
413 &mut self, 277 &mut self,
414 _now: Timestamp, 278 _now: Timestamp,