comparison rust/hg-core/src/discovery.rs @ 42744:c5748c6969b9

rust-discovery: optimization of add commons/missings for empty arguments These two cases have to be catched early for different reasons. In the case of add_missing_revisions, we don't want to trigger the computation of the undecided set (and the children cache) too early: the later the better. In the case of add_common_revisions, the inner `MissingAncestors` object wouldn't know that all ancestors of its bases have already been removed from the undecided. In principle, that would in itself be a lead for further improvement: this remove_ancestors_from could be more incremental, but the current performance seems to be good enough. Differential Revision: https://phab.mercurial-scm.org/D6429
author Georges Racinet on percheron.racinet.fr <georges@racinet.fr>
date Tue, 21 May 2019 12:46:38 +0200
parents 8c9a6adec67a
children 04c3b76fa7a3
comparison
equal deleted inserted replaced
42743:8c9a6adec67a 42744:c5748c6969b9
223 /// Register revisions known as being common 223 /// Register revisions known as being common
224 pub fn add_common_revisions( 224 pub fn add_common_revisions(
225 &mut self, 225 &mut self,
226 common: impl IntoIterator<Item = Revision>, 226 common: impl IntoIterator<Item = Revision>,
227 ) -> Result<(), GraphError> { 227 ) -> Result<(), GraphError> {
228 let before_len = self.common.get_bases().len();
228 self.common.add_bases(common); 229 self.common.add_bases(common);
230 if self.common.get_bases().len() == before_len {
231 return Ok(());
232 }
229 if let Some(ref mut undecided) = self.undecided { 233 if let Some(ref mut undecided) = self.undecided {
230 self.common.remove_ancestors_from(undecided)?; 234 self.common.remove_ancestors_from(undecided)?;
231 } 235 }
232 Ok(()) 236 Ok(())
233 } 237 }
244 /// caller should avoid calling this too early. 248 /// caller should avoid calling this too early.
245 pub fn add_missing_revisions( 249 pub fn add_missing_revisions(
246 &mut self, 250 &mut self,
247 missing: impl IntoIterator<Item = Revision>, 251 missing: impl IntoIterator<Item = Revision>,
248 ) -> Result<(), GraphError> { 252 ) -> Result<(), GraphError> {
253 let mut tovisit: VecDeque<Revision> = missing.into_iter().collect();
254 if tovisit.is_empty() {
255 return Ok(());
256 }
249 self.ensure_children_cache()?; 257 self.ensure_children_cache()?;
250 self.ensure_undecided()?; // for safety of possible future refactors 258 self.ensure_undecided()?; // for safety of possible future refactors
251 let children = self.children_cache.as_ref().unwrap(); 259 let children = self.children_cache.as_ref().unwrap();
252 let mut seen: HashSet<Revision> = HashSet::new(); 260 let mut seen: HashSet<Revision> = HashSet::new();
253 let mut tovisit: VecDeque<Revision> = missing.into_iter().collect();
254 let undecided_mut = self.undecided.as_mut().unwrap(); 261 let undecided_mut = self.undecided.as_mut().unwrap();
255 while let Some(rev) = tovisit.pop_front() { 262 while let Some(rev) = tovisit.pop_front() {
256 if !self.missing.insert(rev) { 263 if !self.missing.insert(rev) {
257 // either it's known to be missing from a previous 264 // either it's known to be missing from a previous
258 // invocation, and there's no need to iterate on its 265 // invocation, and there's no need to iterate on its