mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-29 23:57:51 +00:00
merged_tree: use Merge<Tree> to represent pending trees in TreeDiffStreamImpl
This seems a slightly better in that MergedTree no longer represent a subtree.
This commit is contained in:
parent
991b0e8b68
commit
c741e3db39
2 changed files with 31 additions and 26 deletions
|
@ -295,8 +295,8 @@ impl MergedTree {
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Box::pin(TreeDiffStreamImpl::new(
|
Box::pin(TreeDiffStreamImpl::new(
|
||||||
self.clone(),
|
self.trees.clone(),
|
||||||
other.clone(),
|
other.trees.clone(),
|
||||||
matcher,
|
matcher,
|
||||||
concurrency,
|
concurrency,
|
||||||
))
|
))
|
||||||
|
@ -859,7 +859,7 @@ pub struct TreeDiffStreamImpl<'matcher> {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pending_trees: VecDeque<(
|
pending_trees: VecDeque<(
|
||||||
RepoPathBuf,
|
RepoPathBuf,
|
||||||
BoxFuture<'matcher, BackendResult<(MergedTree, MergedTree)>>,
|
BoxFuture<'matcher, BackendResult<(Merge<Tree>, Merge<Tree>)>>,
|
||||||
)>,
|
)>,
|
||||||
/// The maximum number of trees to request concurrently. However, we do the
|
/// The maximum number of trees to request concurrently. However, we do the
|
||||||
/// accounting per path, so for there will often be twice as many pending
|
/// accounting per path, so for there will often be twice as many pending
|
||||||
|
@ -922,21 +922,21 @@ impl<'matcher> TreeDiffStreamImpl<'matcher> {
|
||||||
/// Creates a iterator over the differences between two trees. Generally
|
/// Creates a iterator over the differences between two trees. Generally
|
||||||
/// prefer `MergedTree::diff_stream()` of calling this directly.
|
/// prefer `MergedTree::diff_stream()` of calling this directly.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
tree1: MergedTree,
|
trees1: Merge<Tree>,
|
||||||
tree2: MergedTree,
|
trees2: Merge<Tree>,
|
||||||
matcher: &'matcher dyn Matcher,
|
matcher: &'matcher dyn Matcher,
|
||||||
max_concurrent_reads: usize,
|
max_concurrent_reads: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
assert!(Arc::ptr_eq(tree1.store(), tree2.store()));
|
assert!(Arc::ptr_eq(trees1.first().store(), trees2.first().store()));
|
||||||
let mut stream = Self {
|
let mut stream = Self {
|
||||||
store: tree1.store().clone(),
|
store: trees1.first().store().clone(),
|
||||||
matcher,
|
matcher,
|
||||||
items: BTreeMap::new(),
|
items: BTreeMap::new(),
|
||||||
pending_trees: VecDeque::new(),
|
pending_trees: VecDeque::new(),
|
||||||
max_concurrent_reads,
|
max_concurrent_reads,
|
||||||
max_queued_items: 10000,
|
max_queued_items: 10000,
|
||||||
};
|
};
|
||||||
stream.add_dir_diff_items(RepoPathBuf::root(), Ok((tree1, tree2)));
|
stream.add_dir_diff_items(RepoPathBuf::root(), Ok((trees1, trees2)));
|
||||||
stream
|
stream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,29 +952,28 @@ impl<'matcher> TreeDiffStreamImpl<'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.
|
||||||
async fn tree(
|
async fn trees(
|
||||||
store: Arc<Store>,
|
store: Arc<Store>,
|
||||||
dir: RepoPathBuf,
|
dir: RepoPathBuf,
|
||||||
values: MergedTreeValue,
|
values: MergedTreeValue,
|
||||||
) -> BackendResult<MergedTree> {
|
) -> BackendResult<Merge<Tree>> {
|
||||||
let trees = if values.is_tree() {
|
if values.is_tree() {
|
||||||
let builder: MergeBuilder<Tree> = futures::stream::iter(values.iter())
|
let builder: MergeBuilder<Tree> = futures::stream::iter(values.iter())
|
||||||
.then(|value| Self::single_tree(&store, dir.clone(), value.as_ref()))
|
.then(|value| Self::single_tree(&store, dir.clone(), value.as_ref()))
|
||||||
.try_collect()
|
.try_collect()
|
||||||
.await?;
|
.await?;
|
||||||
builder.build()
|
Ok(builder.build())
|
||||||
} else {
|
} else {
|
||||||
Merge::resolved(Tree::empty(store, dir))
|
Ok(Merge::resolved(Tree::empty(store, dir)))
|
||||||
};
|
}
|
||||||
Ok(MergedTree { trees })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_dir_diff_items(
|
fn add_dir_diff_items(
|
||||||
&mut self,
|
&mut self,
|
||||||
dir: RepoPathBuf,
|
dir: RepoPathBuf,
|
||||||
tree_diff: BackendResult<(MergedTree, MergedTree)>,
|
tree_diff: BackendResult<(Merge<Tree>, Merge<Tree>)>,
|
||||||
) {
|
) {
|
||||||
let (tree1, tree2) = match tree_diff {
|
let (trees1, trees2) = match tree_diff {
|
||||||
Ok(trees) => trees,
|
Ok(trees) => trees,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.items.insert(DiffStreamKey::normal(dir), Err(err));
|
self.items.insert(DiffStreamKey::normal(dir), Err(err));
|
||||||
|
@ -982,7 +981,7 @@ impl<'matcher> TreeDiffStreamImpl<'matcher> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (basename, before, after) in merged_tree_entry_diff(&tree1.trees, &tree2.trees) {
|
for (basename, before, after) in merged_tree_entry_diff(&trees1, &trees2) {
|
||||||
let path = dir.join(basename);
|
let path = dir.join(basename);
|
||||||
let tree_before = before.is_tree();
|
let tree_before = before.is_tree();
|
||||||
let tree_after = after.is_tree();
|
let tree_after = after.is_tree();
|
||||||
|
@ -1010,9 +1009,9 @@ impl<'matcher> TreeDiffStreamImpl<'matcher> {
|
||||||
// If the path was a tree on either side of the diff, read those trees.
|
// If the path was a tree on either side of the diff, read those trees.
|
||||||
if tree_matches {
|
if tree_matches {
|
||||||
let before_tree_future =
|
let before_tree_future =
|
||||||
Self::tree(self.store.clone(), path.clone(), before.cloned());
|
Self::trees(self.store.clone(), path.clone(), before.cloned());
|
||||||
let after_tree_future =
|
let after_tree_future =
|
||||||
Self::tree(self.store.clone(), path.clone(), after.cloned());
|
Self::trees(self.store.clone(), path.clone(), after.cloned());
|
||||||
let both_trees_future =
|
let both_trees_future =
|
||||||
async { futures::try_join!(before_tree_future, after_tree_future) };
|
async { futures::try_join!(before_tree_future, after_tree_future) };
|
||||||
self.pending_trees
|
self.pending_trees
|
||||||
|
|
|
@ -57,15 +57,21 @@ fn diff_entry_tuple(diff: TreeDiffEntry) -> (RepoPathBuf, (MergedTreeValue, Merg
|
||||||
}
|
}
|
||||||
|
|
||||||
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.as_merge(), tree2.as_merge(), matcher)
|
let trees1 = tree1.as_merge();
|
||||||
|
let trees2 = tree2.as_merge();
|
||||||
|
let iter_diff: Vec<_> = TreeDiffIterator::new(trees1, trees2, matcher)
|
||||||
.map(|diff| (diff.path, diff.values.unwrap()))
|
.map(|diff| (diff.path, diff.values.unwrap()))
|
||||||
.collect();
|
.collect();
|
||||||
let max_concurrent_reads = 10;
|
let max_concurrent_reads = 10;
|
||||||
let stream_diff: Vec<_> =
|
let stream_diff: Vec<_> = TreeDiffStreamImpl::new(
|
||||||
TreeDiffStreamImpl::new(tree1.clone(), tree2.clone(), matcher, max_concurrent_reads)
|
trees1.clone(),
|
||||||
.map(|diff| (diff.path, diff.values.unwrap()))
|
trees2.clone(),
|
||||||
.collect()
|
matcher,
|
||||||
.block_on();
|
max_concurrent_reads,
|
||||||
|
)
|
||||||
|
.map(|diff| (diff.path, diff.values.unwrap()))
|
||||||
|
.collect()
|
||||||
|
.block_on();
|
||||||
assert_eq!(stream_diff, iter_diff);
|
assert_eq!(stream_diff, iter_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue