1use crate::config::Config;
2use once_cell::sync::Lazy;
3use rand::prelude::SliceRandom;
4use rand::RngCore;
5use sha2::{Digest, Sha256};
6use std::collections::HashMap;
7use std::sync::{Arc, Mutex};
8
9use rocksdb::{ColumnFamilyDescriptor, Options, DB};
10
11pub static PERSISTOR: Lazy<Box<dyn Persistor + Send + Sync>> = Lazy::new(|| {
12 let config = Config::new();
13 match config.database.as_str() {
14 "" => Box::new(MemoryPersistor::new()),
15 path => Box::new(DatabasePersistor::new(path)),
16 }
17});
18
19pub const SIZE: usize = 32;
21
22pub type Word = [u8; SIZE];
24
25#[allow(dead_code)]
26#[derive(Debug)]
27pub struct PersistorAccessError(pub String);
28
29pub trait Persistor {
30 fn root_list(&self) -> Vec<Word>;
31 fn root_new(&self, handle: Word, root: Word) -> Result<Word, PersistorAccessError>;
32 fn root_temp(&self, root: Word) -> Result<Word, PersistorAccessError>;
33 fn root_get(&self, handle: Word) -> Result<Word, PersistorAccessError>;
34 fn root_set(&self, handle: Word, old: Word, new: Word) -> Result<Word, PersistorAccessError>;
35 fn root_delete(&self, handle: Word) -> Result<(), PersistorAccessError>;
36 fn branch_set(
37 &self,
38 left: Word,
39 right: Word,
40 digest: Word,
41 ) -> Result<Word, PersistorAccessError>;
42 fn branch_get(&self, branch: Word) -> Result<(Word, Word, Word), PersistorAccessError>;
43 fn leaf_set(&self, content: Vec<u8>) -> Result<Word, PersistorAccessError>;
44 fn leaf_get(&self, leaf: Word) -> Result<Vec<u8>, PersistorAccessError>;
45 fn stump_set(&self, digest: Word) -> Result<Word, PersistorAccessError>;
46 fn stump_get(&self, stump: Word) -> Result<Word, PersistorAccessError>;
47}
48
49#[derive(Clone)]
50pub struct MemoryPersistor {
51 roots: Arc<Mutex<HashMap<Word, (Word, bool)>>>,
52 branches: Arc<Mutex<HashMap<Word, (Word, Word, Word)>>>,
53 leaves: Arc<Mutex<HashMap<Word, Vec<u8>>>>,
54 stumps: Arc<Mutex<HashMap<Word, Word>>>,
55 references: Arc<Mutex<HashMap<Word, usize>>>,
56}
57
58impl MemoryPersistor {
59 pub fn new() -> Self {
60 Self {
61 roots: Arc::new(Mutex::new(HashMap::new())),
62 branches: Arc::new(Mutex::new(HashMap::new())),
63 leaves: Arc::new(Mutex::new(HashMap::new())),
64 stumps: Arc::new(Mutex::new(HashMap::new())),
65 references: Arc::new(Mutex::new(HashMap::new())),
66 }
67 }
68
69 fn reference_increment(&self, node: Word) {
70 let mut references = self.references.lock().expect("Failed to lock references");
71 match references.get(&node) {
72 Some(count) => {
73 let count_ = *count;
74 references.insert(node, count_ + 1);
75 }
76 None => {
77 references.insert(node, 1);
78 }
79 };
80 }
81
82 fn reference_decrement(&self, node: Word) {
83 let mut references = self.references.lock().expect("Failed to lock references");
84 match references.get(&node) {
85 Some(count_old) => {
86 let count_new = *count_old - 1;
87 if count_new > 0 {
88 references.insert(node, count_new);
89 } else {
90 references.remove(&node);
91 let mut branches = self.branches.lock().expect("Failed to lock branches");
92 if let Some((left, right, _)) = branches.get(&node) {
93 let left_ = *left;
94 let right_ = *right;
95 branches.remove(&node);
96 drop(references);
97 drop(branches);
98 self.reference_decrement(left_);
99 self.reference_decrement(right_);
100 } else {
101 let mut leaves = self.leaves.lock().expect("Failed to lock leaves");
102 let mut stumps = self.stumps.lock().expect("Failed to lock stumps");
103 if let Some(_) = leaves.get(&node) {
104 leaves.remove(&node);
105 } else if let Some(_) = stumps.get(&node) {
106 stumps.remove(&node);
107 }
108 }
109 }
110 }
111 None => {}
112 };
113 }
114}
115
116impl Persistor for MemoryPersistor {
117 fn root_list(&self) -> Vec<Word> {
118 let mut keys: Vec<Word> = self
119 .roots
120 .lock()
121 .expect("Failed to get locked roots")
122 .iter()
123 .filter(|&(_, &(_, is_persistent))| is_persistent)
124 .map(|(key, _)| key)
125 .cloned()
126 .collect();
127 keys.sort();
128 keys
129 }
130
131 fn root_new(&self, handle: Word, root: Word) -> Result<Word, PersistorAccessError> {
132 let mut roots = self.roots.lock().expect("Failed to lock roots map");
133 match roots.get(&handle) {
134 Some(_) => Err(PersistorAccessError(format!(
135 "Handle {:?} already exists",
136 handle
137 ))),
138 None => {
139 self.reference_increment(root);
140 roots.insert(handle, (root, true));
141 Ok(handle)
142 }
143 }
144 }
145
146 fn root_temp(&self, root: Word) -> Result<Word, PersistorAccessError> {
147 let mut roots = self.roots.lock().expect("Failed to lock roots map");
148 let mut handle: Word = [0 as u8; 32];
149 rand::thread_rng().fill_bytes(&mut handle);
150 match roots.get(&handle) {
151 Some(_) => Err(PersistorAccessError(format!(
152 "Handle {:?} already exists",
153 handle
154 ))),
155 None => {
156 self.reference_increment(root);
157 roots.insert(handle, (root, false));
158 Ok(handle)
159 }
160 }
161 }
162
163 fn root_get(&self, handle: Word) -> Result<Word, PersistorAccessError> {
164 match self
165 .roots
166 .lock()
167 .expect("Failed to lock roots map")
168 .get(&handle)
169 {
170 Some((root, _)) => Ok(*root),
171 None => Err(PersistorAccessError(format!(
172 "Handle {:?} not found",
173 handle
174 ))),
175 }
176 }
177
178 fn root_set(&self, handle: Word, old: Word, new: Word) -> Result<Word, PersistorAccessError> {
179 let mut roots = self.roots.lock().expect("Failed to lock roots map");
180 match roots.get(&handle) {
181 Some((root, true)) if *root == old => {
182 self.reference_increment(new);
183 self.reference_decrement(old);
184 roots.insert(handle, (new, true));
185 Ok(handle)
186 }
187 Some((_, false)) => Err(PersistorAccessError(format!(
188 "Handle {:?} is temporary",
189 handle
190 ))),
191 Some((_, true)) => Err(PersistorAccessError(format!(
192 "Handle {:?} changed since compare",
193 handle
194 ))),
195 None => Err(PersistorAccessError(format!(
196 "Handle {:?} not found",
197 handle
198 ))),
199 }
200 }
201
202 fn root_delete(&self, handle: Word) -> Result<(), PersistorAccessError> {
203 let mut roots = self.roots.lock().expect("Failed to lock roots map");
204 match roots.get(&handle) {
205 Some((old, _)) => {
206 self.reference_decrement(*old);
207 roots.remove(&handle);
208 Ok(())
209 }
210 None => Err(PersistorAccessError(format!(
211 "Handle {:?} not found",
212 handle
213 ))),
214 }
215 }
216
217 fn branch_set(
218 &self,
219 left: Word,
220 right: Word,
221 digest: Word,
222 ) -> Result<Word, PersistorAccessError> {
223 let mut joined = [0 as u8; SIZE * 3];
224 joined[..SIZE].copy_from_slice(&left);
225 joined[SIZE..SIZE * 2].copy_from_slice(&right);
226 joined[SIZE * 2..].copy_from_slice(&digest);
227
228 let branch = Sha256::digest(joined);
229 self.branches
230 .lock()
231 .expect("Failed to lock branches map")
232 .insert(branch.into(), (left, right, digest));
233 self.reference_increment(left);
234 self.reference_increment(right);
235 Ok(Word::from(branch))
236 }
237
238 fn branch_get(&self, branch: Word) -> Result<(Word, Word, Word), PersistorAccessError> {
239 let branches = self.branches.lock().expect("Failed to lock branches map");
240 match branches.get(&branch) {
241 Some((left, right, digest)) => {
242 let mut joined = [0 as u8; SIZE * 3];
243 joined[..SIZE].copy_from_slice(left);
244 joined[SIZE..SIZE * 2].copy_from_slice(right);
245 joined[SIZE * 2..].copy_from_slice(digest);
246 assert!(Vec::from(branch) == Sha256::digest(joined).to_vec());
247 Ok((*left, *right, *digest))
248 }
249 None => Err(PersistorAccessError(format!(
250 "Branch {:?} not found",
251 branch
252 ))),
253 }
254 }
255
256 fn leaf_set(&self, content: Vec<u8>) -> Result<Word, PersistorAccessError> {
257 let leaf = Word::from(Sha256::digest(Sha256::digest(&content)));
258 self.leaves
259 .lock()
260 .expect("Failed to lock leaves map")
261 .insert(leaf, content);
262 Ok(leaf)
263 }
264
265 fn leaf_get(&self, leaf: Word) -> Result<Vec<u8>, PersistorAccessError> {
266 let leaves = self.leaves.lock().expect("Failed to lock leaves map");
267 match leaves.get(&leaf) {
268 Some(content) => {
269 assert!(Vec::from(leaf) == Sha256::digest(Sha256::digest(content)).to_vec());
270 Ok(content.to_vec())
271 }
272 None => Err(PersistorAccessError(format!("Leaf {:?} not found", leaf))),
273 }
274 }
275
276 fn stump_set(&self, digest: Word) -> Result<Word, PersistorAccessError> {
277 let stump = Sha256::digest(digest);
278 self.stumps
279 .lock()
280 .expect("Failed to lock stump map")
281 .insert(stump.into(), digest);
282 Ok(Word::from(stump))
283 }
284
285 fn stump_get(&self, stump: Word) -> Result<Word, PersistorAccessError> {
286 let stumps = self.stumps.lock().expect("Failed to lock stumps map");
287 match stumps.get(&stump) {
288 Some(digest) => {
289 assert!(Vec::from(stump) == Sha256::digest(Vec::from(digest)).to_vec());
290 Ok(*digest)
291 }
292 None => Err(PersistorAccessError(format!("Stump {:?} not found", stump))),
293 }
294 }
295}
296
297pub struct DatabasePersistor {
298 db: Mutex<DB>,
299}
300
301impl DatabasePersistor {
302 pub fn new(path: &str) -> Self {
303 let mut opts = Options::default();
304 opts.create_if_missing(true);
305 opts.create_missing_column_families(true);
306
307 let cfs = vec![
308 ColumnFamilyDescriptor::new("roots", Options::default()),
309 ColumnFamilyDescriptor::new("branches", Options::default()),
310 ColumnFamilyDescriptor::new("leaves", Options::default()),
311 ColumnFamilyDescriptor::new("stumps", Options::default()),
312 ColumnFamilyDescriptor::new("references", Options::default()),
313 ];
314 let persistor = Self {
315 db: Mutex::new(
316 DB::open_cf_descriptors(&opts, path, cfs).expect("Failed to open database"),
317 ),
318 };
319
320 {
322 let mut handles: Vec<Word> = Vec::new();
323 let db = persistor
324 .db
325 .lock()
326 .expect("Failed to acquire database lock");
327 let mut iter = db.raw_iterator_cf(
328 db.cf_handle("roots")
329 .expect("Failed to get roots column family"),
330 );
331 iter.seek_to_first();
332 while iter.valid() {
333 if (*iter.value().expect("Failed to get iterator value"))[SIZE] == false as u8 {
334 handles.push(
335 (*iter.key().expect("Failed to get iterator key"))
336 .try_into()
337 .expect("Failed to convert key to Word"),
338 );
339 }
340 iter.next();
341 }
342 for handle in handles {
343 db.delete_cf(
344 db.cf_handle("roots")
345 .expect("Failed to get roots column family"),
346 handle,
347 )
348 .expect("Failed to delete value from roots");
349 }
350 }
351
352 persistor
353 }
354
355 fn reference_increment(&self, node: Word) {
356 let db = self.db.lock().expect("Failed to acquire db lock");
357 let references = db
358 .cf_handle("references")
359 .expect("Failed to get references handle");
360 match db.get_cf(references, node) {
361 Ok(Some(count)) => {
362 db.put_cf(
363 references,
364 node,
365 (usize::from_ne_bytes(count.try_into().expect("Invalid count bytes")) + 1)
366 .to_ne_bytes(),
367 )
368 .expect("Failed to increment reference count");
369 }
370 Ok(None) => db
371 .put_cf(references, node, (1 as usize).to_ne_bytes())
372 .expect("Failed to set initial reference count"),
373 Err(e) => {
374 panic! {"{}", e}
375 }
376 };
377 }
378
379 fn reference_decrement(&self, node: Word) {
380 let db = self.db.lock().expect("Failed to acquire db lock");
381 let branches = db
382 .cf_handle("branches")
383 .expect("Failed to get branches handle");
384 let leaves = db.cf_handle("leaves").expect("Failed to get leaves handle");
385 let stumps = db.cf_handle("stumps").expect("Failed to get stumps handle");
386 let references = db
387 .cf_handle("references")
388 .expect("Failed to get references handle");
389 match db
390 .get_cf(references, node)
391 .expect("Failed to get reference count")
392 {
393 Some(count_old) => {
394 let count_new =
395 usize::from_ne_bytes(count_old.try_into().expect("Invalid count bytes")) - 1;
396 if count_new > 0 {
397 db.put_cf(references, node, count_new.to_ne_bytes())
398 .expect("Failed to update reference count");
399 } else {
400 db.delete_cf(references, node)
401 .expect("Failed to delete reference");
402 if let Some(value) = db.get_cf(branches, node).expect("Failed to get branch") {
403 let left = &value[..SIZE].try_into().expect("Invalid left node bytes");
404 let right = &value[SIZE..SIZE * 2].try_into().expect("Invalid right node bytes");
405 db.delete_cf(branches, node)
406 .expect("Failed to delete branch");
407 drop(db);
408 self.reference_decrement(*left);
409 self.reference_decrement(*right);
410 } else {
411 if let Some(_) = db.get_cf(leaves, node).expect("Failed to get leaf") {
412 db.delete_cf(leaves, node).expect("Failed to delete leaf");
413 } else if let Some(_) =
414 db.get_cf(stumps, node).expect("Failed to get stump")
415 {
416 db.delete_cf(stumps, node).expect("Failed to delete stump");
417 }
418 }
419 }
420 }
421 None => {}
422 };
423 }
424}
425
426impl Persistor for DatabasePersistor {
427 fn root_list(&self) -> Vec<Word> {
428 let mut handles: Vec<Word> = Vec::new();
429 let db = self.db.lock().expect("Failed to acquire db lock");
430 let roots = db
431 .cf_handle("roots")
432 .expect("Failed to get roots column family");
433 let mut iter = db.raw_iterator_cf(roots);
434 iter.seek_to_first();
435 while iter.valid() {
436 if (*iter.value().expect("Failed to get iterator value"))[SIZE] != false as u8 {
437 handles.push(
438 (*iter.key().expect("Failed to get iterator key"))
439 .try_into()
440 .expect("Failed to convert key to Word"),
441 );
442 }
443 iter.next();
444 }
445
446 handles.shuffle(&mut rand::thread_rng());
447 handles
448 }
449
450 fn root_new(&self, handle: Word, root: Word) -> Result<Word, PersistorAccessError> {
451 let mut root_marked = [0 as u8; SIZE + 1];
452 root_marked[..SIZE].copy_from_slice(&root);
453 root_marked[SIZE] = true as u8;
454
455 let db = self.db.lock().expect("Failed to acquire db lock");
456 let roots = db
457 .cf_handle("roots")
458 .expect("Failed to get roots column family");
459 match db.get_cf(roots, handle) {
460 Ok(Some(_)) => Err(PersistorAccessError(format!(
461 "Handle {:?} already exists",
462 handle
463 ))),
464 Ok(None) => {
465 db.put_cf(roots, handle, root_marked)
466 .expect("Failed to put root in db");
467 drop(db);
468 self.reference_increment(root);
469 Ok(handle)
470 }
471 Err(e) => Err(PersistorAccessError(format!("{}", e))),
472 }
473 }
474
475 fn root_temp(&self, root: Word) -> Result<Word, PersistorAccessError> {
476 let mut root_marked = [0 as u8; SIZE + 1];
477 root_marked[..SIZE].copy_from_slice(&root);
478 root_marked[SIZE] = false as u8;
479
480 let mut handle: Word = [0 as u8; 32];
481 rand::thread_rng().fill_bytes(&mut handle);
482 let db = self.db.lock().expect("Failed to acquire db lock");
483 let roots = db
484 .cf_handle("roots")
485 .expect("Failed to get roots column family");
486 match db.get_cf(roots, handle) {
487 Ok(Some(_)) => Err(PersistorAccessError(format!(
488 "Handle {:?} already exists",
489 handle
490 ))),
491 Ok(None) => {
492 db.put_cf(roots, handle, root_marked)
493 .expect("Failed to put root in db");
494 drop(db);
495 self.reference_increment(root);
496 Ok(handle)
497 }
498 Err(e) => Err(PersistorAccessError(format!("{}", e))),
499 }
500 }
501
502 fn root_get(&self, handle: Word) -> Result<Word, PersistorAccessError> {
503 let db = self.db.lock().expect("Failed to acquire db lock");
504 let roots = db.cf_handle("roots").expect("Failed to get roots handle");
505 match db.get_cf(roots, handle) {
506 Ok(Some(root_marked)) => Ok(((*root_marked)[..SIZE])
507 .try_into()
508 .expect("Invalid root size")),
509 Ok(None) => Err(PersistorAccessError(format!(
510 "Handle {:?} not found",
511 handle
512 ))),
513 Err(e) => Err(PersistorAccessError(format!("{}", e))),
514 }
515 }
516
517 fn root_set(&self, handle: Word, old: Word, new: Word) -> Result<Word, PersistorAccessError> {
518 let db = self.db.lock().expect("Failed to acquire db lock");
519 let roots = db.cf_handle("roots").expect("Failed to get roots handle");
520 match db.get_cf(roots, handle) {
521 Ok(Some(root_marked)) => match root_marked[SIZE] != false as u8 {
522 true => match root_marked[..SIZE] == old.to_vec() {
523 true => {
524 let mut new_marked = [0 as u8; SIZE + 1];
525 new_marked[..SIZE].copy_from_slice(&new);
526 new_marked[SIZE] = true as u8;
527 db.put_cf(roots, handle, new_marked)
528 .expect("Failed to put root");
529 drop(db);
530 self.reference_increment(new);
531 self.reference_decrement(old);
532 Ok(handle)
533 }
534 false => Err(PersistorAccessError(format!(
535 "Handle {:?} changed since compare",
536 handle
537 ))),
538 },
539 false => Err(PersistorAccessError(format!(
540 "Handle {:?} is temporary",
541 handle
542 ))),
543 },
544 Ok(None) => Err(PersistorAccessError(format!(
545 "Handle {:?} not found",
546 handle
547 ))),
548 Err(e) => Err(PersistorAccessError(format!("{}", e))),
549 }
550 }
551
552 fn root_delete(&self, handle: Word) -> Result<(), PersistorAccessError> {
553 let db = self.db.lock().expect("Failed to acquire db lock");
554 let roots = db.cf_handle("roots").expect("Failed to get roots handle");
555 match db.get_cf(roots, handle) {
556 Ok(Some(root_marked)) => {
557 db.delete_cf(roots, handle).expect("Failed to delete root");
558 drop(db);
559 self.reference_decrement(
560 root_marked[..SIZE].try_into().expect("Invalid root size"),
561 );
562 Ok(())
563 }
564 Ok(None) => Err(PersistorAccessError(format!(
565 "Handle {:?} not found",
566 handle
567 ))),
568 Err(e) => Err(PersistorAccessError(format!("{}", e))),
569 }
570 }
571
572 fn branch_set(
573 &self,
574 left: Word,
575 right: Word,
576 digest: Word,
577 ) -> Result<Word, PersistorAccessError> {
578 let mut joined = [0 as u8; SIZE * 3];
579 joined[..SIZE].copy_from_slice(&left);
580 joined[SIZE..SIZE * 2].copy_from_slice(&right);
581 joined[SIZE * 2..].copy_from_slice(&digest);
582
583 let branch = Sha256::digest(joined);
584
585 let db = self.db.lock().expect("Failed to acquire db lock");
586 let branches = db
587 .cf_handle("branches")
588 .expect("Failed to get branches handle");
589 db.put_cf(branches, branch, joined)
590 .expect("Failed to put branch");
591 drop(db);
592 self.reference_increment(left);
593 self.reference_increment(right);
594
595 Ok(Word::from(branch))
596 }
597
598 fn branch_get(&self, branch: Word) -> Result<(Word, Word, Word), PersistorAccessError> {
599 let db = self.db.lock().expect("Failed to acquire db lock");
600 let branches = db
601 .cf_handle("branches")
602 .expect("Failed to get branches handle");
603 match db.get_cf(branches, branch) {
604 Ok(Some(value)) => {
605 assert!(Vec::from(branch) == Sha256::digest(value.clone()).to_vec());
606 let left = &value[..SIZE].try_into().expect("Invalid left branch size");
607 let right = &value[SIZE..SIZE * 2]
608 .try_into()
609 .expect("Invalid right branch size");
610 let digest = &value[SIZE * 2..]
611 .try_into()
612 .expect("Invalid digest branch size");
613 Ok((*left, *right, *digest))
614 }
615 Ok(None) => Err(PersistorAccessError(format!(
616 "Branch {:?} not found",
617 branch
618 ))),
619 Err(e) => Err(PersistorAccessError(format!("{}", e))),
620 }
621 }
622
623 fn leaf_set(&self, content: Vec<u8>) -> Result<Word, PersistorAccessError> {
624 let leaf = Word::from(Sha256::digest(Sha256::digest(&content)));
625 let db = self.db.lock().expect("Failed to acquire db lock");
626 let leaves = db.cf_handle("leaves").expect("Failed to get leaves handle");
627 db.put_cf(leaves, leaf, content.clone())
628 .expect("Failed to put leaf");
629 Ok(leaf)
630 }
631
632 fn leaf_get(&self, leaf: Word) -> Result<Vec<u8>, PersistorAccessError> {
633 let db = self.db.lock().expect("Failed to acquire db lock");
634 let leaves = db.cf_handle("leaves").expect("Failed to get leaves handle");
635 match db.get_cf(leaves, leaf) {
636 Ok(Some(content)) => {
637 assert!(leaf == *Sha256::digest(Sha256::digest(content.clone())));
638 Ok(content.to_vec())
639 }
640 Ok(None) => Err(PersistorAccessError(format!("Leaf {:?} not found", leaf))),
641 Err(e) => Err(PersistorAccessError(format!("{}", e))),
642 }
643 }
644
645 fn stump_set(&self, digest: Word) -> Result<Word, PersistorAccessError> {
646 let stump = Word::from(Sha256::digest(Vec::from(digest)));
647 let db = self.db.lock().expect("Failed to acquire db lock");
648 let stumps = db.cf_handle("stumps").expect("Failed to get stumps handle");
649 db.put_cf(stumps, stump, digest)
650 .expect("Failed to put stump");
651 Ok(stump)
652 }
653
654 fn stump_get(&self, stump: Word) -> Result<Word, PersistorAccessError> {
655 let db = self.db.lock().expect("Failed to acquire db lock");
656 let stumps = db.cf_handle("stumps").expect("Failed to get stumps handle");
657 match db.get_cf(stumps, stump) {
658 Ok(Some(digest)) => {
659 assert!(stump == *Sha256::digest(digest.clone()));
660 Ok((&(*digest)[..SIZE])
661 .try_into()
662 .expect("Invalid left node bytes"))
663 }
664 Ok(None) => Err(PersistorAccessError(format!(
665 "Stumps {:?} not found",
666 stump
667 ))),
668 Err(e) => Err(PersistorAccessError(format!("{}", e))),
669 }
670 }
671}
672
673#[cfg(test)]
674mod tests {
675 use super::{DatabasePersistor, MemoryPersistor, Persistor, Word, SIZE};
676 use rocksdb::{IteratorMode, DB};
677 use std::fs;
678 use std::sync::Mutex;
679
680 fn test_persistence(persistor: Box<dyn Persistor>) {
681 let zeros: Word = [0 as u8; SIZE];
682
683 assert!(
684 persistor
685 .root_delete(
686 persistor
687 .root_temp(zeros)
688 .expect("Failed to create temp root")
689 )
690 .expect("Failed to delete root")
691 == ()
692 );
693
694 assert!(
695 persistor
696 .root_get(
697 persistor
698 .root_set(
699 persistor
700 .root_new(zeros, zeros)
701 .expect("Failed to create new root"),
702 zeros,
703 zeros,
704 )
705 .expect("Failed to set root"),
706 )
707 .expect("Failed to get root")
708 == zeros
709 );
710
711 assert!(
712 persistor
713 .branch_get(
714 persistor
715 .branch_set(zeros, zeros, zeros)
716 .expect("Failed to set branch"),
717 )
718 .expect("Failed to get branch")
719 == (zeros, zeros, zeros)
720 );
721
722 assert!(
723 persistor
724 .leaf_get(persistor.leaf_set(vec!(0)).expect("Failed to set leaf"),)
725 .expect("Failed to get leaf")
726 == vec!(0)
727 );
728 }
729
730 #[test]
731 fn test_memory_persistence() {
732 test_persistence(Box::new(MemoryPersistor::new()));
733 }
734
735 #[test]
736 fn test_database_persistence() {
737 let db = ".test-database-persistence";
738 let _ = fs::remove_dir_all(db);
739 test_persistence(Box::new(DatabasePersistor::new(db)));
740 let _ = fs::remove_dir_all(db);
741 }
742
743 #[test]
744 fn test_memory_garbage() {
745 let persistor = MemoryPersistor::new();
746 let zeros: Word = [0 as u8; SIZE];
747 let handle: Word = [0 as u8; SIZE];
748
749 let leaf_0 = persistor.leaf_set(vec![0]).expect("Failed to set leaf 0");
750 let leaf_1 = persistor.leaf_set(vec![1]).expect("Failed to set leaf 1");
751 let leaf_2 = persistor.leaf_set(vec![2]).expect("Failed to set leaf 2");
752
753 let stump_0 = persistor
754 .stump_set([0 as u8; SIZE])
755 .expect("Failed to set stump 0");
756
757 let branch_a = persistor
758 .branch_set(leaf_0, leaf_1, zeros)
759 .expect("Failed to set branch A");
760 let branch_b = persistor
761 .branch_set(branch_a, leaf_2, zeros)
762 .expect("Failed to set branch B");
763 let branch_c = persistor
764 .branch_set(branch_b, stump_0, zeros)
765 .expect("Failed to set branch B");
766
767 persistor
768 .root_new(handle, branch_c)
769 .expect("Failed to create new root");
770
771 assert!(persistor.roots.lock().expect("Failed to lock roots").len() == 1);
772 assert!(
773 persistor
774 .branches
775 .lock()
776 .expect("Failed to lock branches")
777 .len()
778 == 3
779 );
780 assert!(
781 persistor
782 .leaves
783 .lock()
784 .expect("Failed to lock leaves")
785 .len()
786 == 3
787 );
788 assert!(
789 persistor
790 .stumps
791 .lock()
792 .expect("Failed to lock leaves")
793 .len()
794 == 1
795 );
796 assert!(
797 persistor
798 .references
799 .lock()
800 .expect("Failed to lock references")
801 .len()
802 == 7
803 );
804
805 let leaf_3 = persistor.leaf_set(vec![3]).expect("Failed to set leaf 3");
806 let branch_d = persistor
807 .branch_set(leaf_2, leaf_3, zeros)
808 .expect("Failed to set branch D");
809 persistor
810 .root_set(handle, branch_c, branch_d)
811 .expect("Failed to set root");
812
813 assert!(persistor.roots.lock().expect("Failed to lock roots").len() == 1);
814 assert!(
815 persistor
816 .branches
817 .lock()
818 .expect("Failed to lock branches")
819 .len()
820 == 1
821 );
822 assert!(
823 persistor
824 .leaves
825 .lock()
826 .expect("Failed to lock leaves")
827 .len()
828 == 2
829 );
830 assert!(
831 persistor
832 .stumps
833 .lock()
834 .expect("Failed to lock stumps")
835 .len()
836 == 0
837 );
838 assert!(
839 persistor
840 .references
841 .lock()
842 .expect("Failed to lock references")
843 .len()
844 == 3
845 );
846 }
847
848 #[test]
849 fn test_database_garbage() {
850 let db = ".test-database-garbage";
851 let _ = fs::remove_dir_all(db);
852 let persistor = DatabasePersistor::new(db);
853 let zeros: Word = [0 as u8; SIZE];
854 let handle: Word = [0 as u8; SIZE];
855 let leaf_0 = persistor.leaf_set(vec![0]).expect("Failed to set leaf 0");
856 let leaf_1 = persistor.leaf_set(vec![1]).expect("Failed to set leaf 1");
857 let leaf_2 = persistor.leaf_set(vec![2]).expect("Failed to set leaf 2");
858
859 let stump_0 = persistor
860 .stump_set([0 as u8; SIZE])
861 .expect("Failed to set stump 0");
862
863 let branch_a = persistor
864 .branch_set(leaf_0, leaf_1, zeros)
865 .expect("Failed to set branch A");
866 let branch_b = persistor
867 .branch_set(branch_a, leaf_2, zeros)
868 .expect("Failed to set branch B");
869 let branch_c = persistor
870 .branch_set(branch_b, stump_0, zeros)
871 .expect("Failed to set branch C");
872
873 persistor
874 .root_new(handle, branch_c)
875 .expect("Failed to create new root");
876
877 let cf_count = |mdb: &Mutex<DB>, cf| {
878 let db_ = mdb.lock().expect("Failed to lock database");
879 db_.iterator_cf(
880 db_.cf_handle(cf).expect("Failed to get CF handle"),
881 IteratorMode::Start,
882 )
883 .count()
884 };
885
886 {
887 assert!(cf_count(&persistor.db, "roots") == 1);
888 assert!(cf_count(&persistor.db, "branches") == 3);
889 assert!(cf_count(&persistor.db, "leaves") == 3);
890 assert!(cf_count(&persistor.db, "stumps") == 1);
891 assert!(cf_count(&persistor.db, "references") == 7);
892 }
893
894 let leaf_3 = persistor.leaf_set(vec![3]).expect("Failed to set leaf 3");
895 let branch_d = persistor
896 .branch_set(leaf_2, leaf_3, zeros)
897 .expect("Failed to set branch D");
898 persistor
899 .root_set(handle, branch_c, branch_d)
900 .expect("Failed to set root");
901
902 {
903 assert!(cf_count(&persistor.db, "roots") == 1);
904 assert!(cf_count(&persistor.db, "branches") == 1);
905 assert!(cf_count(&persistor.db, "leaves") == 2);
906 assert!(cf_count(&persistor.db, "stumps") == 0);
907 assert!(cf_count(&persistor.db, "references") == 3);
908 }
909
910 let _ = fs::remove_dir_all(db);
911 }
912}