Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

index: turn CompositeIndex into transparent reference type #3269

Merged
merged 4 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions lib/src/default_index/composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::iter;
use std::sync::{Arc, Mutex};

use itertools::Itertools;
use ref_cast::{ref_cast_custom, RefCastCustom};

use super::entry::{
IndexEntry, IndexPosition, IndexPositionByGeneration, LocalPosition, SmallIndexPositionsVec,
Expand Down Expand Up @@ -76,47 +77,49 @@ pub(super) trait IndexSegment: Send + Sync {
fn parent_positions(&self, local_pos: LocalPosition) -> SmallIndexPositionsVec;
}

pub(super) type DynIndexSegment = dyn IndexSegment;

/// Abstraction over owned and borrowed types that can be cheaply converted to
/// a `CompositeIndex` reference.
pub trait AsCompositeIndex {
/// Returns reference wrapper that provides global access to this index.
fn as_composite(&self) -> CompositeIndex<'_>;
fn as_composite(&self) -> &CompositeIndex;
}

impl<T: AsCompositeIndex + ?Sized> AsCompositeIndex for &T {
fn as_composite(&self) -> CompositeIndex<'_> {
fn as_composite(&self) -> &CompositeIndex {
<T as AsCompositeIndex>::as_composite(self)
}
}

impl<T: AsCompositeIndex + ?Sized> AsCompositeIndex for &mut T {
fn as_composite(&self) -> CompositeIndex<'_> {
fn as_composite(&self) -> &CompositeIndex {
<T as AsCompositeIndex>::as_composite(self)
}
}

/// Reference wrapper that provides global access to nested index segments.
#[derive(Clone, Copy)]
pub struct CompositeIndex<'a>(&'a dyn IndexSegment);
#[derive(RefCastCustom)]
#[repr(transparent)]
pub struct CompositeIndex(DynIndexSegment);

