cleaned up working state

This commit is contained in:
Qyriad 2024-08-29 13:01:41 -06:00
parent a86faf68b5
commit 411354fbec
3 changed files with 147 additions and 500 deletions

View file

@ -19,7 +19,7 @@ mod proof;
pub use proof::SmtProof;
use winter_utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
mod rollback;
//mod rollback;
#[cfg(test)]
mod tests;

View file

@ -442,6 +442,7 @@ fn test_checked_insertion() {
let new_parent_1 = mutations.get_inner_node(parent_1_index).unwrap();
assert_eq!(leaf_1_parent, new_parent_1);
let mut index = NodeIndex::from(Smt::key_to_leaf_index(&key_1));
for depth in (0..smt.depth()).rev() {
let is_right = index.is_value_odd();
index.move_up();
@ -500,6 +501,25 @@ fn test_checked_insertion() {
}
assert_eq!(mutations.new_root, root_2);
let mut smt = smt;
//smt.apply_muts(mutations);
mutations.apply(&mut smt);
let smt = smt;
assert_eq!(smt.root(), root_2);
let mut mutations = smt.start_muts();
smt.good_insert(&mut mutations, key_2, EMPTY_WORD);
assert_eq!(mutations.new_root, root_1);
drop(mutations);
let mut mutations = smt.start_muts();
smt.good_insert(&mut mutations, key_3, value_3);
assert_eq!(mutations.new_root, root_3);
let mut smt = smt;
mutations.apply(&mut smt);
assert_eq!(smt.root(), root_3);
}
/// Tests that 2 key-value pairs stored in the same leaf have the same path

View file

@ -2,7 +2,6 @@ use alloc::{
collections::{btree_map::Entry, BTreeMap},
vec::Vec,
};
use tap::Pipe;
use super::{EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, NodeIndex};
use crate::{
@ -154,15 +153,6 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
return Ok(value);
}
//let mut mutations = Mutations::new();
//self.prospective_insert(&mut mutations, key.clone(), value.clone());
//let Mutations {
// mut node_removals,
// mut node_additions,
// mut pair_insertions,
// new_root,
//} = mutations;
let mut control = self.clone();
control.insert(key.clone(), value.clone());
@ -174,18 +164,6 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
for depth in (0..index.depth()).rev() {
index.move_up();
assert_eq!(depth, index.depth());
let control_node = control.get_inner_node(index);
let test_node = mutations.maybe_get_node(index).or_empty();
//let test_node = match mutations.get_inner_node(index) {
// Some(node) => node,
// None => {
// let &child = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1);
// InnerNode { left: child, right: child }
// },
//};
assert_eq!(control_node, test_node, "nodes at {index:?} are different!");
}
assert_eq!(control.root(), mutations.new_root);
@ -196,118 +174,12 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
self.apply_muts(mutations);
// Actual mutations start here.
//self.apply_mutations(mutations);
//for (key, value) in pair_insertions.drain(..) {
// self.insert_value(key, value);
//}
//
//for index in node_removals.drain(..) {
// self.remove_inner_node(index);
//}
//
//for (index, new_node) in node_additions.drain(..) {
// self.insert_inner_node(index, new_node);
//}
//
//self.set_root(new_root);
Ok(old_value)
}
//fn prospective_insert(
// &self,
// mutations: &mut Mutations<DEPTH, Self::Key, Self::Value>,
// key: Self::Key,
// value: Self::Value,
//) {
// let old_value = self.get_value(&key);
// // If the old value and new value are the same, there's nothing to update.
// if value == old_value {
// return;
// }
//
// let mut node_index = {
// let leaf_index: LeafIndex<DEPTH> = Self::key_to_leaf_index(&key);
// NodeIndex::from(leaf_index)
// };
//
// //let mut new_child_hash = self.hash_prospective_leaf(&key, &value);
// //let existing_leaf = match self.maybe_get_leaf(&key) {
// // Some(leaf) => Some(leaf),
// // None => mutations
// // .pair_insertions
// // .iter()
// // .find(|&pair| pair.0 == key)
// // .cloned()
// // .map(|pair| self.get_prospective_leaf(None, &pair.0, &pair.1)),
// //};
// let maybe_prospective_leaf = mutations
// .pair_insertions
// .iter()
// .find(|&pair| pair.0 == key)
// .cloned()
// .map(|pair| self.get_prospective_leaf(None, &pair.0, &pair.1));
// std::dbg!(&maybe_prospective_leaf);
// let existing_leaf = match maybe_prospective_leaf {
// Some(leaf) => Some(leaf),
// None => self.maybe_get_leaf(&key),
// };
// let new_child = self.get_prospective_leaf(existing_leaf.as_ref(), &key, &value);
// let mut new_child_hash = Self::hash_leaf(&new_child);
// for node_depth in (0..node_index.depth()).rev() {
// let is_right = node_index.is_value_odd();
// node_index.move_up();
//
// //let old_node = self.get_inner_node(node_index);
// //let old_node = mutations.get_inner_node(node_index).unwrap_or_else(|| {
// // std::eprintln!("nothing in mutations, getting existing");
// // self.get_inner_node(node_index)
// //});
// let old_node = match mutations.get_inner_node(node_index) {
// Some(old_node) => {
// std::eprintln!("old node found in mutations, using that");
// old_node
// },
// None => self.get_inner_node(node_index),
// };
// let new_node = if is_right {
// InnerNode {
// left: old_node.left,
// right: new_child_hash,
// }
// } else {
// InnerNode {
// left: new_child_hash,
// right: old_node.right,
// }
// };
// if let Some(prospective_node) = mutations.get_inner_node_mut(node_index) {
// *prospective_node = new_node.clone();
// }
//
// // The next iteration will operate on this node's new hash.
// new_child_hash = new_node.hash();
//
// let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth);
// if new_child_hash == equivalent_empty_hash {
// // If a subtree is empty, we can remove the inner node, since it's equal to the
// // default value.
// mutations.node_removals.push(node_index);
// } else {
// mutations.node_additions.push((node_index, new_node));
// }
// }
//
// // Once we're at depth 0, the last node we made is the new root.
// mutations.new_root = new_child_hash;
// mutations.pair_insertions.push((key, value));
//}
fn good_insert(
&self,
mutations: &mut Muts<DEPTH, Self::Key, Self::Value>,
mutations: &mut MutationSet<DEPTH, Self>,
key: Self::Key,
value: Self::Value,
) {
@ -316,8 +188,6 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
return;
}
std::eprintln!("{}: performing insert with key {key:?}", func!());
let mut node_index = {
let leaf_index: LeafIndex<DEPTH> = Self::key_to_leaf_index(&key);
NodeIndex::from(leaf_index)
@ -325,67 +195,22 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
let mut control = self.clone();
control.apply_muts(mutations.clone());
//control.insert(key.clone(), value.clone());
//let existing_leaf = self.maybe_get_leaf(&key);
//let mut maybe_leaf = mutations.maybe_get_values(&key);
//assert!(matches!(maybe_leaf.len(), 0 | 1));
//let maybe_leaf = maybe_leaf.pop();
//let existing_leaf = match maybe_leaf {
// Some(existing_value) => {
// let prospective_leaf =
// self.get_prospective_leaf(existing_leaf.as_ref(), &key, &existing_value);
// assert_eq!(existing_leaf, None);
// Some(prospective_leaf)
// },
// None => existing_leaf,
//};
//
//let new_child = self.get_prospective_leaf(existing_leaf.as_ref(), &key, &value);
//assert_eq!(self.maybe_get_leaf(&key), None, "key {key:?} already has values?");
//let new_leaf = self.get_prospective_leaf(None, &key, &value);
let old_leaf = mutations.maybe_get_leaf(self, &key);
assert_eq!(control.maybe_get_leaf(&key), old_leaf);
if mutations.pair_insertions.is_empty() {
std::eprintln!(
"no insertions yet, our current leaf is {:?}",
self.maybe_get_leaf(&key)
);
}
let new_leaf = self.get_prospective_leaf(old_leaf.as_ref(), &key, &value);
let leaf_hash = Self::hash_leaf(&new_leaf);
assert_eq!(control.hash_prospective_leaf(&key, &value), leaf_hash);
let mut new_child_hash = leaf_hash;
// Prospective values for this key.
//let prospective_values = mutations.maybe_get_values(&key);
//assert_eq!(prospective_values.len(), 0);
//let new_leaf = match mutations.maybe_get_values(&key) {
//
//}
//let ref control_leaf = control.get_leaf(&key);
//assert_eq!(control_leaf, &existing_leaf.unwrap());
//let control_hash = Self::hash_leaf(control_leaf);
//assert_eq!(control_hash, new_child_hash);
//
//assert_eq!(control_leaf, &new_child);
for node_depth in (0..node_index.depth()).rev() {
let is_right = node_index.is_value_odd();
node_index.move_up();
let old_node = match mutations.get_inner_node(node_index) {
Some(prospective) => {
//let existing = self.get_inner_node(node_index);
//let &equivalent_empty = EmptySubtreeRoots::entry(DEPTH, node_depth);
//if existing.hash() != equivalent_empty && existing != prospective {
// //assert_eq!(existing, prospective);
//}
prospective
},
None => self.get_inner_node(node_index),
};
let old_node = mutations
.get_inner_node(node_index)
.unwrap_or_else(|| self.get_inner_node(node_index));
assert_eq!(control.get_inner_node(node_index), old_node);
let new_node = if is_right {
@ -406,12 +231,6 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
control.apply_muts(mutations);
let control_old_node = control.get_inner_node(node_index);
assert_eq!(control_old_node, old_node);
//control.insert(key.clone(), value.clone());
//let control_leaf = control.get_leaf(&key);
//assert_eq!(control_leaf, new_leaf);
//let control_new_node = control.get_inner_node(node_index);
//assert_eq!(control_new_node, new_node);
}
let mut modified_control = control.clone();
@ -421,16 +240,12 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
// The next iteration will operate on this node's new hash.
new_child_hash = new_node.hash();
std::eprintln!("\n{}: new_child_hash={new_child_hash:?}", func!());
let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth);
if new_child_hash == equivalent_empty_hash {
mutations.maybe_remove_node(node_index);
//mutations.mutations.push(Mutation::Removal(node_index));
//std::eprintln!("did removal do something? {did_change}");
} else {
mutations.maybe_insert_inner_node(node_index, new_node);
mutations.insert_inner_node(node_index, new_node);
let leaf_index = NodeIndex::from(Self::key_to_leaf_index(&key));
let leaf_parent = mutations.get_inner_node(leaf_index.as_up()).unwrap();
@ -452,83 +267,40 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8>: Clone {
assert_eq!(control.root(), mutations.new_root);
}
fn start_muts(&self) -> Muts<DEPTH, Self::Key, Self::Value> {
Muts::<DEPTH, Self::Key, Self::Value> {
//mutations: Default::default(),
fn start_muts(&self) -> MutationSet<DEPTH, Self> {
MutationSet::<DEPTH, Self> {
node_mutations: Default::default(),
pair_insertions: Default::default(),
new_root: self.root(),
}
}
//fn apply_mutations(&mut self, mut mutations: Mutations<DEPTH, Self::Key, Self::Value>) {
// for (key, value) in mutations.pair_insertions.drain(..) {
// self.insert_value(key, value);
// }
//
// for index in mutations.node_removals.drain(..) {
// self.remove_inner_node(index);
// }
//
// for (index, new_node) in mutations.node_additions.drain(..) {
// self.insert_inner_node(index, new_node);
// }
//
// self.set_root(mutations.new_root);
//}
fn apply_muts(&mut self, mutations: Muts<DEPTH, Self::Key, Self::Value>) {
fn apply_muts(&mut self, mutations: MutationSet<DEPTH, Self>) {
use NodeMutation::*;
let Muts {
let MutationSet {
node_mutations,
pair_insertions,
new_root,
} = mutations;
#[cfg(any(debug_assertions, test))]
let mut control = self.clone();
if cfg!(any(debug_assertions, test)) {
for (key, value) in pair_insertions.iter().cloned() {
control.insert(key, value);
}
}
for (index, mutation) in node_mutations.into_iter() {
match mutation {
Removal => self.remove_inner_node(index),
Addition(node) => self.insert_inner_node(index, node),
}
//if cfg!(any(debug_assertions, test)) {
// let control_node = control.get_inner_node(index);
// let test_node = self.get_inner_node(index);
// assert_eq!(control_node, test_node);
//}
}
for (key, value) in pair_insertions.into_iter() {
self.insert_value(key, value);
}
self.set_root(new_root);
if cfg!(any(debug_assertions, test)) {
assert_eq!(control.root(), self.root());
}
//for mutation in mutations.node_mutations.drain(..) {
// match mutation {
// Removal(idx) => self.remove_inner_node(idx),
// Addition(idx, node)
// }
//}
//use Mutation::*;
//for mutation in mutations.mutations.drain(..) {
// match mutation {
// Removal(idx) => self.remove_inner_node(idx),
// Addition(idx, node) => self.insert_inner_node(idx, node),
// PairInsertion(key, value) => {
// self.insert_value(key, value);
// },
// }
//}
}
/// Recomputes the branch nodes (including the root) from `index` all the way to the root.
/// `node_hash_at_index` is the hash of the node stored at index.
@ -688,192 +460,83 @@ impl<const DEPTH: u8> TryFrom<NodeIndex> for LeafIndex<DEPTH> {
}
}
// MUTATIONS
//#[derive(Debug, Clone, PartialEq)]
//#[cfg(not(test))]
//pub enum Mutation<K, V> {
// Removal(NodeIndex),
// Addition(NodeIndex, InnerNode),
// PairInsertion(K, V),
//}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NodeMutation {
Removal,
Addition(InnerNode),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Muts<const DEPTH: u8, K, V> {
//mutations: Vec<Mutation<K, V>>,
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MutationSet<const DEPTH: u8, T>
where
T: SparseMerkleTree<DEPTH> + Clone,
{
node_mutations: BTreeMap<NodeIndex, NodeMutation>,
pair_insertions: Vec<(K, V)>,
pair_insertions: Vec<(T::Key, T::Value)>,
new_root: RpoDigest,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MaybeNode<const DEPTH: u8> {
inner: Option<InnerNode>,
index: NodeIndex,
}
impl<const DEPTH: u8> MaybeNode<DEPTH> {
pub fn from(inner: InnerNode, index: NodeIndex) -> Self {
Self { inner: Some(inner), index }
}
pub fn new_empty(index: NodeIndex) -> Self {
Self { inner: None, index }
}
pub fn or_empty(self) -> InnerNode {
match self.inner {
Some(node) => node,
None => {
let &child = EmptySubtreeRoots::entry(DEPTH, self.index.depth() + 1);
InnerNode { left: child, right: child }
},
}
}
}
impl<const DEPTH: u8, K: PartialEq, V: Clone> Muts<DEPTH, K, V> {
fn maybe_get_values(&self, key: &K) -> Vec<V> {
self.pair_insertions
.iter()
.filter_map(|(cur_key, cur_value)| if cur_key == key { Some(cur_value) } else { None })
.cloned()
.collect()
}
fn maybe_get_leaf<T>(&self, tree: &T, key: &K) -> Option<T::Leaf>
impl<const DEPTH: u8, T> MutationSet<DEPTH, T>
where
T: SparseMerkleTree<DEPTH, Key = K, Value = V>,
T: SparseMerkleTree<DEPTH>,
{
fn maybe_get_leaf(&self, tree: &T, key: &T::Key) -> Option<T::Leaf> {
std::eprintln!("BEGIN");
let leaf_index = T::key_to_leaf_index(key);
let pairs_at_index = self
.pair_insertions
.iter()
.filter(|&pair| T::key_to_leaf_index(&pair.0) == leaf_index);
let inital_acc: Option<T::Leaf> = tree.maybe_get_leaf(&key);
let inital_acc = tree.maybe_get_leaf(&key);
let mut iteration: u32 = 0;
let leaf = pairs_at_index.fold(inital_acc, |acc, (k, v)| {
//
Some(tree.get_prospective_leaf(acc.as_ref(), k, v))
std::eprintln!(" iteration {iteration}");
iteration += 1;
let existing_leaf = acc.as_ref();
Some(tree.get_prospective_leaf(existing_leaf, k, v))
});
std::eprintln!("END");
leaf
}
fn get_inner_node(&self, index: NodeIndex) -> Option<InnerNode> {
use NodeMutation::*;
match self.node_mutations.get(&index) {
Some(Addition(node)) => Some(node.clone()),
Some(Removal) => {
//std::eprintln!("{}: found other mutation? wat do. {other:?}", func!());
//panic!();
//let &empty_child_hash = EmptySubtreeRoots::entry(DEPTH, index.depth());
let node = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1);
Some(InnerNode { left: *node, right: *node })
self.node_mutations.get(&index).map(|mutation| match mutation {
Addition(node) => node.clone(),
Removal => {
let &child = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1);
InnerNode { left: child, right: child }
},
None => None,
})
}
//use Mutation::*;
//self.mutations.iter().find_map(|mutation| match mutation {
// Addition(idx, node) if *idx == index => Some(node.clone()),
// _ => None,
//})
}
fn maybe_get_node(&self, index: NodeIndex) -> MaybeNode<DEPTH> {
pub fn insert_inner_node(&mut self, index: NodeIndex, new_node: InnerNode) {
use Entry::*;
use NodeMutation::*;
match self.node_mutations.get(&index) {
Some(Addition(node)) => MaybeNode::from(node.clone(), index),
Some(Removal) => {
MaybeNode::from(MaybeNode::<DEPTH> { inner: None, index }.or_empty(), index)
},
None => MaybeNode::new_empty(index),
}
}
fn get_inner_node_mut(&mut self, index: NodeIndex) -> Option<&mut InnerNode> {
//use Mutation::*;
use NodeMutation::*;
//self.mutations.iter_mut().find_map(|mutation| match mutation {
// Addition(idx, node) if *idx == index => Some(node),
// Removal(idx) if *idx == index => {
// panic!();
// },
// _ => None,
//})
match self.node_mutations.get_mut(&index) {
Some(Addition(node)) => Some(node),
_ => None,
}
}
pub fn maybe_insert_inner_node(&mut self, index: NodeIndex, node: InnerNode) -> bool {
//use Mutation::*;
use NodeMutation::*;
std::eprintln!(
"attempting to insert inner node at {index:?}, with {} mutations",
self.node_mutations.len()
);
let mut mutated: bool = false;
//let mut found_existing: bool = false;
// XXX
let orig = node.clone();
let orig = new_node.clone();
let mut node = Some(node);
use Entry::*;
match self.node_mutations.entry(index) {
Vacant(entry) => {
let node = node.take().unwrap();
std::eprintln!("{}: normal insert", func!());
entry.insert(Addition(node));
entry.insert(Addition(new_node));
},
Occupied(mut entry) => match entry.get_mut() {
Addition(ref existing) if Some(existing) == node.as_ref() => {
std::eprintln!("{}: existing entry is identical; doing nothing", func!());
},
Addition(existing) => {
let node = node.take().unwrap();
std::eprintln!(
"{}: modifying existing addition entry from {:?} to {:?}",
func!(),
existing.hash(),
node.hash()
);
mutated = true;
*existing = node;
// If there's an existing addition with this key, then overwrite it to be an
// addition of this new node instead.
*existing = new_node;
},
Removal => {
std::eprintln!("{}: removal found; changing to addition", func!());
mutated = true;
entry.insert(Addition(node.take().unwrap()));
// Likewise a removal of this key gets overwritten with an addition.
entry.insert(Addition(new_node));
},
},
};
std::eprintln!("");
//match self.node_mutations.get_mut(&index) {
// Some(mutation) => match mutation {
// Addition(existing) => {
// *existing = node.take().unwrap();
// found_existing = true;
// mutated = true;
// },
// Removal(existing) => {
// self.node_mutations.remove()
// }
// },
//};
// XXX: sanity check
match self.get_inner_node(index) {
Some(inserted) => assert_eq!(orig, inserted),
@ -883,67 +546,23 @@ impl<const DEPTH: u8, K: PartialEq, V: Clone> Muts<DEPTH, K, V> {
assert_eq!(orig, node);
},
};
mutated
//self.mutations.retain_mut(|mutation: &mut Mutation<_, _>| match mutation {
// Removal(idx) if *idx == index => {
// mutated = true;
// std::eprintln!("maybe_insert_node(): found removal at same index, removing");
// false
// },
// Addition(idx, cur_node) => {
// // FIXME: unnecessary clones
// if Some(cur_node.clone()) == node.as_mut().cloned() {
// found_existing = true;
// std::eprintln!("maybe_insert_node(): found identical addition, ignoring");
// panic!();
// } else if *idx == index {
// mutated = true;
// std::eprintln!(
// "maybe_insert_node(): found different addition at same index, replacing"
// );
// *cur_node = node.take().unwrap(); // XXX
// }
// true
// },
// _ => true,
//});
//
//if !mutated && !found_existing {
// mutated = true;
// self.mutations.push(Addition(index, node.take().unwrap()));
//}
//mutated
}
pub fn maybe_remove_node(&mut self, index: NodeIndex) -> bool {
use NodeMutation::*;
std::eprintln!(
"attempting to remove inner node at {index:?} with {} mutations",
self.node_mutations.len()
);
let mut mutated: bool = false;
pub fn maybe_remove_node(&mut self, index: NodeIndex) {
use Entry::*;
use NodeMutation::*;
match self.node_mutations.entry(index) {
Vacant(entry) => {
std::eprintln!("{}: normal removal", func!());
mutated = true;
entry.insert(Removal);
},
Occupied(mut entry) => match entry.get_mut() {
Addition(_) => {
std::eprintln!("{}: found addition; changing to removal", func!());
mutated = true;
entry.insert(Removal);
},
Removal => {
std::eprintln!("{}: identical to existing removal; doing nothing", func!());
Removal => (),
},
},
};
}
// XXX: sanity check
match self.get_inner_node(index) {
@ -955,72 +574,80 @@ impl<const DEPTH: u8, K: PartialEq, V: Clone> Muts<DEPTH, K, V> {
},
None => (),
};
mutated
// use Mutation::*;
//
// let mut mutated: bool = false;
// let mut found_existing: bool = false;
//
// self.mutations.retain_mut(|mutation: &mut Mutation<_, _>| match mutation {
// Removal(idx) if *idx == index => {
// found_existing = true;
// std::eprintln!(
// "maybe_remove_node(): found a removal with same index, doing nothing"
// );
// true
// },
// Addition(idx, _) if *idx == index => {
// mutated = true;
// std::eprintln!("maybe_remove_node(): found an addition with same index, removing.");
// false
// },
// _ => true,
// });
//
// if !found_existing {
// mutated = true;
// std::eprintln!("maybe_remove_node(): pushing Removal");
// self.mutations.push(Removal(index));
// }
// mutated
}
}
//#[derive(Debug, Clone, PartialEq)]
//pub struct Mutations<const DEPTH: u8, K, V> {
// node_removals: Vec<NodeIndex>,
// node_additions: Vec<(NodeIndex, InnerNode)>,
// pair_insertions: Vec<(K, V)>,
// new_root: RpoDigest,
//}
//
//impl<const DEPTH: u8, K, V> Mutations<DEPTH, K, V> {
// pub fn new() -> Self {
// Mutations {
// node_removals: vec![],
// node_additions: vec![],
// pair_insertions: vec![],
// new_root: Default::default(),
// }
// }
//
// pub fn get_inner_node(&self, index: NodeIndex) -> Option<InnerNode> {
// self.node_additions
// .iter()
// .find(|(idx, _)| *idx == index)
// .map(|(_, node)| node.clone())
// //.unwrap_or_else(|| {
// // let &child = EmptySubtreeRoots::entry(DEPTH, index.depth() + 1);
// // InnerNode { left: child, right: child }
// //})
// }
//
// pub fn get_inner_node_mut(&mut self, index: NodeIndex) -> Option<&mut InnerNode> {
// self.node_additions
// .iter_mut()
// .find(|(idx, _)| *idx == index)
// .map(|(_, node)| node)
// }
//}
pub fn insert(&mut self, tree: &T, key: T::Key, value: T::Value) {
// This functions calculations are eager. Future work could make them lazy?
let old_value = tree.get_value(&key);
if value == old_value {
return;
}
let mut node_index = {
let leaf_index: LeafIndex<DEPTH> = T::key_to_leaf_index(&key);
NodeIndex::from(leaf_index)
};
let old_leaf = self.maybe_get_leaf(tree, &key);
let new_leaf = tree.get_prospective_leaf(old_leaf.as_ref(), &key, &value);
let mut new_child_hash = T::hash_leaf(&new_leaf);
for node_depth in (0..node_index.depth()).rev() {
let is_right = node_index.is_value_odd();
node_index.move_up();
let old_node = self
.get_inner_node(node_index)
.unwrap_or_else(|| tree.get_inner_node(node_index));
let new_node = if is_right {
InnerNode {
left: old_node.left,
right: new_child_hash,
}
} else {
InnerNode {
left: new_child_hash,
right: old_node.right,
}
};
// The next iteration will operate on this new node's new.
new_child_hash = new_node.hash();
let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth);
if new_child_hash == equivalent_empty_hash {
self.maybe_remove_node(node_index);
} else {
self.insert_inner_node(node_index, new_node);
}
}
// Once we're at depth 0, the last node we made is the new root.
self.new_root = new_child_hash;
self.pair_insertions.push((key, value));
}
pub fn apply(self, tree: &mut T) {
use NodeMutation::*;
let MutationSet {
node_mutations,
pair_insertions,
new_root,
} = self;
for (index, mutation) in node_mutations {
match mutation {
Removal => tree.remove_inner_node(index),
Addition(node) => tree.insert_inner_node(index, node),
}
}
for (key, value) in pair_insertions {
tree.insert_value(key, value);
}
tree.set_root(new_root);
}
}