mirror of
https://github.com/aljazceru/pubky-core.git
synced 2025-12-31 21:04:34 +01:00
feat: cache Node hash
This commit is contained in:
@@ -6,7 +6,6 @@ use crate::{Hash, Hasher, HASH_LEN};
|
||||
|
||||
// TODO: room for improvement (pending actual benchmarks to justify):
|
||||
// - cache encoding
|
||||
// - cache hashing
|
||||
|
||||
// TODO: remove unwrap
|
||||
// TODO: KeyType and ValueType
|
||||
@@ -24,6 +23,10 @@ pub struct Node {
|
||||
|
||||
// Metadata that should not be encoded.
|
||||
ref_count: u64,
|
||||
|
||||
// Memoized hashes
|
||||
/// The Hash of the node, if None then something changed, and the hash should be recomputed.
|
||||
hash: Option<Hash>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -47,6 +50,7 @@ impl Node {
|
||||
right: None,
|
||||
|
||||
ref_count: 0,
|
||||
hash: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +99,13 @@ impl Node {
|
||||
}
|
||||
|
||||
/// Returns the hash of the node.
|
||||
pub fn hash(&self) -> Hash {
|
||||
let encoded = self.canonical_encode();
|
||||
hash(&encoded)
|
||||
pub fn hash(&mut self) -> Hash {
|
||||
self.hash.unwrap_or_else(|| {
|
||||
let encoded = self.canonical_encode();
|
||||
let hash = hash(&encoded);
|
||||
self.hash = Some(hash);
|
||||
hash
|
||||
})
|
||||
}
|
||||
|
||||
// === Private Methods ===
|
||||
@@ -105,6 +113,8 @@ impl Node {
|
||||
/// Set the value.
|
||||
pub(crate) fn set_value(&mut self, value: &[u8]) -> &mut Self {
|
||||
self.value = value.into();
|
||||
self.hash = None;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
@@ -124,6 +134,7 @@ impl Node {
|
||||
Branch::Left => self.left = new_child,
|
||||
Branch::Right => self.right = new_child,
|
||||
};
|
||||
self.hash = None;
|
||||
|
||||
self
|
||||
}
|
||||
@@ -250,5 +261,6 @@ fn decode_node(data: (u64, &[u8])) -> Node {
|
||||
right,
|
||||
|
||||
ref_count,
|
||||
hash: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ pub(crate) fn remove<'a>(
|
||||
node.decrement_ref_count().save(nodes_table);
|
||||
|
||||
match branch {
|
||||
Branch::Left => node.set_left_child(root.map(|n| n.hash())),
|
||||
Branch::Right => node.set_right_child(root.map(|n| n.hash())),
|
||||
Branch::Left => node.set_left_child(root.map(|mut n| n.hash())),
|
||||
Branch::Right => node.set_right_child(root.map(|mut n| n.hash())),
|
||||
};
|
||||
|
||||
node.increment_ref_count().save(nodes_table);
|
||||
@@ -107,7 +107,7 @@ fn zip_up(
|
||||
.decrement_ref_count()
|
||||
.save(nodes_table)
|
||||
// save new version
|
||||
.set_left_child(previous.map(|n| n.hash()))
|
||||
.set_left_child(previous.map(|mut n| n.hash()))
|
||||
.increment_ref_count()
|
||||
.save(nodes_table);
|
||||
|
||||
@@ -127,7 +127,7 @@ fn zip_up(
|
||||
.decrement_ref_count()
|
||||
.save(nodes_table)
|
||||
// save new version
|
||||
.set_right_child(previous.map(|n| n.hash()))
|
||||
.set_right_child(previous.map(|mut n| n.hash()))
|
||||
.increment_ref_count()
|
||||
.save(nodes_table);
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ fn verify_children_rank(treap: &HashTreap, node: Option<Node>) -> bool {
|
||||
fn assert_root(treap: &HashTreap, expected_root_hash: &str) {
|
||||
let root_hash = treap
|
||||
.root()
|
||||
.map(|n| n.hash())
|
||||
.map(|mut n| n.hash())
|
||||
.expect("Has root hash after insertion");
|
||||
|
||||
assert_eq!(
|
||||
@@ -167,8 +167,8 @@ fn into_mermaid_graph(treap: &HashTreap) -> String {
|
||||
|
||||
graph.push_str("graph TD;\n");
|
||||
|
||||
if let Some(root) = treap.root() {
|
||||
build_graph_string(&treap, &root, &mut graph);
|
||||
if let Some(mut root) = treap.root() {
|
||||
build_graph_string(&treap, &mut root, &mut graph);
|
||||
}
|
||||
|
||||
graph.push_str(&format!(
|
||||
@@ -178,28 +178,28 @@ fn into_mermaid_graph(treap: &HashTreap) -> String {
|
||||
graph
|
||||
}
|
||||
|
||||
fn build_graph_string(treap: &HashTreap, node: &Node, graph: &mut String) {
|
||||
fn build_graph_string(treap: &HashTreap, node: &mut Node, graph: &mut String) {
|
||||
let key = format_key(node.key());
|
||||
let node_label = format!("{}(({}))", node.hash(), key);
|
||||
|
||||
// graph.push_str(&format!("## START node {}\n", node_label));
|
||||
if let Some(child) = treap.get_node(node.left()) {
|
||||
if let Some(mut child) = treap.get_node(node.left()) {
|
||||
let key = format_key(child.key());
|
||||
let child_label = format!("{}(({}))", child.hash(), key);
|
||||
|
||||
graph.push_str(&format!(" {} --l--> {};\n", node_label, child_label));
|
||||
build_graph_string(&treap, &child, graph);
|
||||
build_graph_string(&treap, &mut child, graph);
|
||||
} else {
|
||||
graph.push_str(&format!(" {} -.-> {}l((l));\n", node_label, node.hash()));
|
||||
graph.push_str(&format!(" class {}l null;\n", node.hash()));
|
||||
}
|
||||
|
||||
if let Some(child) = treap.get_node(node.right()) {
|
||||
if let Some(mut child) = treap.get_node(node.right()) {
|
||||
let key = format_key(child.key());
|
||||
let child_label = format!("{}(({}))", child.hash(), key);
|
||||
|
||||
graph.push_str(&format!(" {} --r--> {};\n", node_label, child_label));
|
||||
build_graph_string(&treap, &child, graph);
|
||||
build_graph_string(&treap, &mut child, graph);
|
||||
} else {
|
||||
graph.push_str(&format!(" {} -.-> {}r((r));\n", node_label, node.hash()));
|
||||
graph.push_str(&format!(" class {}r null;\n", node.hash()));
|
||||
|
||||
@@ -68,7 +68,7 @@ impl<'treap> HashTreap<'treap> {
|
||||
.root_hash_inner(&roots_table)
|
||||
.and_then(|hash| Node::open(&nodes_table, hash));
|
||||
|
||||
let new_root = crate::operations::insert(&mut nodes_table, old_root, key, value);
|
||||
let mut new_root = crate::operations::insert(&mut nodes_table, old_root, key, value);
|
||||
|
||||
roots_table
|
||||
.insert(self.name.as_bytes(), new_root.hash().as_bytes().as_slice())
|
||||
@@ -96,7 +96,7 @@ impl<'treap> HashTreap<'treap> {
|
||||
|
||||
removed_node = old_node;
|
||||
|
||||
if let Some(new_root) = new_root {
|
||||
if let Some(mut new_root) = new_root {
|
||||
roots_table
|
||||
.insert(self.name.as_bytes(), new_root.hash().as_bytes().as_slice())
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user