Mercurial > hg
diff rust/hg-core/src/revlog/index.rs @ 51259:ed6683d4cb29
rust-index: implement faster retain heads using a vec instead of a hashset
This is the same optimization that the C index does, we're only catching up
now because this showed up as slow in benchmarking.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 29 Nov 2023 10:04:41 -0500 |
parents | e74dd6d73cb5 |
children | c4f1a790bda8 |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/index.rs Thu Dec 14 11:52:05 2023 +0100 +++ b/rust/hg-core/src/revlog/index.rs Wed Nov 29 10:04:41 2023 -0500 @@ -1,4 +1,3 @@ -use std::collections::hash_map::RandomState; use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::ops::Deref; @@ -565,32 +564,24 @@ return Ok(self_head_revs.to_owned()); } } - let mut revs: HashSet<Revision, RandomState> = - if filtered_revs.is_empty() { - (0..self.len()) - .into_iter() - .map(|i| Revision(i as BaseRevision)) - .collect() - } else { - (0..self.len()) - .into_iter() - .filter_map(|i| { - let r = Revision(i as BaseRevision); - if filtered_revs.contains(&r) { - None - } else { - Some(r) - } - }) - .collect() - }; - dagops::retain_heads(self, &mut revs)?; - if self.is_empty() { - revs.insert(NULL_REVISION); - } - let mut as_vec: Vec<Revision> = - revs.into_iter().map(Into::into).collect(); - as_vec.sort_unstable(); + + let as_vec = if self.is_empty() { + vec![NULL_REVISION] + } else { + let mut not_heads = vec![false; self.len()]; + dagops::retain_heads_fast(self, &mut not_heads, filtered_revs)?; + not_heads + .into_iter() + .enumerate() + .filter_map(|(idx, is_not_head)| { + if is_not_head { + None + } else { + Some(Revision(idx as BaseRevision)) + } + }) + .collect() + }; *self .head_revs .write()