oasis_core_runtime/storage/mkvs/tree/
mod.rs1#[macro_use]
2mod macros;
3
4mod commit;
5mod errors;
6mod insert;
7mod iterator;
8mod lookup;
9mod marshal;
10mod node;
11mod overlay;
12mod prefetch;
13mod remove;
14
15pub use errors::*;
16pub use node::*;
17pub use overlay::*;
18
19use std::{cell::RefCell, fmt, rc::Rc};
20
21use anyhow::Result;
22
23use crate::{
24 common::{crypto::hash::Hash, namespace::Namespace},
25 storage::mkvs::{self, cache::*, sync::*},
26};
27
28pub struct Options {
30 node_capacity: usize,
31 value_capacity: usize,
32 root: Option<Root>,
33 root_type: Option<RootType>,
34}
35
36impl Default for Options {
37 fn default() -> Self {
38 Self {
39 node_capacity: 50_000,
40 value_capacity: 16 * 1024 * 1024,
41 root: None,
42 root_type: None,
43 }
44 }
45}
46
47#[derive(Default)]
51pub struct Builder {
52 options: Options,
53}
54
55impl Builder {
56 pub fn new() -> Self {
58 Builder::default()
59 }
60
61 pub fn with_capacity(mut self, node_capacity: usize, value_capacity: usize) -> Self {
71 self.options.node_capacity = node_capacity;
72 self.options.value_capacity = value_capacity;
73 self
74 }
75
76 pub fn with_root(mut self, root: Root) -> Self {
82 self.options.root = Some(root);
83 self
84 }
85
86 pub fn with_root_type(mut self, root_type: RootType) -> Self {
92 self.options.root_type = Some(root_type);
93 self
94 }
95
96 pub fn build(self, read_syncer: Box<dyn ReadSync>) -> Tree {
98 assert!(
99 self.options.root_type.is_some() || self.options.root.is_some(),
100 "mkvs/tree: neither root type nor storage root specified"
101 );
102 if let Some(root) = self.options.root {
103 if let Some(root_type) = self.options.root_type {
104 assert!(
105 root.root_type == root_type,
106 "mkvs/tree: specified storage root and incompatible root type"
107 );
108 }
109 }
110 Tree::new(read_syncer, &self.options)
111 }
112}
113
114pub struct Tree {
116 pub(crate) cache: RefCell<Box<LRUCache>>,
117 pub(crate) root_type: RootType,
118}
119
120unsafe impl Send for Tree {}
122
123impl Tree {
124 pub fn new(read_syncer: Box<dyn ReadSync>, opts: &Options) -> Tree {
126 let root_type = if opts.root.is_none() {
127 opts.root_type.unwrap()
128 } else {
129 opts.root.unwrap().root_type
130 };
131 let tree = Tree {
132 cache: RefCell::new(LRUCache::new(
133 opts.node_capacity,
134 opts.value_capacity,
135 read_syncer,
136 root_type,
137 )),
138 root_type,
139 };
140
141 if let Some(root) = opts.root {
142 tree.cache
143 .borrow_mut()
144 .set_pending_root(Rc::new(RefCell::new(NodePointer {
145 clean: true,
146 hash: root.hash,
147 ..Default::default()
148 })));
149 tree.cache.borrow_mut().set_sync_root(root);
150 }
151
152 tree
153 }
154
155 pub fn builder() -> Builder {
157 Builder::new()
158 }
159}
160
161impl fmt::Debug for Tree {
162 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
163 self.cache.borrow().get_pending_root().fmt(f)
164 }
165}
166
167impl mkvs::FallibleMKVS for Tree {
168 fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
169 Tree::get(self, key)
170 }
171
172 fn get_proof(&self, key: &[u8]) -> Result<Option<Proof>> {
173 Tree::get_proof(self, key)
174 }
175
176 fn cache_contains_key(&self, key: &[u8]) -> bool {
177 Tree::cache_contains_key(self, key)
178 }
179
180 fn insert(&mut self, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>> {
181 Tree::insert(self, key, value)
182 }
183
184 fn remove(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>> {
185 Tree::remove(self, key)
186 }
187
188 fn prefetch_prefixes(&self, prefixes: &[mkvs::Prefix], limit: u16) -> Result<()> {
189 Tree::prefetch_prefixes(self, prefixes, limit)
190 }
191
192 fn iter(&self) -> Box<dyn mkvs::Iterator + '_> {
193 Box::new(Tree::iter(self))
194 }
195
196 fn commit(&mut self, namespace: Namespace, version: u64) -> Result<Hash> {
197 Tree::commit(self, namespace, version)
198 }
199}
200
201#[cfg(test)]
202mod node_test;
203#[cfg(test)]
204mod tree_bench;
205#[cfg(test)]
206mod tree_test;