Merge pull request #86 from zcash/shardtree-arc-wielder

shardtree: Switch from `Rc` to `Arc` to make trees `Send`
This commit is contained in:
str4d 2023-07-17 23:01:17 +01:00 committed by GitHub
commit bae25ad89c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 33 deletions

View File

@ -1,4 +1,4 @@
use std::{collections::BTreeMap, fmt, ops::Range, rc::Rc};
use std::{collections::BTreeMap, fmt, ops::Range, sync::Arc};
use incrementalmerkletree::{Address, Hashable, Level, Position, Retention};
use tracing::trace;
@ -255,7 +255,7 @@ fn unite<H: Hashable + Clone + PartialEq>(
lroot: LocatedPrunableTree<H>,
rroot: LocatedPrunableTree<H>,
prune_below: Level,
) -> LocatedTree<Option<Rc<H>>, (H, RetentionFlags)> {
) -> LocatedPrunableTree<H> {
assert_eq!(lroot.root_addr.parent(), rroot.root_addr.parent());
LocatedTree {
root_addr: lroot.root_addr.parent(),
@ -264,8 +264,8 @@ fn unite<H: Hashable + Clone + PartialEq>(
} else {
Tree(Node::Parent {
ann: None,
left: Rc::new(lroot.root),
right: Rc::new(rroot.root),
left: Arc::new(lroot.root),
right: Arc::new(rroot.root),
})
},
}

View File

@ -1,7 +1,7 @@
use core::fmt::{self, Debug, Display};
use either::Either;
use std::collections::{BTreeMap, BTreeSet};
use std::rc::Rc;
use std::sync::Arc;
use tracing::trace;
use incrementalmerkletree::{
@ -1018,10 +1018,10 @@ impl<
.map(|(l, r)| {
// the node values of child nodes cannot contain the hashes of
// empty nodes or nodes with positions greater than the
Rc::new(S::H::combine(l_addr.level(), l, r))
Arc::new(S::H::combine(l_addr.level(), l, r))
}),
left: new_left.map_or_else(|| left.clone(), Rc::new),
right: new_right.map_or_else(|| right.clone(), Rc::new),
left: new_left.map_or_else(|| left.clone(), Arc::new),
right: new_right.map_or_else(|| right.clone(), Arc::new),
});
Ok((root, Some(new_parent)))
@ -1049,7 +1049,7 @@ impl<
Ok((
root,
replacement.map(|r| r.reannotate_root(Some(Rc::new(value.0.clone())))),
replacement.map(|r| r.reannotate_root(Some(Arc::new(value.0.clone())))),
))
}
}

View File

