diff --git a/lib/src/default_index_store.rs b/lib/src/default_index_store.rs index 3e28ad23b..27aa55a53 100644 --- a/lib/src/default_index_store.rs +++ b/lib/src/default_index_store.rs @@ -896,20 +896,6 @@ impl<'a> CompositeIndex<'a> { .find_map(|segment| segment.segment_commit_id_to_pos(commit_id)) } - /// Suppose the given `commit_id` exists, returns the minimum prefix length - /// to disambiguate it. The length to be returned is a number of hexadecimal - /// digits. - /// - /// If the given `commit_id` doesn't exist, this will return the prefix - /// length that never matches with any commit ids. - pub fn shortest_unique_commit_id_prefix_len(&self, commit_id: &CommitId) -> usize { - let (prev_id, next_id) = self.resolve_neighbor_commit_ids(commit_id); - itertools::chain(prev_id, next_id) - .map(|id| backend::common_hex_len(commit_id.as_bytes(), id.as_bytes()) + 1) - .max() - .unwrap_or(0) - } - /// Suppose the given `commit_id` exists, returns the previous and next /// commit ids in lexicographical order. fn resolve_neighbor_commit_ids( @@ -936,33 +922,11 @@ impl<'a> CompositeIndex<'a> { .unwrap() } - pub fn resolve_prefix(&self, prefix: &HexPrefix) -> PrefixResolution { - self.ancestor_index_segments() - .fold(PrefixResolution::NoMatch, |acc_match, segment| { - if acc_match == PrefixResolution::AmbiguousMatch { - acc_match // avoid checking the parent file(s) - } else { - let local_match = segment.segment_resolve_prefix(prefix); - acc_match.plus(&local_match) - } - }) - } - pub fn entry_by_id(&self, commit_id: &CommitId) -> Option> { self.commit_id_to_pos(commit_id) .map(|pos| self.entry_by_pos(pos)) } - pub fn has_id(&self, commit_id: &CommitId) -> bool { - self.commit_id_to_pos(commit_id).is_some() - } - - pub fn is_ancestor(&self, ancestor_id: &CommitId, descendant_id: &CommitId) -> bool { - let ancestor_pos = self.commit_id_to_pos(ancestor_id).unwrap(); - let descendant_pos = self.commit_id_to_pos(descendant_id).unwrap(); - self.is_ancestor_pos(ancestor_pos, descendant_pos) - } - fn is_ancestor_pos(&self, ancestor_pos: IndexPosition, descendant_pos: IndexPosition) -> bool { let ancestor_generation = self.entry_by_pos(ancestor_pos).generation_number(); let mut work = vec![descendant_pos]; @@ -983,21 +947,6 @@ impl<'a> CompositeIndex<'a> { false } - pub fn common_ancestors(&self, set1: &[CommitId], set2: &[CommitId]) -> Vec { - let pos1 = set1 - .iter() - .map(|id| self.commit_id_to_pos(id).unwrap()) - .collect_vec(); - let pos2 = set2 - .iter() - .map(|id| self.commit_id_to_pos(id).unwrap()) - .collect_vec(); - self.common_ancestors_pos(&pos1, &pos2) - .iter() - .map(|pos| self.entry_by_pos(*pos).commit_id()) - .collect() - } - fn common_ancestors_pos( &self, set1: &[IndexPosition], @@ -1056,20 +1005,6 @@ impl<'a> CompositeIndex<'a> { rev_walk } - pub(crate) fn heads( - &self, - candidate_ids: &mut dyn Iterator, - ) -> Vec { - let candidate_positions: BTreeSet<_> = candidate_ids - .map(|id| self.commit_id_to_pos(id).unwrap()) - .collect(); - - self.heads_pos(candidate_positions) - .iter() - .map(|pos| self.entry_by_pos(*pos).commit_id()) - .collect() - } - fn heads_pos( &self, mut candidate_positions: BTreeSet, @@ -1105,13 +1040,86 @@ impl<'a> CompositeIndex<'a> { } candidate_positions } +} + +impl Index for CompositeIndex<'_> { + /// Suppose the given `commit_id` exists, returns the minimum prefix length + /// to disambiguate it. The length to be returned is a number of hexadecimal + /// digits. + /// + /// If the given `commit_id` doesn't exist, this will return the prefix + /// length that never matches with any commit ids. + fn shortest_unique_commit_id_prefix_len(&self, commit_id: &CommitId) -> usize { + let (prev_id, next_id) = self.resolve_neighbor_commit_ids(commit_id); + itertools::chain(prev_id, next_id) + .map(|id| backend::common_hex_len(commit_id.as_bytes(), id.as_bytes()) + 1) + .max() + .unwrap_or(0) + } + + fn resolve_prefix(&self, prefix: &HexPrefix) -> PrefixResolution { + self.ancestor_index_segments() + .fold(PrefixResolution::NoMatch, |acc_match, segment| { + if acc_match == PrefixResolution::AmbiguousMatch { + acc_match // avoid checking the parent file(s) + } else { + let local_match = segment.segment_resolve_prefix(prefix); + acc_match.plus(&local_match) + } + }) + } + + fn has_id(&self, commit_id: &CommitId) -> bool { + self.commit_id_to_pos(commit_id).is_some() + } + + fn is_ancestor(&self, ancestor_id: &CommitId, descendant_id: &CommitId) -> bool { + let ancestor_pos = self.commit_id_to_pos(ancestor_id).unwrap(); + let descendant_pos = self.commit_id_to_pos(descendant_id).unwrap(); + self.is_ancestor_pos(ancestor_pos, descendant_pos) + } + + fn common_ancestors(&self, set1: &[CommitId], set2: &[CommitId]) -> Vec { + let pos1 = set1 + .iter() + .map(|id| self.commit_id_to_pos(id).unwrap()) + .collect_vec(); + let pos2 = set2 + .iter() + .map(|id| self.commit_id_to_pos(id).unwrap()) + .collect_vec(); + self.common_ancestors_pos(&pos1, &pos2) + .iter() + .map(|pos| self.entry_by_pos(*pos).commit_id()) + .collect() + } + + fn heads(&self, candidate_ids: &mut dyn Iterator) -> Vec { + let candidate_positions: BTreeSet<_> = candidate_ids + .map(|id| self.commit_id_to_pos(id).unwrap()) + .collect(); + + self.heads_pos(candidate_positions) + .iter() + .map(|pos| self.entry_by_pos(*pos).commit_id()) + .collect() + } /// Parents before children - pub fn topo_order(&self, input: &mut dyn Iterator) -> Vec { + fn topo_order(&self, input: &mut dyn Iterator) -> Vec { let mut ids = input.cloned().collect_vec(); ids.sort_by_cached_key(|id| self.commit_id_to_pos(id).unwrap()); ids } + + fn evaluate_revset<'index>( + &'index self, + expression: &ResolvedExpression, + store: &Arc, + ) -> Result + 'index>, RevsetEvaluationError> { + let revset_impl = default_revset_engine::evaluate(expression, store, self, *self)?; + Ok(Box::new(revset_impl)) + } } pub struct IndexLevelStats { diff --git a/lib/tests/test_index.rs b/lib/tests/test_index.rs index 95638d530..34b306855 100644 --- a/lib/tests/test_index.rs +++ b/lib/tests/test_index.rs @@ -18,6 +18,7 @@ use jujutsu_lib::backend::CommitId; use jujutsu_lib::commit::Commit; use jujutsu_lib::commit_builder::CommitBuilder; use jujutsu_lib::default_index_store::{CompositeIndex, MutableIndexImpl, ReadonlyIndexWrapper}; +use jujutsu_lib::index::Index as _; use jujutsu_lib::repo::{MutableRepo, ReadonlyRepo, Repo}; use jujutsu_lib::settings::UserSettings; use test_case::test_case;