impl<'a> CompositeIndex<'a> {
pub(super) fn new(segment: &'a dyn IndexSegment) -> Self {
CompositeIndex(segment)
}
impl CompositeIndex {
#[ref_cast_custom]
pub(super) const fn new(segment: &DynIndexSegment) -> &Self;

/// Iterates parent and its ancestor readonly index segments.
pub(super) fn ancestor_files_without_local(
&self,
) -> impl Iterator<Item = &'a Arc<ReadonlyIndexSegment>> {
) -> impl Iterator<Item = &Arc<ReadonlyIndexSegment>> {
let parent_file = self.0.parent_file();
iter::successors(parent_file, |file| file.parent_file())
}

/// Iterates self and its ancestor index segments.
pub(super) fn ancestor_index_segments(&self) -> impl Iterator<Item = &'a dyn IndexSegment> {
iter::once(self.0).chain(
pub(super) fn ancestor_index_segments(&self) -> impl Iterator<Item = &DynIndexSegment> {
iter::once(&self.0).chain(
self.ancestor_files_without_local()
.map(|file| file.as_ref() as &dyn IndexSegment),
.map(|file| file.as_ref() as &DynIndexSegment),
)
}

Expand Down Expand Up @@ -158,7 +161,7 @@ impl<'a> CompositeIndex<'a> {
}
}

pub fn entry_by_pos(&self, pos: IndexPosition) -> IndexEntry<'a> {
pub fn entry_by_pos(&self, pos: IndexPosition) -> IndexEntry<'_> {
self.ancestor_index_segments()
.find_map(|segment| {
u32::checked_sub(pos.0, segment.num_parent_commits())
Expand All @@ -167,7 +170,7 @@ impl<'a> CompositeIndex<'a> {
.unwrap()
}

pub fn entry_by_id(&self, commit_id: &CommitId) -> Option<IndexEntry<'a>> {
pub fn entry_by_id(&self, commit_id: &CommitId) -> Option<IndexEntry<'_>> {
self.ancestor_index_segments().find_map(|segment| {
let local_pos = segment.commit_id_to_pos(commit_id)?;
let pos = IndexPosition(local_pos.0 + segment.num_parent_commits());
Expand Down Expand Up @@ -330,7 +333,7 @@ impl<'a> CompositeIndex<'a> {
self.heads_pos(result)
}

pub(super) fn all_heads(self) -> impl Iterator<Item = CommitId> + 'a {
pub(super) fn all_heads(&self) -> impl Iterator<Item = CommitId> + '_ {
self.all_heads_pos()
.map(move |pos| self.entry_by_pos(pos).commit_id())
}
Expand Down Expand Up @@ -390,19 +393,20 @@ impl<'a> CompositeIndex<'a> {
&self,
expression: &ResolvedExpression,
store: &Arc<Store>,
) -> Result<Box<dyn Revset + 'a>, RevsetEvaluationError> {
let revset_impl = revset_engine::evaluate(expression, store, *self)?;
) -> Result<Box<dyn Revset + '_>, RevsetEvaluationError> {
let revset_impl = revset_engine::evaluate(expression, store, self)?;
Ok(Box::new(revset_impl))
}
}

impl AsCompositeIndex for CompositeIndex<'_> {
fn as_composite(&self) -> CompositeIndex<'_> {
*self
impl AsCompositeIndex for CompositeIndex {
fn as_composite(&self) -> &CompositeIndex {
self
}
}

impl Index for CompositeIndex<'_> {
// In revset engine, we need to convert &CompositeIndex to &dyn Index.
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.
Expand Down
6 changes: 3 additions & 3 deletions lib/src/default_index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::hash::{Hash, Hasher};

use smallvec::SmallVec;

use super::composite::{CompositeIndex, IndexSegment};
use super::composite::{CompositeIndex, DynIndexSegment};
use crate::backend::{ChangeId, CommitId};
use crate::object_id::ObjectId;

Expand All @@ -43,7 +43,7 @@ pub(super) type SmallLocalPositionsVec = SmallVec<[LocalPosition; 4]>;

#[derive(Clone)]
pub struct IndexEntry<'a> {
source: &'a dyn IndexSegment,
source: &'a DynIndexSegment,
pos: IndexPosition,
/// Position within the source segment
local_pos: LocalPosition,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl Hash for IndexEntry<'_> {

impl<'a> IndexEntry<'a> {
pub(super) fn new(
source: &'a dyn IndexSegment,
source: &'a DynIndexSegment,
pos: IndexPosition,
local_pos: LocalPosition,
) -> Self {
Expand Down
10 changes: 5 additions & 5 deletions lib/src/default_index/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ mod tests {
use smallvec::smallvec_inline;
use test_case::test_case;

use super::composite::IndexSegment;
use super::composite::{DynIndexSegment, IndexSegment};
use super::entry::SmallIndexPositionsVec;
use super::mutable::MutableIndexSegment;
use super::*;
Expand All @@ -63,7 +63,7 @@ mod tests {
fn index_empty(on_disk: bool) {
let temp_dir = testutils::new_temp_dir();
let mutable_segment = MutableIndexSegment::full(3, 16);
let index_segment: Box<dyn IndexSegment> = if on_disk {
let index_segment: Box<DynIndexSegment> = if on_disk {
let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
Box::new(Arc::try_unwrap(saved_index).unwrap())
} else {
Expand Down Expand Up @@ -94,7 +94,7 @@ mod tests {
let id_0 = CommitId::from_hex("000000");
let change_id0 = new_change_id();
mutable_segment.add_commit_data(id_0.clone(), change_id0.clone(), &[]);
let index_segment: Box<dyn IndexSegment> = if on_disk {
let index_segment: Box<DynIndexSegment> = if on_disk {
let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
Box::new(Arc::try_unwrap(saved_index).unwrap())
} else {
Expand Down Expand Up @@ -179,7 +179,7 @@ mod tests {
mutable_segment.add_commit_data(id_3.clone(), change_id3.clone(), &[id_2.clone()]);
mutable_segment.add_commit_data(id_4.clone(), change_id4, &[id_1.clone()]);
mutable_segment.add_commit_data(id_5.clone(), change_id5, &[id_4.clone(), id_2.clone()]);
let index_segment: Box<dyn IndexSegment> = if on_disk {
let index_segment: Box<DynIndexSegment> = if on_disk {
let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
Box::new(Arc::try_unwrap(saved_index).unwrap())
} else {
Expand Down Expand Up @@ -291,7 +291,7 @@ mod tests {
new_change_id(),
&[id_1, id_2, id_3, id_4, id_5],
);
let index_segment: Box<dyn IndexSegment> = if on_disk {
let index_segment: Box<DynIndexSegment> = if on_disk {
let saved_index = mutable_segment.save_in(temp_dir.path()).unwrap();
Box::new(Arc::try_unwrap(saved_index).unwrap())
} else {
Expand Down
10 changes: 6 additions & 4 deletions lib/src/default_index/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ use itertools::Itertools;
use smallvec::{smallvec, SmallVec};
use tempfile::NamedTempFile;

use super::composite::{AsCompositeIndex, ChangeIdIndexImpl, CompositeIndex, IndexSegment};
use super::composite::{
AsCompositeIndex, ChangeIdIndexImpl, CompositeIndex, DynIndexSegment, IndexSegment,
};
use super::entry::{IndexPosition, LocalPosition, SmallIndexPositionsVec, SmallLocalPositionsVec};
use super::readonly::{
DefaultReadonlyIndex, ReadonlyIndexSegment, INDEX_SEGMENT_FILE_FORMAT_VERSION, OVERFLOW_FLAG,
Expand Down Expand Up @@ -88,7 +90,7 @@ impl MutableIndexSegment {
}
}

pub(super) fn as_composite(&self) -> CompositeIndex {
pub(super) fn as_composite(&self) -> &CompositeIndex {
CompositeIndex::new(self)
}

Expand Down Expand Up @@ -137,7 +139,7 @@ impl MutableIndexSegment {
self.graph.push(entry);
}

pub(super) fn add_commits_from(&mut self, other_segment: &dyn IndexSegment) {
pub(super) fn add_commits_from(&mut self, other_segment: &DynIndexSegment) {
let other = CompositeIndex::new(other_segment);
for pos in other_segment.num_parent_commits()..other.num_commits() {
let entry = other.entry_by_pos(IndexPosition(pos));
Expand Down Expand Up @@ -465,7 +467,7 @@ impl DefaultMutableIndex {
}

impl AsCompositeIndex for DefaultMutableIndex {
fn as_composite(&self) -> CompositeIndex<'_> {
fn as_composite(&self) -> &CompositeIndex {
self.0.as_composite()
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/default_index/readonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ impl ReadonlyIndexSegment {
}))
}

pub(super) fn as_composite(&self) -> CompositeIndex {
pub(super) fn as_composite(&self) -> &CompositeIndex {
CompositeIndex::new(self)
}

Expand Down Expand Up @@ -570,7 +570,7 @@ impl DefaultReadonlyIndex {
}

impl AsCompositeIndex for DefaultReadonlyIndex {
fn as_composite(&self) -> CompositeIndex<'_> {
fn as_composite(&self) -> &CompositeIndex {
self.0.as_composite()
}
}
Expand Down
36 changes: 17 additions & 19 deletions lib/src/default_index/rev_walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ pub(super) trait RevWalk<I: ?Sized> {
// to be reimplemented.

/// Reattaches the underlying `index`.
fn attach(self, index: I) -> RevWalkBorrowedIndexIter<I, Self>
fn attach(self, index: &I) -> RevWalkBorrowedIndexIter<'_, I, Self>
where
Self: Sized,
I: Sized,
{
RevWalkBorrowedIndexIter { index, walk: self }
}
Expand All @@ -52,28 +51,27 @@ pub(super) trait RevWalk<I: ?Sized> {
/// Adapter that turns `RevWalk` into `Iterator` by attaching borrowed `index`.
#[derive(Clone, Debug)]
#[must_use]
pub(super) struct RevWalkBorrowedIndexIter<I, W> {
// TODO: `index: I` will be a reference type.
index: I,
pub(super) struct RevWalkBorrowedIndexIter<'a, I: ?Sized, W> {
index: &'a I,
walk: W,
}

impl<I, W> RevWalkBorrowedIndexIter<I, W> {
impl<I: ?Sized, W> RevWalkBorrowedIndexIter<'_, I, W> {
/// Turns into `'static`-lifetime walk object by detaching the index.
pub fn detach(self) -> W {
self.walk
}
}

impl<I, W: RevWalk<I>> Iterator for RevWalkBorrowedIndexIter<I, W> {
impl<I: ?Sized, W: RevWalk<I>> Iterator for RevWalkBorrowedIndexIter<'_, I, W> {
type Item = W::Item;

fn next(&mut self) -> Option<Self::Item> {
self.walk.next(&self.index)
self.walk.next(self.index)
}
}

impl<I, W: RevWalk<I>> FusedIterator for RevWalkBorrowedIndexIter<I, W> {}
impl<I: ?Sized, W: RevWalk<I>> FusedIterator for RevWalkBorrowedIndexIter<'_, I, W> {}

/// Adapter that turns `RevWalk` into `Iterator` by attaching owned `index`.
#[derive(Clone, Debug)]
Expand All @@ -100,7 +98,7 @@ pub(super) trait RevWalkIndex {
fn adjacent_positions(&self, pos: Self::Position) -> Self::AdjacentPositions;
}

impl RevWalkIndex for CompositeIndex<'_> {
impl RevWalkIndex for CompositeIndex {
type Position = IndexPosition;
type AdjacentPositions = SmallIndexPositionsVec;

Expand All @@ -118,7 +116,7 @@ pub(super) struct RevWalkDescendantsIndex {
type DescendantIndexPositionsVec = SmallVec<[Reverse<IndexPosition>; 4]>;

impl RevWalkDescendantsIndex {
fn build(index: CompositeIndex, positions: impl IntoIterator<Item = IndexPosition>) -> Self {
fn build(index: &CompositeIndex, positions: impl IntoIterator<Item = IndexPosition>) -> Self {
// For dense set, it's probably cheaper to use `Vec` instead of `HashMap`.
let mut children_map: HashMap<IndexPosition, DescendantIndexPositionsVec> = HashMap::new();
for pos in positions {
Expand Down Expand Up @@ -242,13 +240,13 @@ impl<P: Ord, T: Ord> RevWalkQueue<P, T> {
#[derive(Clone)]
#[must_use]
pub(super) struct RevWalkBuilder<'a> {
index: CompositeIndex<'a>,
index: &'a CompositeIndex,
wanted: Vec<IndexPosition>,
unwanted: Vec<IndexPosition>,
}

impl<'a> RevWalkBuilder<'a> {
pub fn new(index: CompositeIndex<'a>) -> Self {
pub fn new(index: &'a CompositeIndex) -> Self {
RevWalkBuilder {
index,
wanted: Vec::new(),
Expand Down Expand Up @@ -383,7 +381,7 @@ impl<'a> RevWalkBuilder<'a> {
}

pub(super) type RevWalkAncestors<'a> =
RevWalkBorrowedIndexIter<CompositeIndex<'a>, RevWalkImpl<IndexPosition>>;
RevWalkBorrowedIndexIter<'a, CompositeIndex, RevWalkImpl<IndexPosition>>;

#[derive(Clone)]
#[must_use]
Expand Down Expand Up @@ -420,7 +418,7 @@ impl<I: RevWalkIndex + ?Sized> RevWalk<I> for RevWalkImpl<I::Position> {
}

pub(super) type RevWalkAncestorsGenerationRange<'a> =
RevWalkBorrowedIndexIter<CompositeIndex<'a>, RevWalkGenerationRangeImpl<IndexPosition>>;
RevWalkBorrowedIndexIter<'a, CompositeIndex, RevWalkGenerationRangeImpl<IndexPosition>>;
pub(super) type RevWalkDescendantsGenerationRange = RevWalkOwnedIndexIter<
RevWalkDescendantsIndex,
RevWalkGenerationRangeImpl<Reverse<IndexPosition>>,
Expand Down Expand Up @@ -540,7 +538,7 @@ impl RevWalkItemGenerationRange {

/// Walks descendants from the roots, in order of ascending index position.
pub(super) type RevWalkDescendants<'a> =
RevWalkBorrowedIndexIter<CompositeIndex<'a>, RevWalkDescendantsImpl>;
RevWalkBorrowedIndexIter<'a, CompositeIndex, RevWalkDescendantsImpl>;

#[derive(Clone)]
#[must_use]
Expand All @@ -561,7 +559,7 @@ impl RevWalkDescendants<'_> {
}
}

impl RevWalk<CompositeIndex<'_>> for RevWalkDescendantsImpl {
impl RevWalk<CompositeIndex> for RevWalkDescendantsImpl {
type Item = IndexPosition;

fn next(&mut self, index: &CompositeIndex) -> Option<Self::Item> {
Expand Down Expand Up @@ -626,7 +624,7 @@ impl AncestorsBitSet {
}

/// Updates set by visiting ancestors until the given `to_visit_pos`.
pub fn visit_until(&mut self, index: CompositeIndex, to_visit_pos: IndexPosition) {
pub fn visit_until(&mut self, index: &CompositeIndex, to_visit_pos: IndexPosition) {
let to_visit_bitset_pos = to_visit_pos.0 / u64::BITS;
if to_visit_bitset_pos >= self.last_visited_bitset_pos {
return;
Expand Down Expand Up @@ -673,7 +671,7 @@ mod tests {
move || iter.next().unwrap()
}

fn to_positions_vec(index: CompositeIndex<'_>, commit_ids: &[CommitId]) -> Vec<IndexPosition> {
fn to_positions_vec(index: &CompositeIndex, commit_ids: &[CommitId]) -> Vec<IndexPosition> {
commit_ids
.iter()
.map(|id| index.commit_id_to_pos(id).unwrap())
Expand Down
Loading