oasis_core_runtime/storage/mkvs/tree/
commit.rs1use anyhow::Result;
2
3use crate::{
4 common::{crypto::hash::Hash, namespace::Namespace},
5 storage::mkvs::{
6 cache::{Cache, LRUCache, UpdateList},
7 tree::{Node, NodeBox, NodeKind, NodePtrRef, Root, Tree},
8 },
9};
10
11impl Tree {
12 pub fn commit(&mut self, namespace: Namespace, version: u64) -> Result<Hash> {
15 let mut update_list: UpdateList<LRUCache> = UpdateList::new();
16 let pending_root = self.cache.borrow().get_pending_root();
17 let new_hash = _commit(pending_root, &mut update_list)?;
18
19 update_list.commit(&mut self.cache.borrow_mut());
20
21 self.cache.borrow_mut().set_sync_root(Root {
22 namespace,
23 version,
24 root_type: self.root_type,
25 hash: new_hash,
26 });
27
28 Ok(new_hash)
29 }
30}
31
32pub fn _commit<C: Cache>(ptr: NodePtrRef, update_list: &mut UpdateList<C>) -> Result<Hash> {
33 if ptr.borrow().clean {
34 return Ok(ptr.borrow().hash);
35 }
36
37 match classify_noderef!(? ptr.borrow().node) {
38 NodeKind::None => {
39 ptr.borrow_mut().hash = Hash::empty_hash();
40 }
41 NodeKind::Internal => {
42 let some_node_ref = ptr.borrow().get_node();
43 if some_node_ref.borrow().is_clean() {
44 ptr.borrow_mut().hash = some_node_ref.borrow().get_hash();
45 } else {
46 let int_leaf_node = noderef_as!(some_node_ref, Internal).leaf_node.clone();
47 let int_left = noderef_as!(some_node_ref, Internal).left.clone();
48 let int_right = noderef_as!(some_node_ref, Internal).right.clone();
49
50 _commit(int_leaf_node, update_list)?;
51 _commit(int_left, update_list)?;
52 _commit(int_right, update_list)?;
53
54 some_node_ref.borrow_mut().update_hash();
55 ptr.borrow_mut().hash = some_node_ref.borrow().get_hash();
56
57 update_list.push(Box::new(move |_| {
58 noderef_as_mut!(some_node_ref, Internal).clean = true
59 }));
60 }
61 }
62 NodeKind::Leaf => {
63 let node_ref = ptr.borrow().get_node();
64 if node_ref.borrow().is_clean() {
65 ptr.borrow_mut().hash = node_ref.borrow().get_hash();
66 } else {
67 node_ref.borrow_mut().update_hash();
68 ptr.borrow_mut().hash = node_ref.borrow().get_hash();
69
70 update_list.push(Box::new(move |_| {
71 noderef_as_mut!(node_ref, Leaf).clean = true
72 }));
73 }
74 }
75 };
76
77 let closure_ptr = ptr.clone();
78 update_list.push(Box::new(move |cache| {
79 closure_ptr.borrow_mut().clean = true;
80 cache.commit_node(closure_ptr.clone());
82 }));
83
84 Ok(ptr.borrow().hash)
85}