Change `append` to take ownership of the value being appended.
It is now up to the caller to clone the value if necessary.
This commit is contained in:
parent
0dde92c699
commit
8998f839ce
|
@ -47,6 +47,8 @@ referred to by their new location.
|
||||||
- `BridgeTree::authentication_path` has been renamed to `BridgeTree::witness`
|
- `BridgeTree::authentication_path` has been renamed to `BridgeTree::witness`
|
||||||
- `BridgeTree::witnessed` has been renamed to `BridgeTree::marked`
|
- `BridgeTree::witnessed` has been renamed to `BridgeTree::marked`
|
||||||
- `BridgeTree::witnessed_indices` has been renamed to `BridgeTree::marked_indices`
|
- `BridgeTree::witnessed_indices` has been renamed to `BridgeTree::marked_indices`
|
||||||
|
- `BridgeTree::append` and `NonEmptyFrontier::append` now take ownership of the
|
||||||
|
value being appended instead of the value being passed by reference.
|
||||||
|
|
||||||
The following types have been moved from the `bridgetree` module of
|
The following types have been moved from the `bridgetree` module of
|
||||||
`incrementalmerkletree` to the crate root:
|
`incrementalmerkletree` to the crate root:
|
||||||
|
|
|
@ -326,16 +326,16 @@ impl<H: Hashable + Clone, const DEPTH: u8> Frontier<H, DEPTH> {
|
||||||
/// Appends a new value to the frontier at the next available slot.
|
/// Appends a new value to the frontier at the next available slot.
|
||||||
/// Returns true if successful and false if the frontier would exceed
|
/// Returns true if successful and false if the frontier would exceed
|
||||||
/// the maximum allowed depth.
|
/// the maximum allowed depth.
|
||||||
pub fn append(&mut self, value: &H) -> bool {
|
pub fn append(&mut self, value: H) -> bool {
|
||||||
if let Some(frontier) = self.frontier.as_mut() {
|
if let Some(frontier) = self.frontier.as_mut() {
|
||||||
if frontier.position().is_complete_subtree(DEPTH.into()) {
|
if frontier.position().is_complete_subtree(DEPTH.into()) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
frontier.append(value.clone());
|
frontier.append(value);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.frontier = Some(NonEmptyFrontier::new(value.clone()));
|
self.frontier = Some(NonEmptyFrontier::new(value));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,7 +917,7 @@ impl<H: Hashable + Ord + Clone, const DEPTH: u8> BridgeTree<H, DEPTH> {
|
||||||
/// Appends a new value to the tree at the next available slot.
|
/// Appends a new value to the tree at the next available slot.
|
||||||
/// Returns true if successful and false if the tree would exceed
|
/// Returns true if successful and false if the tree would exceed
|
||||||
/// the maximum allowed depth.
|
/// the maximum allowed depth.
|
||||||
pub fn append(&mut self, value: &H) -> bool {
|
pub fn append(&mut self, value: H) -> bool {
|
||||||
if let Some(bridge) = self.current_bridge.as_mut() {
|
if let Some(bridge) = self.current_bridge.as_mut() {
|
||||||
if bridge
|
if bridge
|
||||||
.frontier
|
.frontier
|
||||||
|
@ -926,11 +926,11 @@ impl<H: Hashable + Ord + Clone, const DEPTH: u8> BridgeTree<H, DEPTH> {
|
||||||
{
|
{
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
bridge.append(value.clone());
|
bridge.append(value);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.current_bridge = Some(MerkleBridge::new(value.clone()));
|
self.current_bridge = Some(MerkleBridge::new(value));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1308,7 +1308,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<H: Hashable + Clone, const DEPTH: u8> Frontier<H> for super::Frontier<H, DEPTH> {
|
impl<H: Hashable + Clone, const DEPTH: u8> Frontier<H> for super::Frontier<H, DEPTH> {
|
||||||
fn append(&mut self, value: &H) -> bool {
|
fn append(&mut self, value: H) -> bool {
|
||||||
super::Frontier::append(self, value)
|
super::Frontier::append(self, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1318,7 +1318,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: Hashable + Ord + Clone, const DEPTH: u8> Tree<H> for BridgeTree<H, DEPTH> {
|
impl<H: Hashable + Ord + Clone, const DEPTH: u8> Tree<H> for BridgeTree<H, DEPTH> {
|
||||||
fn append(&mut self, value: &H) -> bool {
|
fn append(&mut self, value: H) -> bool {
|
||||||
BridgeTree::append(self, value)
|
BridgeTree::append(self, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1428,13 +1428,13 @@ mod tests {
|
||||||
assert_eq!(frontier.root().len(), 16);
|
assert_eq!(frontier.root().len(), 16);
|
||||||
assert_eq!(frontier.root(), "________________");
|
assert_eq!(frontier.root(), "________________");
|
||||||
|
|
||||||
frontier.append(&"a".to_string());
|
frontier.append("a".to_string());
|
||||||
assert_eq!(frontier.root(), "a_______________");
|
assert_eq!(frontier.root(), "a_______________");
|
||||||
|
|
||||||
frontier.append(&"b".to_string());
|
frontier.append("b".to_string());
|
||||||
assert_eq!(frontier.root(), "ab______________");
|
assert_eq!(frontier.root(), "ab______________");
|
||||||
|
|
||||||
frontier.append(&"c".to_string());
|
frontier.append("c".to_string());
|
||||||
assert_eq!(frontier.root(), "abc_____________");
|
assert_eq!(frontier.root(), "abc_____________");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,9 +1462,9 @@ mod tests {
|
||||||
fn tree_depth() {
|
fn tree_depth() {
|
||||||
let mut tree = BridgeTree::<String, 3>::new(100);
|
let mut tree = BridgeTree::<String, 3>::new(100);
|
||||||
for c in 'a'..'i' {
|
for c in 'a'..'i' {
|
||||||
assert!(tree.append(&c.to_string()))
|
assert!(tree.append(c.to_string()))
|
||||||
}
|
}
|
||||||
assert!(!tree.append(&'i'.to_string()));
|
assert!(!tree.append('i'.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arb_bridgetree<G: Strategy + Clone>(
|
fn arb_bridgetree<G: Strategy + Clone>(
|
||||||
|
@ -1529,10 +1529,10 @@ mod tests {
|
||||||
fn drop_oldest_checkpoint() {
|
fn drop_oldest_checkpoint() {
|
||||||
let mut t = BridgeTree::<String, 6>::new(100);
|
let mut t = BridgeTree::<String, 6>::new(100);
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.mark();
|
t.mark();
|
||||||
t.append(&"b".to_string());
|
t.append("b".to_string());
|
||||||
t.append(&"c".to_string());
|
t.append("c".to_string());
|
||||||
assert!(
|
assert!(
|
||||||
t.drop_oldest_checkpoint(),
|
t.drop_oldest_checkpoint(),
|
||||||
"Checkpoint drop is expected to succeed"
|
"Checkpoint drop is expected to succeed"
|
||||||
|
@ -1567,7 +1567,7 @@ mod tests {
|
||||||
let mut has_witness = vec![];
|
let mut has_witness = vec![];
|
||||||
for i in 0usize..100 {
|
for i in 0usize..100 {
|
||||||
let elem: String = format!("{},", i);
|
let elem: String = format!("{},", i);
|
||||||
assert!(t.append(&elem), "Append should succeed.");
|
assert!(t.append(elem), "Append should succeed.");
|
||||||
if i % 5 == 0 {
|
if i % 5 == 0 {
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
}
|
}
|
||||||
|
@ -1610,7 +1610,7 @@ mod tests {
|
||||||
fn garbage_collect_idx() {
|
fn garbage_collect_idx() {
|
||||||
let mut tree: BridgeTree<String, 7> = BridgeTree::new(100);
|
let mut tree: BridgeTree<String, 7> = BridgeTree::new(100);
|
||||||
let empty_root = tree.root(0);
|
let empty_root = tree.root(0);
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ is not another good use case for polymorphism over tree implementations.
|
||||||
- `Tree::get_witnessed_leaf` has been renamed to `Tree::get_marked_leaf`
|
- `Tree::get_witnessed_leaf` has been renamed to `Tree::get_marked_leaf`
|
||||||
- `Tree::remove_witness` has been renamed to `Tree::remove_mark`
|
- `Tree::remove_witness` has been renamed to `Tree::remove_mark`
|
||||||
- `Tree::authentication_path` has been renamed to `Tree::witness`
|
- `Tree::authentication_path` has been renamed to `Tree::witness`
|
||||||
|
- `Tree::append` now takes ownership of the value being appended instead of a value passed
|
||||||
|
by reference.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub trait Frontier<H> {
|
||||||
/// Appends a new value to the frontier at the next available slot.
|
/// Appends a new value to the frontier at the next available slot.
|
||||||
/// Returns true if successful and false if the frontier would exceed
|
/// Returns true if successful and false if the frontier would exceed
|
||||||
/// the maximum allowed depth.
|
/// the maximum allowed depth.
|
||||||
fn append(&mut self, value: &H) -> bool;
|
fn append(&mut self, value: H) -> bool;
|
||||||
|
|
||||||
/// Obtains the current root of this Merkle frontier by hashing
|
/// Obtains the current root of this Merkle frontier by hashing
|
||||||
/// against empty nodes up to the maximum height of the pruned
|
/// against empty nodes up to the maximum height of the pruned
|
||||||
|
@ -32,7 +32,7 @@ pub trait Tree<H> {
|
||||||
/// Appends a new value to the tree at the next available slot.
|
/// Appends a new value to the tree at the next available slot.
|
||||||
/// Returns true if successful and false if the tree would exceed
|
/// Returns true if successful and false if the tree would exceed
|
||||||
/// the maximum allowed depth.
|
/// the maximum allowed depth.
|
||||||
fn append(&mut self, value: &H) -> bool;
|
fn append(&mut self, value: H) -> bool;
|
||||||
|
|
||||||
/// Returns the most recently appended leaf value.
|
/// Returns the most recently appended leaf value.
|
||||||
fn current_position(&self) -> Option<Position>;
|
fn current_position(&self) -> Option<Position>;
|
||||||
|
@ -150,11 +150,11 @@ pub fn witness<T>(pos: usize, depth: usize) -> Operation<T> {
|
||||||
Operation::Authpath(Position::from(pos), depth)
|
Operation::Authpath(Position::from(pos), depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: Hashable> Operation<H> {
|
impl<H: Hashable + Clone> Operation<H> {
|
||||||
pub fn apply<T: Tree<H>>(&self, tree: &mut T) -> Option<(Position, Vec<H>)> {
|
pub fn apply<T: Tree<H>>(&self, tree: &mut T) -> Option<(Position, Vec<H>)> {
|
||||||
match self {
|
match self {
|
||||||
Append(a) => {
|
Append(a) => {
|
||||||
assert!(tree.append(a), "append failed");
|
assert!(tree.append(a.clone()), "append failed");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
CurrentPosition => None,
|
CurrentPosition => None,
|
||||||
|
@ -227,7 +227,7 @@ where
|
||||||
pub fn apply_operation<H, T: Tree<H>>(tree: &mut T, op: Operation<H>) {
|
pub fn apply_operation<H, T: Tree<H>>(tree: &mut T, op: Operation<H>) {
|
||||||
match op {
|
match op {
|
||||||
Append(value) => {
|
Append(value) => {
|
||||||
tree.append(&value);
|
tree.append(value);
|
||||||
}
|
}
|
||||||
Mark => {
|
Mark => {
|
||||||
tree.mark();
|
tree.mark();
|
||||||
|
@ -264,7 +264,7 @@ pub fn check_operations<H: Hashable + Ord + Clone + Debug, T: Tree<H>>(
|
||||||
prop_assert_eq!(tree_size, tree_values.len());
|
prop_assert_eq!(tree_size, tree_values.len());
|
||||||
match op {
|
match op {
|
||||||
Append(value) => {
|
Append(value) => {
|
||||||
if tree.append(value) {
|
if tree.append(value.clone()) {
|
||||||
prop_assert!(tree_size < (1 << tree_depth));
|
prop_assert!(tree_size < (1 << tree_depth));
|
||||||
tree_size += 1;
|
tree_size += 1;
|
||||||
tree_values.push(value.clone());
|
tree_values.push(value.clone());
|
||||||
|
@ -385,8 +385,8 @@ impl<H: Hashable + Ord + Clone + Debug, I: Tree<H>, E: Tree<H>> CombinedTree<H,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: Hashable + Ord + Clone + Debug, I: Tree<H>, E: Tree<H>> Tree<H> for CombinedTree<H, I, E> {
|
impl<H: Hashable + Ord + Clone + Debug, I: Tree<H>, E: Tree<H>> Tree<H> for CombinedTree<H, I, E> {
|
||||||
fn append(&mut self, value: &H) -> bool {
|
fn append(&mut self, value: H) -> bool {
|
||||||
let a = self.inefficient.append(value);
|
let a = self.inefficient.append(value.clone());
|
||||||
let b = self.efficient.append(value);
|
let b = self.efficient.append(value);
|
||||||
assert_eq!(a, b);
|
assert_eq!(a, b);
|
||||||
a
|
a
|
||||||
|
@ -471,29 +471,29 @@ pub fn check_root_hashes<T: Tree<String>, F: Fn(usize) -> T>(new_tree: F) {
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
assert_eq!(tree.root(0).unwrap(), "________________");
|
assert_eq!(tree.root(0).unwrap(), "________________");
|
||||||
|
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
assert_eq!(tree.root(0).unwrap().len(), 16);
|
assert_eq!(tree.root(0).unwrap().len(), 16);
|
||||||
assert_eq!(tree.root(0).unwrap(), "a_______________");
|
assert_eq!(tree.root(0).unwrap(), "a_______________");
|
||||||
|
|
||||||
tree.append(&"b".to_string());
|
tree.append("b".to_string());
|
||||||
assert_eq!(tree.root(0).unwrap(), "ab______________");
|
assert_eq!(tree.root(0).unwrap(), "ab______________");
|
||||||
|
|
||||||
tree.append(&"c".to_string());
|
tree.append("c".to_string());
|
||||||
assert_eq!(tree.root(0).unwrap(), "abc_____________");
|
assert_eq!(tree.root(0).unwrap(), "abc_____________");
|
||||||
|
|
||||||
let mut t = new_tree(100);
|
let mut t = new_tree(100);
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
t.mark();
|
t.mark();
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
assert_eq!(t.root(0).unwrap(), "aaaa____________");
|
assert_eq!(t.root(0).unwrap(), "aaaa____________");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new_tree: F) {
|
pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new_tree: F) {
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(0), &tree.root(0).unwrap()),
|
tree.witness(Position::from(0), &tree.root(0).unwrap()),
|
||||||
|
@ -505,7 +505,7 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
tree.append(&"b".to_string());
|
tree.append("b".to_string());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(0.into(), &tree.root(0).unwrap()),
|
tree.witness(0.into(), &tree.root(0).unwrap()),
|
||||||
Some(vec![
|
Some(vec![
|
||||||
|
@ -516,7 +516,7 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
tree.append(&"c".to_string());
|
tree.append("c".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(2), &tree.root(0).unwrap()),
|
tree.witness(Position::from(2), &tree.root(0).unwrap()),
|
||||||
|
@ -528,7 +528,7 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
tree.append(&"d".to_string());
|
tree.append("d".to_string());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(2), &tree.root(0).unwrap()),
|
tree.witness(Position::from(2), &tree.root(0).unwrap()),
|
||||||
Some(vec![
|
Some(vec![
|
||||||
|
@ -539,7 +539,7 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
tree.append(&"e".to_string());
|
tree.append("e".to_string());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(2), &tree.root(0).unwrap()),
|
tree.witness(Position::from(2), &tree.root(0).unwrap()),
|
||||||
Some(vec![
|
Some(vec![
|
||||||
|
@ -551,13 +551,13 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
for c in 'b'..'h' {
|
for c in 'b'..'h' {
|
||||||
tree.append(&c.to_string());
|
tree.append(c.to_string());
|
||||||
}
|
}
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&"h".to_string());
|
tree.append("h".to_string());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(0.into(), &tree.root(0).unwrap()),
|
tree.witness(0.into(), &tree.root(0).unwrap()),
|
||||||
|
@ -570,17 +570,17 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&"b".to_string());
|
tree.append("b".to_string());
|
||||||
tree.append(&"c".to_string());
|
tree.append("c".to_string());
|
||||||
tree.append(&"d".to_string());
|
tree.append("d".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&"e".to_string());
|
tree.append("e".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&"f".to_string());
|
tree.append("f".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&"g".to_string());
|
tree.append("g".to_string());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(5), &tree.root(0).unwrap()),
|
tree.witness(Position::from(5), &tree.root(0).unwrap()),
|
||||||
|
@ -594,10 +594,10 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
for c in 'a'..'l' {
|
for c in 'a'..'l' {
|
||||||
tree.append(&c.to_string());
|
tree.append(c.to_string());
|
||||||
}
|
}
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&'l'.to_string());
|
tree.append('l'.to_string());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(10), &tree.root(0).unwrap()),
|
tree.witness(Position::from(10), &tree.root(0).unwrap()),
|
||||||
|
@ -610,16 +610,16 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&'a'.to_string());
|
tree.append('a'.to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
assert!(tree.rewind());
|
assert!(tree.rewind());
|
||||||
for c in 'b'..'f' {
|
for c in 'b'..'f' {
|
||||||
tree.append(&c.to_string());
|
tree.append(c.to_string());
|
||||||
}
|
}
|
||||||
tree.mark();
|
tree.mark();
|
||||||
for c in 'f'..'i' {
|
for c in 'f'..'i' {
|
||||||
tree.append(&c.to_string());
|
tree.append(c.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -633,17 +633,17 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&'a'.to_string());
|
tree.append('a'.to_string());
|
||||||
tree.append(&'b'.to_string());
|
tree.append('b'.to_string());
|
||||||
tree.append(&'c'.to_string());
|
tree.append('c'.to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&'d'.to_string());
|
tree.append('d'.to_string());
|
||||||
tree.append(&'e'.to_string());
|
tree.append('e'.to_string());
|
||||||
tree.append(&'f'.to_string());
|
tree.append('f'.to_string());
|
||||||
tree.append(&'g'.to_string());
|
tree.append('g'.to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
tree.append(&'h'.to_string());
|
tree.append('h'.to_string());
|
||||||
assert!(tree.rewind());
|
assert!(tree.rewind());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -657,8 +657,8 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&'a'.to_string());
|
tree.append('a'.to_string());
|
||||||
tree.append(&'b'.to_string());
|
tree.append('b'.to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(0), &tree.root(0).unwrap()),
|
tree.witness(Position::from(0), &tree.root(0).unwrap()),
|
||||||
|
@ -667,13 +667,13 @@ pub fn check_witnesses<T: Tree<String> + std::fmt::Debug, F: Fn(usize) -> T>(new
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
for c in 'a'..'n' {
|
for c in 'a'..'n' {
|
||||||
tree.append(&c.to_string());
|
tree.append(c.to_string());
|
||||||
}
|
}
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&'n'.to_string());
|
tree.append('n'.to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.append(&'o'.to_string());
|
tree.append('o'.to_string());
|
||||||
tree.append(&'p'.to_string());
|
tree.append('p'.to_string());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tree.witness(Position::from(12), &tree.root(0).unwrap()),
|
tree.witness(Position::from(12), &tree.root(0).unwrap()),
|
||||||
|
@ -718,55 +718,55 @@ pub fn check_checkpoint_rewind<T: Tree<String>, F: Fn(usize) -> T>(new_tree: F)
|
||||||
assert!(t.rewind());
|
assert!(t.rewind());
|
||||||
|
|
||||||
let mut t = new_tree(100);
|
let mut t = new_tree(100);
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
t.append(&"b".to_string());
|
t.append("b".to_string());
|
||||||
t.mark();
|
t.mark();
|
||||||
assert!(t.rewind());
|
assert!(t.rewind());
|
||||||
assert_eq!(Some(Position::from(0)), t.current_position());
|
assert_eq!(Some(Position::from(0)), t.current_position());
|
||||||
|
|
||||||
let mut t = new_tree(100);
|
let mut t = new_tree(100);
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.mark();
|
t.mark();
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
assert!(t.rewind());
|
assert!(t.rewind());
|
||||||
|
|
||||||
let mut t = new_tree(100);
|
let mut t = new_tree(100);
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
t.mark();
|
t.mark();
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
assert!(t.rewind());
|
assert!(t.rewind());
|
||||||
assert_eq!(Some(Position::from(0)), t.current_position());
|
assert_eq!(Some(Position::from(0)), t.current_position());
|
||||||
|
|
||||||
let mut t = new_tree(100);
|
let mut t = new_tree(100);
|
||||||
t.append(&"a".to_string());
|
t.append("a".to_string());
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
t.checkpoint();
|
t.checkpoint();
|
||||||
assert!(t.rewind());
|
assert!(t.rewind());
|
||||||
t.append(&"b".to_string());
|
t.append("b".to_string());
|
||||||
assert!(t.rewind());
|
assert!(t.rewind());
|
||||||
t.append(&"b".to_string());
|
t.append("b".to_string());
|
||||||
assert_eq!(t.root(0).unwrap(), "ab______________");
|
assert_eq!(t.root(0).unwrap(), "ab______________");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_rewind_remove_mark<T: Tree<String>, F: Fn(usize) -> T>(new_tree: F) {
|
pub fn check_rewind_remove_mark<T: Tree<String>, F: Fn(usize) -> T>(new_tree: F) {
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"e".to_string());
|
tree.append("e".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
assert!(tree.rewind());
|
assert!(tree.rewind());
|
||||||
assert!(tree.remove_mark(0usize.into()));
|
assert!(tree.remove_mark(0usize.into()));
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"e".to_string());
|
tree.append("e".to_string());
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
tree.mark();
|
tree.mark();
|
||||||
assert!(tree.rewind());
|
assert!(tree.rewind());
|
||||||
assert!(!tree.remove_mark(0usize.into()));
|
assert!(!tree.remove_mark(0usize.into()));
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"e".to_string());
|
tree.append("e".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
assert!(tree.remove_mark(0usize.into()));
|
assert!(tree.remove_mark(0usize.into()));
|
||||||
|
@ -774,7 +774,7 @@ pub fn check_rewind_remove_mark<T: Tree<String>, F: Fn(usize) -> T>(new_tree: F)
|
||||||
assert!(tree.remove_mark(0usize.into()));
|
assert!(tree.remove_mark(0usize.into()));
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"e".to_string());
|
tree.append("e".to_string());
|
||||||
tree.mark();
|
tree.mark();
|
||||||
assert!(tree.remove_mark(0usize.into()));
|
assert!(tree.remove_mark(0usize.into()));
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
|
@ -782,14 +782,14 @@ pub fn check_rewind_remove_mark<T: Tree<String>, F: Fn(usize) -> T>(new_tree: F)
|
||||||
assert!(!tree.remove_mark(0usize.into()));
|
assert!(!tree.remove_mark(0usize.into()));
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
assert!(!tree.remove_mark(0usize.into()));
|
assert!(!tree.remove_mark(0usize.into()));
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
assert!(tree.mark().is_some());
|
assert!(tree.mark().is_some());
|
||||||
assert!(tree.rewind());
|
assert!(tree.rewind());
|
||||||
|
|
||||||
let mut tree = new_tree(100);
|
let mut tree = new_tree(100);
|
||||||
tree.append(&"a".to_string());
|
tree.append("a".to_string());
|
||||||
tree.checkpoint();
|
tree.checkpoint();
|
||||||
assert!(tree.mark().is_some());
|
assert!(tree.mark().is_some());
|
||||||
assert!(tree.remove_mark(0usize.into()));
|
assert!(tree.remove_mark(0usize.into()));
|
||||||
|
|
|
@ -53,11 +53,11 @@ impl<H: Hashable + Clone> TreeState<H> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: Hashable + Clone> Frontier<H> for TreeState<H> {
|
impl<H: Hashable + Clone> Frontier<H> for TreeState<H> {
|
||||||
fn append(&mut self, value: &H) -> bool {
|
fn append(&mut self, value: H) -> bool {
|
||||||
if self.current_offset == (1 << self.depth) {
|
if self.current_offset == (1 << self.depth) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
self.leaves[self.current_offset] = value.clone();
|
self.leaves[self.current_offset] = value;
|
||||||
self.current_offset += 1;
|
self.current_offset += 1;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ impl<H: Hashable + PartialEq + Clone> CompleteTree<H> {
|
||||||
impl<H: Hashable + PartialEq + Clone + std::fmt::Debug> Tree<H> for CompleteTree<H> {
|
impl<H: Hashable + PartialEq + Clone + std::fmt::Debug> Tree<H> for CompleteTree<H> {
|
||||||
/// Appends a new value to the tree at the next available slot. Returns true
|
/// Appends a new value to the tree at the next available slot. Returns true
|
||||||
/// if successful and false if the tree is full.
|
/// if successful and false if the tree is full.
|
||||||
fn append(&mut self, value: &H) -> bool {
|
fn append(&mut self, value: H) -> bool {
|
||||||
self.tree_state.append(value)
|
self.tree_state.append(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,9 +279,9 @@ mod tests {
|
||||||
|
|
||||||
let mut tree = CompleteTree::<SipHashable>::new(DEPTH, 100);
|
let mut tree = CompleteTree::<SipHashable>::new(DEPTH, 100);
|
||||||
for value in values {
|
for value in values {
|
||||||
assert!(tree.append(&value));
|
assert!(tree.append(value));
|
||||||
}
|
}
|
||||||
assert!(!tree.append(&SipHashable(0)));
|
assert!(!tree.append(SipHashable(0)));
|
||||||
|
|
||||||
let expected = SipHashable::combine(
|
let expected = SipHashable::combine(
|
||||||
Level::from(2),
|
Level::from(2),
|
||||||
|
@ -317,10 +317,10 @@ mod tests {
|
||||||
|
|
||||||
let mut tree = CompleteTree::<SipHashable>::new(DEPTH, 100);
|
let mut tree = CompleteTree::<SipHashable>::new(DEPTH, 100);
|
||||||
for value in values {
|
for value in values {
|
||||||
assert!(tree.append(&value));
|
assert!(tree.append(value));
|
||||||
tree.mark();
|
tree.mark();
|
||||||
}
|
}
|
||||||
assert!(!tree.append(&SipHashable(0)));
|
assert!(!tree.append(SipHashable(0)));
|
||||||
|
|
||||||
let expected = SipHashable::combine(
|
let expected = SipHashable::combine(
|
||||||
<Level>::from(2),
|
<Level>::from(2),
|
||||||
|
|
Loading…
Reference in New Issue