diff --git a/lib/src/default_index/composite.rs b/lib/src/default_index/composite.rs index eda60436e81..5506cee192e 100644 --- a/lib/src/default_index/composite.rs +++ b/lib/src/default_index/composite.rs @@ -96,6 +96,8 @@ impl AsCompositeIndex for &mut T { } /// Reference wrapper that provides global access to nested index segments. +/// We refer to this as a composite index because it implements an index of both +/// commit IDs and change IDs. #[derive(Clone, Copy)] pub struct CompositeIndex<'a>(&'a dyn IndexSegment); @@ -359,6 +361,8 @@ impl<'a> CompositeIndex<'a> { .map(|(i, _)| IndexPosition(u32::try_from(i).unwrap())) } + /// Returns the subset of positions in `candidate_positions` which refer to + /// entries that are heads in the repository. pub fn heads_pos( &self, mut candidate_positions: BTreeSet, @@ -410,12 +414,6 @@ impl AsCompositeIndex for CompositeIndex<'_> { } 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) @@ -478,7 +476,6 @@ impl Index for CompositeIndex<'_> { .collect() } - /// Parents before children 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()); @@ -514,9 +511,6 @@ impl ChangeIdIndexImpl { } impl ChangeIdIndex for ChangeIdIndexImpl { - /// Resolves change id prefix among all ids, then filters out hidden - /// entries. - /// /// If `SingleMatch` is returned, the commits including in the set are all /// visible. `AmbiguousMatch` may be returned even if the prefix is unique /// within the visible entries. @@ -543,11 +537,6 @@ impl ChangeIdIndex for ChangeIdIndexImpl { } } - /// Calculates the shortest prefix length of the given `change_id` among all - /// ids including hidden entries. - /// - /// The returned length is usually a few digits longer than the minimum - /// length to disambiguate within the visible entries. fn shortest_unique_prefix_len(&self, change_id: &ChangeId) -> usize { self.index .as_composite() diff --git a/lib/src/default_index/mod.rs b/lib/src/default_index/mod.rs index f52af70f435..4134cefaaea 100644 --- a/lib/src/default_index/mod.rs +++ b/lib/src/default_index/mod.rs @@ -12,6 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Implements an index of the commits in a repository conforms to the +//! [`crate::index::Index`] trait. The index is stored on local disk and +//! contains an entry for every commit in the repository. See +//! [`DefaultReadonlyIndex`] and [`DefaultMutableIndex`]. + #![allow(missing_docs)] mod composite; diff --git a/lib/src/index.rs b/lib/src/index.rs index 28dc6d9e4f3..df898d0522c 100644 --- a/lib/src/index.rs +++ b/lib/src/index.rs @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![allow(missing_docs)] +//! Traits and Error types for working with indexes of the commits in a +//! repository. use std::any::Any; use std::fmt::Debug; @@ -28,33 +29,42 @@ use crate::operation::Operation; use crate::revset::{ResolvedExpression, Revset, RevsetEvaluationError}; use crate::store::Store; -/// Error while reading index from the `IndexStore`. +/// Returned if an error occurs while reading an index from the [`IndexStore`]. #[derive(Debug, Error)] #[error(transparent)] pub struct IndexReadError(pub Box); -/// Error while writing index to the `IndexStore`. +/// Returned if an error occurs while writing an index to the [`IndexStore`]. #[derive(Debug, Error)] #[error(transparent)] pub struct IndexWriteError(pub Box); -/// Error to be returned if `Index::all_heads_for_gc()` is not supported by the +/// An error returned if `Index::all_heads_for_gc()` is not supported by the /// index backend. #[derive(Debug, Error)] #[error("Cannot collect all heads by index of this type")] pub struct AllHeadsForGcUnsupported; +/// Defines the interface for types that provide persistent storage for an +/// index. pub trait IndexStore: Send + Sync + Debug { + #[allow(missing_docs)] fn as_any(&self) -> &dyn Any; + /// Returns a name representing the type of index that the `IndexStore` is + /// compatible with. For example, the `IndexStore` for the default index + /// returns "default". fn name(&self) -> &str; + /// Returns the index at the specified operation. fn get_index_at_op( &self, op: &Operation, store: &Arc, ) -> Result, IndexReadError>; + /// Writes `index` to the index store and returns a read-only version of the + /// index. fn write_index( &self, index: Box, @@ -62,15 +72,30 @@ pub trait IndexStore: Send + Sync + Debug { ) -> Result, IndexWriteError>; } +/// Defines the interface for types that provide an index of the commits in a +/// repository by [`CommitId`]. pub trait Index: Send + Sync { + /// Returns the minimum prefix length to disambiguate `commit_id` from other + /// commits in the index. The length returned is the number of hexadecimal + /// digits in the minimum prefix. + /// + /// If the given `commit_id` doesn't exist, zero is returned since a prefix + /// length of zero never matches any commit id. fn shortest_unique_commit_id_prefix_len(&self, commit_id: &CommitId) -> usize; + /// Searches the index for commit IDs matching `prefix`. Returns a + /// [`PrefixResolution`] with a [`CommitId`] if the prefix matches a single + /// commit. fn resolve_commit_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution; + /// Returns true if `commit_id` is present in the index. fn has_id(&self, commit_id: &CommitId) -> bool; + /// Returns true if `ancestor_id` commit is an ancestor of the + /// `descendant_id` commit. fn is_ancestor(&self, ancestor_id: &CommitId, descendant_id: &CommitId) -> bool; + /// Returns the common ancestors of the commits in `set1` and `set2`. fn common_ancestors(&self, set1: &[CommitId], set2: &[CommitId]) -> Vec; /// Heads among all indexed commits at the associated operation. @@ -85,11 +110,18 @@ pub trait Index: Send + Sync { &self, ) -> Result + '_>, AllHeadsForGcUnsupported>; + /// Returns the subset of commit IDs in `candidates` which are heads in the + /// repository. If a commit id is duplicated in the `candidates` list it + /// will appear at most once in the output. fn heads(&self, candidates: &mut dyn Iterator) -> Vec; - /// Parents before children + /// Sorts a list of commit IDs in topological order where parent commits + /// appear before their children. Commit IDs in the `input` are not + /// deduplicated. fn topo_order(&self, input: &mut dyn Iterator) -> Vec; + /// Resolves the revset `expression` against the index and corresponding + /// `store`. fn evaluate_revset<'index>( &'index self, expression: &ResolvedExpression, @@ -97,6 +129,7 @@ pub trait Index: Send + Sync { ) -> Result, RevsetEvaluationError>; } +#[allow(missing_docs)] pub trait ReadonlyIndex: Send + Sync { fn as_any(&self) -> &dyn Any; @@ -108,6 +141,7 @@ pub trait ReadonlyIndex: Send + Sync { fn start_modification(&self) -> Box; } +#[allow(missing_docs)] pub trait MutableIndex { fn as_any(&self) -> &dyn Any; @@ -125,8 +159,11 @@ pub trait MutableIndex { fn merge_in(&mut self, other: &dyn ReadonlyIndex); } +/// Defines the interface for types that provide an index of the commits in a +/// repository by [`ChangeId`]. pub trait ChangeIdIndex: Send + Sync { - /// Resolve an unambiguous change ID prefix to the commit IDs in the index. + /// Resolve an unambiguous change ID prefix to the visible commit IDs in the + /// index. /// /// The order of the returned commit IDs is unspecified. fn resolve_prefix(&self, prefix: &HexPrefix) -> PrefixResolution>;