stack_test_epic_core/core/pmmr/
vec_backend.rs1use std::collections::HashSet;
16use std::convert::TryFrom;
17use std::fs::File;
18
19use croaring::Bitmap;
20
21use crate::core::hash::Hash;
22use crate::core::pmmr::{self, Backend};
23use crate::core::BlockHeader;
24use crate::ser::PMMRable;
25
26#[derive(Clone, Debug)]
29pub struct VecBackend<T: PMMRable> {
30 pub data: Option<Vec<T>>,
32 pub hashes: Vec<Hash>,
34 pub removed: HashSet<u64>,
36}
37
38impl<T: PMMRable> Backend<T> for VecBackend<T> {
39 fn append(&mut self, elmt: &T, hashes: Vec<Hash>) -> Result<(), String> {
40 if let Some(data) = &mut self.data {
41 data.push(elmt.clone());
42 }
43 self.hashes.append(&mut hashes.clone());
44 Ok(())
45 }
46
47 fn get_hash(&self, position: u64) -> Option<Hash> {
48 if self.removed.contains(&position) {
49 None
50 } else {
51 self.get_from_file(position)
52 }
53 }
54
55 fn get_data(&self, position: u64) -> Option<T::E> {
56 if self.removed.contains(&position) {
57 None
58 } else {
59 self.get_data_from_file(position)
60 }
61 }
62
63 fn get_from_file(&self, position: u64) -> Option<Hash> {
64 let idx = usize::try_from(position.saturating_sub(1)).expect("usize from u64");
65 self.hashes.get(idx).cloned()
66 }
67
68 fn get_data_from_file(&self, position: u64) -> Option<T::E> {
69 if let Some(data) = &self.data {
70 let idx = usize::try_from(pmmr::n_leaves(position).saturating_sub(1))
71 .expect("usize from u64");
72 data.get(idx).map(|x| x.as_elmt())
73 } else {
74 None
75 }
76 }
77
78 fn data_as_temp_file(&self) -> Result<File, String> {
79 unimplemented!()
80 }
81
82 fn n_unpruned_leaves(&self) -> u64 {
84 unimplemented!()
85 }
86
87 fn leaf_pos_iter(&self) -> Box<dyn Iterator<Item = u64> + '_> {
88 Box::new(
89 self.hashes
90 .iter()
91 .enumerate()
92 .map(|(x, _)| (x + 1) as u64)
93 .filter(move |x| pmmr::is_leaf(*x) && !self.removed.contains(x)),
94 )
95 }
96
97 fn leaf_idx_iter(&self, from_idx: u64) -> Box<dyn Iterator<Item = u64> + '_> {
98 let from_pos = pmmr::insertion_to_pmmr_index(from_idx + 1);
99 Box::new(
100 self.leaf_pos_iter()
101 .skip_while(move |x| *x < from_pos)
102 .map(|x| pmmr::n_leaves(x).saturating_sub(1)),
103 )
104 }
105
106 fn remove(&mut self, position: u64) -> Result<(), String> {
107 self.removed.insert(position);
108 Ok(())
109 }
110
111 fn rewind(&mut self, position: u64, _rewind_rm_pos: &Bitmap) -> Result<(), String> {
112 if let Some(data) = &mut self.data {
113 let idx = pmmr::n_leaves(position);
114 data.truncate(usize::try_from(idx).expect("usize from u64"));
115 }
116 self.hashes
117 .truncate(usize::try_from(position).expect("usize from u64"));
118 Ok(())
119 }
120
121 fn snapshot(&self, _header: &BlockHeader) -> Result<(), String> {
122 Ok(())
123 }
124
125 fn release_files(&mut self) {}
126
127 fn dump_stats(&self) {}
128}
129
130impl<T: PMMRable> VecBackend<T> {
131 pub fn new() -> VecBackend<T> {
133 VecBackend {
134 data: Some(vec![]),
135 hashes: vec![],
136 removed: HashSet::new(),
137 }
138 }
139
140 pub fn new_hash_only() -> VecBackend<T> {
142 VecBackend {
143 data: None,
144 hashes: vec![],
145 removed: HashSet::new(),
146 }
147 }
148
149 pub fn size(&self) -> u64 {
151 self.hashes.len() as u64
152 }
153}