mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-01 00:50:57 +00:00
merged_tree: make TreeDiffIterator accept trees as &Merge<Tree>
For the same reason as the patch for TreeEntriesIterator. It's probably better to assume that MergedTree represents the root tree.
This commit is contained in:
parent
9378adedb7
commit
6fc7cec4a5
2 changed files with 34 additions and 29 deletions
|
@ -122,6 +122,11 @@ impl MergedTree {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the underlying `Merge<Tree>`.
|
||||||
|
pub fn as_merge(&self) -> &Merge<Tree> {
|
||||||
|
&self.trees
|
||||||
|
}
|
||||||
|
|
||||||
/// Extracts the underlying `Merge<Tree>`.
|
/// Extracts the underlying `Merge<Tree>`.
|
||||||
pub fn take(self) -> Merge<Tree> {
|
pub fn take(self) -> Merge<Tree> {
|
||||||
self.trees
|
self.trees
|
||||||
|
@ -281,7 +286,9 @@ impl MergedTree {
|
||||||
let concurrency = self.store().concurrency();
|
let concurrency = self.store().concurrency();
|
||||||
if concurrency <= 1 {
|
if concurrency <= 1 {
|
||||||
Box::pin(futures::stream::iter(TreeDiffIterator::new(
|
Box::pin(futures::stream::iter(TreeDiffIterator::new(
|
||||||
self, other, matcher,
|
&self.trees,
|
||||||
|
&other.trees,
|
||||||
|
matcher,
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Box::pin(TreeDiffStreamImpl::new(
|
Box::pin(TreeDiffStreamImpl::new(
|
||||||
|
@ -327,8 +334,8 @@ fn all_tree_basenames(trees: &Merge<Tree>) -> impl Iterator<Item = &RepoPathComp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merged_tree_basenames<'a>(
|
fn merged_tree_basenames<'a>(
|
||||||
tree1: &'a MergedTree,
|
trees1: &'a Merge<Tree>,
|
||||||
tree2: &'a MergedTree,
|
trees2: &'a Merge<Tree>,
|
||||||
) -> Box<dyn Iterator<Item = &'a RepoPathComponent> + 'a> {
|
) -> Box<dyn Iterator<Item = &'a RepoPathComponent> + 'a> {
|
||||||
fn merge_iters<'a>(
|
fn merge_iters<'a>(
|
||||||
iter1: impl Iterator<Item = &'a RepoPathComponent> + 'a,
|
iter1: impl Iterator<Item = &'a RepoPathComponent> + 'a,
|
||||||
|
@ -336,19 +343,16 @@ fn merged_tree_basenames<'a>(
|
||||||
) -> Box<dyn Iterator<Item = &'a RepoPathComponent> + 'a> {
|
) -> Box<dyn Iterator<Item = &'a RepoPathComponent> + 'a> {
|
||||||
Box::new(iter1.merge(iter2).dedup())
|
Box::new(iter1.merge(iter2).dedup())
|
||||||
}
|
}
|
||||||
merge_iters(
|
merge_iters(all_tree_basenames(trees1), all_tree_basenames(trees2))
|
||||||
all_tree_basenames(&tree1.trees),
|
|
||||||
all_tree_basenames(&tree2.trees),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merged_tree_entry_diff<'a>(
|
fn merged_tree_entry_diff<'a>(
|
||||||
before: &'a MergedTree,
|
before: &'a Merge<Tree>,
|
||||||
after: &'a MergedTree,
|
after: &'a Merge<Tree>,
|
||||||
) -> impl Iterator<Item = (&'a RepoPathComponent, MergedTreeVal<'a>, MergedTreeVal<'a>)> {
|
) -> impl Iterator<Item = (&'a RepoPathComponent, MergedTreeVal<'a>, MergedTreeVal<'a>)> {
|
||||||
merged_tree_basenames(before, after).filter_map(|basename| {
|
merged_tree_basenames(before, after).filter_map(|basename| {
|
||||||
let value_before = before.value(basename);
|
let value_before = trees_value(before, basename);
|
||||||
let value_after = after.value(basename);
|
let value_after = trees_value(after, basename);
|
||||||
(value_after != value_before).then_some((basename, value_before, value_after))
|
(value_after != value_before).then_some((basename, value_before, value_after))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -602,17 +606,17 @@ enum TreeDiffItem {
|
||||||
impl<'matcher> TreeDiffIterator<'matcher> {
|
impl<'matcher> TreeDiffIterator<'matcher> {
|
||||||
/// Creates a iterator over the differences between two trees. Generally
|
/// Creates a iterator over the differences between two trees. Generally
|
||||||
/// prefer `MergedTree::diff()` of calling this directly.
|
/// prefer `MergedTree::diff()` of calling this directly.
|
||||||
pub fn new(tree1: &MergedTree, tree2: &MergedTree, matcher: &'matcher dyn Matcher) -> Self {
|
pub fn new(trees1: &Merge<Tree>, trees2: &Merge<Tree>, matcher: &'matcher dyn Matcher) -> Self {
|
||||||
assert!(Arc::ptr_eq(tree1.store(), tree2.store()));
|
assert!(Arc::ptr_eq(trees1.first().store(), trees2.first().store()));
|
||||||
let root_dir = RepoPath::root();
|
let root_dir = RepoPath::root();
|
||||||
let mut stack = Vec::new();
|
let mut stack = Vec::new();
|
||||||
if !matcher.visit(root_dir).is_nothing() {
|
if !matcher.visit(root_dir).is_nothing() {
|
||||||
stack.push(TreeDiffItem::Dir(TreeDiffDirItem::from_trees(
|
stack.push(TreeDiffItem::Dir(TreeDiffDirItem::from_trees(
|
||||||
root_dir, tree1, tree2, matcher,
|
root_dir, trees1, trees2, matcher,
|
||||||
)));
|
)));
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
store: tree1.store().clone(),
|
store: trees1.first().store().clone(),
|
||||||
stack,
|
stack,
|
||||||
matcher,
|
matcher,
|
||||||
}
|
}
|
||||||
|
@ -630,29 +634,28 @@ impl<'matcher> TreeDiffIterator<'matcher> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the given tree if `value` is a tree, otherwise an empty tree.
|
/// Gets the given tree if `value` is a tree, otherwise an empty tree.
|
||||||
fn tree(
|
fn trees(
|
||||||
store: &Arc<Store>,
|
store: &Arc<Store>,
|
||||||
dir: &RepoPath,
|
dir: &RepoPath,
|
||||||
values: &MergedTreeValue,
|
values: &MergedTreeValue,
|
||||||
) -> BackendResult<MergedTree> {
|
) -> BackendResult<Merge<Tree>> {
|
||||||
let trees = if values.is_tree() {
|
if values.is_tree() {
|
||||||
values.try_map(|value| Self::single_tree(store, dir, value.as_ref()))?
|
values.try_map(|value| Self::single_tree(store, dir, value.as_ref()))
|
||||||
} else {
|
} else {
|
||||||
Merge::resolved(Tree::null(store.clone(), dir.to_owned()))
|
Ok(Merge::resolved(Tree::null(store.clone(), dir.to_owned())))
|
||||||
};
|
}
|
||||||
Ok(MergedTree { trees })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeDiffDirItem {
|
impl TreeDiffDirItem {
|
||||||
fn from_trees(
|
fn from_trees(
|
||||||
dir: &RepoPath,
|
dir: &RepoPath,
|
||||||
tree1: &MergedTree,
|
trees1: &Merge<Tree>,
|
||||||
tree2: &MergedTree,
|
trees2: &Merge<Tree>,
|
||||||
matcher: &dyn Matcher,
|
matcher: &dyn Matcher,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut entries = vec![];
|
let mut entries = vec![];
|
||||||
for (name, before, after) in merged_tree_entry_diff(tree1, tree2) {
|
for (name, before, after) in merged_tree_entry_diff(trees1, trees2) {
|
||||||
let path = dir.join(name);
|
let path = dir.join(name);
|
||||||
let before = before.to_merge();
|
let before = before.to_merge();
|
||||||
let after = after.to_merge();
|
let after = after.to_merge();
|
||||||
|
@ -712,11 +715,11 @@ impl Iterator for TreeDiffIterator<'_> {
|
||||||
let tree_before = before.is_tree();
|
let tree_before = before.is_tree();
|
||||||
let tree_after = after.is_tree();
|
let tree_after = after.is_tree();
|
||||||
let post_subdir = if tree_before || tree_after {
|
let post_subdir = if tree_before || tree_after {
|
||||||
let before_tree = match Self::tree(&self.store, &path, &before) {
|
let before_tree = match Self::trees(&self.store, &path, &before) {
|
||||||
Ok(tree) => tree,
|
Ok(tree) => tree,
|
||||||
Err(err) => return Some((path, Err(err))),
|
Err(err) => return Some((path, Err(err))),
|
||||||
};
|
};
|
||||||
let after_tree = match Self::tree(&self.store, &path, &after) {
|
let after_tree = match Self::trees(&self.store, &path, &after) {
|
||||||
Ok(tree) => tree,
|
Ok(tree) => tree,
|
||||||
Err(err) => return Some((path, Err(err))),
|
Err(err) => return Some((path, Err(err))),
|
||||||
};
|
};
|
||||||
|
@ -878,7 +881,9 @@ impl<'matcher> TreeDiffStreamImpl<'matcher> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (basename, value_before, value_after) in merged_tree_entry_diff(&tree1, &tree2) {
|
for (basename, value_before, value_after) in
|
||||||
|
merged_tree_entry_diff(&tree1.trees, &tree2.trees)
|
||||||
|
{
|
||||||
let path = dir.join(basename);
|
let path = dir.join(basename);
|
||||||
let before = value_before.to_merge();
|
let before = value_before.to_merge();
|
||||||
let after = value_after.to_merge();
|
let after = value_after.to_merge();
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn file_value(file_id: &FileId) -> TreeValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diff_stream_equals_iter(tree1: &MergedTree, tree2: &MergedTree, matcher: &dyn Matcher) {
|
fn diff_stream_equals_iter(tree1: &MergedTree, tree2: &MergedTree, matcher: &dyn Matcher) {
|
||||||
let iter_diff: Vec<_> = TreeDiffIterator::new(tree1, tree2, matcher)
|
let iter_diff: Vec<_> = TreeDiffIterator::new(tree1.as_merge(), tree2.as_merge(), matcher)
|
||||||
.map(|(path, diff)| (path, diff.unwrap()))
|
.map(|(path, diff)| (path, diff.unwrap()))
|
||||||
.collect();
|
.collect();
|
||||||
let max_concurrent_reads = 10;
|
let max_concurrent_reads = 10;
|
||||||
|
|
Loading…
Reference in a new issue