1use crate::Nibbles;
2use alloc::{sync::Arc, vec::Vec};
3use alloy_primitives::map::{B256Map, B256Set};
4
5#[derive(Clone, Default, Debug)]
7pub struct TriePrefixSetsMut {
8 pub account_prefix_set: PrefixSetMut,
10 pub storage_prefix_sets: B256Map<PrefixSetMut>,
13 pub destroyed_accounts: B256Set,
15}
16
17impl TriePrefixSetsMut {
18 pub fn is_empty(&self) -> bool {
20 self.account_prefix_set.is_empty() &&
21 self.storage_prefix_sets.is_empty() &&
22 self.destroyed_accounts.is_empty()
23 }
24
25 pub fn extend(&mut self, other: Self) {
27 self.account_prefix_set.extend(other.account_prefix_set);
28 for (hashed_address, prefix_set) in other.storage_prefix_sets {
29 self.storage_prefix_sets.entry(hashed_address).or_default().extend(prefix_set);
30 }
31 self.destroyed_accounts.extend(other.destroyed_accounts);
32 }
33
34 pub fn freeze(self) -> TriePrefixSets {
38 TriePrefixSets {
39 account_prefix_set: self.account_prefix_set.freeze(),
40 storage_prefix_sets: self
41 .storage_prefix_sets
42 .into_iter()
43 .map(|(hashed_address, prefix_set)| (hashed_address, prefix_set.freeze()))
44 .collect(),
45 destroyed_accounts: self.destroyed_accounts,
46 }
47 }
48
49 pub fn clear(&mut self) {
51 self.destroyed_accounts.clear();
52 self.storage_prefix_sets.clear();
53 self.account_prefix_set.clear();
54 }
55}
56
57#[derive(Default, Debug, Clone)]
59pub struct TriePrefixSets {
60 pub account_prefix_set: PrefixSet,
62 pub storage_prefix_sets: B256Map<PrefixSet>,
65 pub destroyed_accounts: B256Set,
67}
68
69#[derive(PartialEq, Eq, Clone, Default, Debug)]
99pub struct PrefixSetMut {
100 all: bool,
103 keys: Vec<Nibbles>,
104}
105
106impl<I> From<I> for PrefixSetMut
107where
108 I: IntoIterator<Item = Nibbles>,
109{
110 fn from(value: I) -> Self {
111 Self { all: false, keys: value.into_iter().collect() }
112 }
113}
114
115impl PrefixSetMut {
116 pub fn with_capacity(capacity: usize) -> Self {
118 Self { all: false, keys: Vec::with_capacity(capacity) }
119 }
120
121 pub const fn all() -> Self {
123 Self { all: true, keys: Vec::new() }
124 }
125
126 pub fn insert(&mut self, nibbles: Nibbles) {
128 self.keys.push(nibbles);
129 }
130
131 pub fn extend(&mut self, other: Self) {
133 self.all |= other.all;
134 self.keys.extend(other.keys);
135 }
136
137 pub fn extend_keys<I>(&mut self, keys: I)
139 where
140 I: IntoIterator<Item = Nibbles>,
141 {
142 self.keys.extend(keys);
143 }
144
145 pub const fn len(&self) -> usize {
147 self.keys.len()
148 }
149
150 pub const fn is_empty(&self) -> bool {
152 self.keys.is_empty()
153 }
154
155 pub fn clear(&mut self) {
157 self.all = false;
158 self.keys.clear();
159 }
160
161 pub fn freeze(mut self) -> PrefixSet {
165 if self.all {
166 PrefixSet { index: 0, all: true, keys: Arc::new(Vec::new()) }
167 } else {
168 self.keys.sort_unstable();
169 self.keys.dedup();
170 self.keys.shrink_to_fit();
172 PrefixSet { index: 0, all: false, keys: Arc::new(self.keys) }
173 }
174 }
175}
176
177#[derive(Debug, Default, Clone)]
181pub struct PrefixSet {
182 all: bool,
184 index: usize,
185 keys: Arc<Vec<Nibbles>>,
186}
187
188impl PrefixSet {
189 #[inline]
204 pub fn contains(&mut self, prefix: &Nibbles) -> bool {
205 if self.all {
206 return true
207 }
208
209 while self.index > 0 && &self.keys[self.index] > prefix {
210 self.index -= 1;
211 }
212
213 for (idx, key) in self.keys[self.index..].iter().enumerate() {
214 if key.starts_with(prefix) {
215 self.index += idx;
216 return true
217 }
218
219 if key > prefix {
220 self.index += idx;
221 return false
222 }
223 }
224
225 false
226 }
227
228 pub fn iter(&self) -> core::slice::Iter<'_, Nibbles> {
230 self.keys.iter()
231 }
232
233 pub const fn all(&self) -> bool {
235 self.all
236 }
237
238 pub fn len(&self) -> usize {
240 self.keys.len()
241 }
242
243 pub fn is_empty(&self) -> bool {
245 self.keys.is_empty()
246 }
247}
248
249impl<'a> IntoIterator for &'a PrefixSet {
250 type Item = &'a Nibbles;
251 type IntoIter = core::slice::Iter<'a, Nibbles>;
252 fn into_iter(self) -> Self::IntoIter {
253 self.iter()
254 }
255}
256
257#[cfg(test)]
258mod tests {
259 use super::*;
260
261 #[test]
262 fn test_contains_with_multiple_inserts_and_duplicates() {
263 let mut prefix_set_mut = PrefixSetMut::default();
264 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
265 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
266 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
267 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); let mut prefix_set = prefix_set_mut.freeze();
270 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
271 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
272 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
273 assert_eq!(prefix_set.len(), 3); }
275
276 #[test]
277 fn test_freeze_shrinks_capacity() {
278 let mut prefix_set_mut = PrefixSetMut::default();
279 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
280 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
281 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
282 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); assert_eq!(prefix_set_mut.keys.len(), 4); assert_eq!(prefix_set_mut.keys.capacity(), 4); let mut prefix_set = prefix_set_mut.freeze();
288 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
289 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
290 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
291 assert_eq!(prefix_set.keys.len(), 3); assert_eq!(prefix_set.keys.capacity(), 3); }
294
295 #[test]
296 fn test_freeze_shrinks_existing_capacity() {
297 let mut prefix_set_mut = PrefixSetMut::with_capacity(101);
299 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
300 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
301 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
302 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); assert_eq!(prefix_set_mut.keys.len(), 4); assert_eq!(prefix_set_mut.keys.capacity(), 101); let mut prefix_set = prefix_set_mut.freeze();
308 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
309 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
310 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
311 assert_eq!(prefix_set.keys.len(), 3); assert_eq!(prefix_set.keys.capacity(), 3); }
314
315 #[test]
316 fn test_prefix_set_all_extend() {
317 let mut prefix_set_mut = PrefixSetMut::default();
318 prefix_set_mut.extend(PrefixSetMut::all());
319 assert!(prefix_set_mut.all);
320 }
321}