From 88018e84fc1963d4317d2ffeeb8d27a115217f2b Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sun, 11 Aug 2024 13:06:15 +0900 Subject: [PATCH] merged_tree: micro-optimize Merge entries iterator to return &TreeValue try_resolve_file_conflict() is also updated. It could be a generic function, but there are only two callers, and the legacy tree one is used only in tests. --- lib/src/merged_tree.rs | 12 ++++++------ lib/src/tree.rs | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/src/merged_tree.rs b/lib/src/merged_tree.rs index a64572304e..e47ea3b071 100644 --- a/lib/src/merged_tree.rs +++ b/lib/src/merged_tree.rs @@ -389,7 +389,7 @@ fn all_tree_entries( /// than `tree.entries_non_recursive()`. fn all_merged_tree_entries( trees: &Merge, -) -> impl Iterator { +) -> impl Iterator>)> { let mut entries_iters = trees .iter() .map(|tree| tree.entries_non_recursive().peekable()) @@ -404,7 +404,7 @@ fn all_merged_tree_entries( .iter_mut() .map(|iter| { let entry = iter.next_if(|entry| entry.name() == next_name)?; - Some(entry.value().clone()) + Some(entry.value()) }) .collect(); Some((next_name, values.build())) @@ -456,7 +456,7 @@ fn merge_trees(merge: &Merge) -> BackendResult> { let mut conflicts = vec![]; for (basename, path_merge) in all_merged_tree_entries(merge) { let path = dir.join(basename); - let path_merge = merge_tree_values(store, &path, path_merge)?; + let path_merge = merge_tree_values(store, &path, &path_merge)?; match path_merge.into_resolved() { Ok(value) => { new_tree.set_or_remove(basename, value); @@ -493,10 +493,10 @@ fn merge_trees(merge: &Merge) -> BackendResult> { fn merge_tree_values( store: &Arc, path: &RepoPath, - values: MergedTreeValue, + values: &Merge>, ) -> BackendResult { if let Some(resolved) = values.resolve_trivial() { - return Ok(Merge::resolved(resolved.clone())); + return Ok(Merge::resolved(resolved.cloned())); } if let Some(trees) = values.to_tree_merge(store, path)? { @@ -517,7 +517,7 @@ fn merge_tree_values( Ok(Merge::normal(resolved)) } else { // Failed to merge the files, or the paths are not files - Ok(values) + Ok(values.map(|value| value.cloned())) } } } diff --git a/lib/src/tree.rs b/lib/src/tree.rs index 75066144ca..3fa14d0227 100644 --- a/lib/src/tree.rs +++ b/lib/src/tree.rs @@ -28,7 +28,7 @@ use crate::backend::{ }; use crate::files::MergeResult; use crate::matchers::{EverythingMatcher, Matcher}; -use crate::merge::{trivial_merge, Merge, MergedTreeValue}; +use crate::merge::{trivial_merge, Merge}; use crate::object_id::ObjectId; use crate::repo_path::{RepoPath, RepoPathBuf, RepoPathComponent}; use crate::store::Store; @@ -382,8 +382,9 @@ fn merge_tree_value( match merge.into_resolved() { Ok(value) => value, Err(conflict) => { + let conflict_borrowed = conflict.map(|value| value.as_ref()); if let Some(tree_value) = - try_resolve_file_conflict(store, &filename, &conflict)? + try_resolve_file_conflict(store, &filename, &conflict_borrowed)? { Some(tree_value) } else { @@ -403,7 +404,7 @@ fn merge_tree_value( pub fn try_resolve_file_conflict( store: &Store, filename: &RepoPath, - conflict: &MergedTreeValue, + conflict: &Merge>, ) -> BackendResult> { // If there are any non-file or any missing parts in the conflict, we can't // merge it. We check early so we don't waste time reading file contents if