Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/revlog/index.rs @ 51237:9f876765cbe2
rust-index: add support for `headrevsfiltered`
The implementation is merged with that of `headrevs` also to make sure that
caches are up to date.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Mon, 30 Oct 2023 11:14:25 +0100 |
parents | a7bba7df9189 |
children | 0112803e6c01 |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/index.rs Tue Sep 19 15:21:43 2023 +0200 +++ b/rust/hg-core/src/revlog/index.rs Mon Oct 30 11:14:25 2023 +0100 @@ -263,6 +263,9 @@ /// Cache of the head revisions in this index, kept in sync. Should /// be accessed via the [`Self::head_revs`] method. head_revs: Vec<Revision>, + /// Cache of the last filtered revisions in this index, used to make sure + /// we haven't changed filters when returning the cached `head_revs`. + filtered_revs: HashSet<Revision>, } impl Debug for Index { @@ -363,6 +366,7 @@ uses_generaldelta, is_inline: true, head_revs: vec![], + filtered_revs: HashSet::new(), }) } else { Err(HgError::corrupted("unexpected inline revlog length")) @@ -374,6 +378,7 @@ uses_generaldelta, is_inline: false, head_revs: vec![], + filtered_revs: HashSet::new(), }) } } @@ -520,13 +525,36 @@ /// Return the head revisions of this index pub fn head_revs(&mut self) -> Result<Vec<Revision>, GraphError> { - if !self.head_revs.is_empty() { + self.head_revs_filtered(&HashSet::new()) + } + + /// Return the head revisions of this index + pub fn head_revs_filtered( + &mut self, + filtered_revs: &HashSet<Revision>, + ) -> Result<Vec<Revision>, GraphError> { + if !self.head_revs.is_empty() && filtered_revs == &self.filtered_revs { return Ok(self.head_revs.to_owned()); } - let mut revs: HashSet<Revision, RandomState> = (0..self.len()) - .into_iter() - .map(|i| Revision(i as BaseRevision)) - .collect(); + 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); @@ -535,6 +563,7 @@ revs.into_iter().map(Into::into).collect(); as_vec.sort_unstable(); self.head_revs = as_vec.to_owned(); + self.filtered_revs = filtered_revs.to_owned(); Ok(as_vec) }