Mercurial > hg
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 |