@ -1,7 +1,7 @@
use std::collections::{BTreeMap, BTreeSet};
use std::fmt;
use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
use bitflags::bitflags;
use incrementalmerkletree::{
@ -62,7 +62,7 @@ impl<C> From<Retention<C>> for RetentionFlags {
}
}
pub type PrunableTree<H> = Tree<Option<Rc<H>>, (H, RetentionFlags)>;
pub type PrunableTree<H> = Tree<Option<Arc<H>>, (H, RetentionFlags)>;
impl<H: Hashable + Clone + PartialEq> PrunableTree<H> {
/// Returns the the value if this is a leaf.
@ -229,7 +229,7 @@ impl<H: Hashable + Clone + PartialEq> PrunableTree<H> {
| (parent @ Tree(Node::Parent { .. }), Tree(Node::Leaf { value })) => {
let parent_hash = parent.root_hash(addr, no_default_fill);
if parent_hash.iter().all(|r| r == &value.0) {
Ok(parent.reannotate_root(Some(Rc::new(value.0))))
Ok(parent.reannotate_root(Some(Arc::new(value.0))))
} else {
trace!(leaf = ?value, node = ?parent_hash, "Merge conflict for leaf into node");
Err(addr)
@ -284,7 +284,7 @@ impl<H: Hashable + Clone + PartialEq> PrunableTree<H> {
/// replacement `Nil` value).
///
/// `level` must be the level of the two nodes that are being joined.
pub(crate) fn unite(level: Level, ann: Option<Rc<H>>, left: Self, right: Self) -> Self {
pub(crate) fn unite(level: Level, ann: Option<Arc<H>>, left: Self, right: Self) -> Self {
match (left, right) {
(Tree(Node::Nil), Tree(Node::Nil)) => Tree(Node::Nil),
(Tree(Node::Leaf { value: lv }), Tree(Node::Leaf { value: rv }))
@ -302,15 +302,15 @@ impl<H: Hashable + Clone + PartialEq> PrunableTree<H> {
(left, right) => Tree(
Node::Parent {
ann,
left: Rc::new(left),
right: Rc::new(right),
left: Arc::new(left),
right: Arc::new(right),
},
),
}
}
}
pub type LocatedPrunableTree<H> = LocatedTree<Option<Rc<H>>, (H, RetentionFlags)>;
pub type LocatedPrunableTree<H> = LocatedTree<Option<Arc<H>>, (H, RetentionFlags)>;
/// A data structure describing the nature of a [`Node::Nil`] node in the tree that was introduced
/// as the consequence of an insertion.
@ -638,7 +638,7 @@ impl<H: Hashable + Clone + PartialEq> LocatedPrunableTree<H> {
// In the case that we are replacing a node entirely, we need to extend the
// subtree up to the level of the node being replaced, adding Nil siblings
// and recording the presence of those incomplete nodes when necessary
let replacement = |ann: Option<Rc<H>>, mut node: LocatedPrunableTree<H>| {
let replacement = |ann: Option<Arc<H>>, mut node: LocatedPrunableTree<H>| {
// construct the replacement node bottom-up
let mut incomplete = vec![];
while node.root_addr.level() < root_addr.level() {
@ -651,14 +651,14 @@ impl<H: Hashable + Clone + PartialEq> LocatedPrunableTree<H> {
root: if node.root_addr.is_right_child() {
Tree(Node::Parent {
ann: None,
left: Rc::new(Tree(Node::Nil)),
right: Rc::new(node.root),
left: Arc::new(Tree(Node::Nil)),
right: Arc::new(node.root),
})
} else {
Tree(Node::Parent {
ann: None,
left: Rc::new(node.root),
right: Rc::new(Tree(Node::Nil)),
left: Arc::new(node.root),
right: Arc::new(Tree(Node::Nil)),
})
},
};
@ -682,7 +682,7 @@ impl<H: Hashable + Clone + PartialEq> LocatedPrunableTree<H> {
} else if subtree.root.node_value().iter().all(|v| v == &value) {
Ok((
// at this point we statically know the root to be a parent
subtree.root.reannotate_root(Some(Rc::new(value.clone()))),
subtree.root.reannotate_root(Some(Arc::new(value.clone()))),
vec![],
))
} else {
@ -694,7 +694,7 @@ impl<H: Hashable + Clone + PartialEq> LocatedPrunableTree<H> {
Err(InsertionError::Conflict(root_addr))
}
} else {
Ok(replacement(Some(Rc::new(value.clone())), subtree))
Ok(replacement(Some(Arc::new(value.clone())), subtree))
}
}
parent if root_addr == subtree.root_addr => {

View File

@ -42,8 +42,8 @@ where
} else {
Node::Parent {
ann,
left: Rc::new(left),
right: Rc::new(right),
left: Arc::new(left),
right: Arc::new(right),
}
})
})
@ -59,7 +59,7 @@ where
H::Value: Clone + 'static,
{
arb_tree(
proptest::option::of(arb_leaf.clone().prop_map(Rc::new)),
proptest::option::of(arb_leaf.clone().prop_map(Arc::new)),
(arb_leaf, arb_retention_flags()),
depth,
size,

View File

@ -1,5 +1,5 @@
use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;
use incrementalmerkletree::{Address, Level, Position};
@ -73,10 +73,10 @@ impl<'a, C: Clone, A: Clone, V: Clone> Node<C, &'a A, &'a V> {
/// An immutable binary tree with each of its nodes tagged with an annotation value.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Tree<A, V>(pub(crate) Node<Rc<Tree<A, V>>, A, V>);
pub struct Tree<A, V>(pub(crate) Node<Arc<Tree<A, V>>, A, V>);
impl<A, V> Deref for Tree<A, V> {
type Target = Node<Rc<Tree<A, V>>, A, V>;
type Target = Node<Arc<Tree<A, V>>, A, V>;
fn deref(&self) -> &Self::Target {
&self.0
}
@ -94,8 +94,8 @@ impl<A, V> Tree<A, V> {
pub fn parent(ann: A, left: Self, right: Self) -> Self {
Tree(Node::Parent {
ann,
left: Rc::new(left),
right: Rc::new(right),
left: Arc::new(left),
right: Arc::new(right),
})
}
@ -308,12 +308,12 @@ impl<A: Default + Clone, V: Clone> LocatedTree<A, V> {
let mut l_decomposed = go(
level,
l_addr,
Rc::try_unwrap(left).unwrap_or_else(|rc| (*rc).clone()),
Arc::try_unwrap(left).unwrap_or_else(|rc| (*rc).clone()),
);
let mut r_decomposed = go(
level,
r_addr,
Rc::try_unwrap(right).unwrap_or_else(|rc| (*rc).clone()),
Arc::try_unwrap(right).unwrap_or_else(|rc| (*rc).clone()),
);
l_decomposed.append(&mut r_decomposed);
l_decomposed