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: refactor maybe_squash_with_ancestors() #2739

Merged
merged 2 commits into from
Dec 23, 2023
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
8 changes: 6 additions & 2 deletions lib/src/default_index/composite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,16 @@ impl<'a> CompositeIndex<'a> {
CompositeIndex(segment)
}

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

fn ancestor_index_segments(&self) -> impl Iterator<Item = &'a dyn IndexSegment> {
/// 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(
self.ancestor_files_without_local()
.map(|file| file.as_ref() as &dyn IndexSegment),
Expand Down
49 changes: 21 additions & 28 deletions lib/src/default_index/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,33 +240,27 @@ impl MutableIndexSegment {
fn maybe_squash_with_ancestors(self) -> MutableIndexSegment {
let mut num_new_commits = self.segment_num_commits();
let mut files_to_squash = vec![];
let mut maybe_parent_file = self.parent_file.clone();
let mut squashed;
loop {
match maybe_parent_file {
Some(parent_file) => {
// TODO: We should probably also squash if the parent file has less than N
// commits, regardless of how many (few) are in `self`.
if 2 * num_new_commits < parent_file.segment_num_commits() {
squashed = MutableIndexSegment::incremental(parent_file);
break;
}
num_new_commits += parent_file.segment_num_commits();
files_to_squash.push(parent_file.clone());
maybe_parent_file = parent_file.segment_parent_file().cloned();
}
None => {
squashed =
MutableIndexSegment::full(self.commit_id_length, self.change_id_length);
break;
}
let mut base_parent_file = None;
for parent_file in self.as_composite().ancestor_files_without_local() {
// TODO: We should probably also squash if the parent file has less than N
// commits, regardless of how many (few) are in `self`.
if 2 * num_new_commits < parent_file.segment_num_commits() {
base_parent_file = Some(parent_file.clone());
break;
}
num_new_commits += parent_file.segment_num_commits();
files_to_squash.push(parent_file.clone());
}

if files_to_squash.is_empty() {
return self;
}

let mut squashed = if let Some(parent_file) = base_parent_file {
MutableIndexSegment::incremental(parent_file)
} else {
MutableIndexSegment::full(self.commit_id_length, self.change_id_length)
};
for parent_file in files_to_squash.iter().rev() {
squashed.add_commits_from(parent_file.as_ref());
}
Expand All @@ -279,11 +273,10 @@ impl MutableIndexSegment {
return Ok(self.parent_file.unwrap());
}

let squashed = self.maybe_squash_with_ancestors();
let mut buf = Vec::new();
squashed.serialize_parent_filename(&mut buf);
self.serialize_parent_filename(&mut buf);
let local_entries_offset = buf.len();
squashed.serialize_local_entries(&mut buf);
self.serialize_local_entries(&mut buf);
let mut hasher = Blake2b512::new();
hasher.update(&buf);
let index_file_id_hex = hex::encode(hasher.finalize());
Expand All @@ -297,9 +290,9 @@ impl MutableIndexSegment {
Ok(ReadonlyIndexSegment::load_with_parent_file(
&mut &buf[local_entries_offset..],
index_file_id_hex,
squashed.parent_file,
squashed.commit_id_length,
squashed.change_id_length,
self.parent_file,
self.commit_id_length,
self.change_id_length,
)
.expect("in-memory index data should be valid and readable"))
}
Expand Down Expand Up @@ -411,8 +404,8 @@ impl DefaultMutableIndex {
self.0.add_commit_data(commit_id, change_id, parent_ids);
}

pub(super) fn save_in(self, dir: &Path) -> io::Result<Arc<ReadonlyIndexSegment>> {
self.0.save_in(dir)
pub(super) fn squash_and_save_in(self, dir: &Path) -> io::Result<Arc<ReadonlyIndexSegment>> {
self.0.maybe_squash_with_ancestors().save_in(dir)
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/src/default_index/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl DefaultIndexStore {
op_id: &OperationId,
) -> Result<Arc<ReadonlyIndexSegment>, DefaultIndexStoreError> {
let index_segment = mutable_index
.save_in(&self.dir)
.squash_and_save_in(&self.dir)
.map_err(DefaultIndexStoreError::SaveIndex)?;
self.associate_file_with_operation(&index_segment, op_id)
.map_err(|source| DefaultIndexStoreError::AssociateIndex {
Expand Down