1use crate::Nibbles;
2use alloc::{sync::Arc, vec::Vec};
3use alloy_primitives::map::{B256Map, B256Set};
4use core::ops::Range;
5
6#[derive(Clone, Default, Debug, PartialEq, Eq)]
8pub struct TriePrefixSetsMut {
9 pub account_prefix_set: PrefixSetMut,
11 pub storage_prefix_sets: B256Map<PrefixSetMut>,
14 pub destroyed_accounts: B256Set,
16}
17
18impl TriePrefixSetsMut {
19 pub fn is_empty(&self) -> bool {
21 self.account_prefix_set.is_empty() &&
22 self.storage_prefix_sets.is_empty() &&
23 self.destroyed_accounts.is_empty()
24 }
25
26 pub fn extend(&mut self, other: Self) {
28 self.account_prefix_set.extend(other.account_prefix_set);
29 for (hashed_address, prefix_set) in other.storage_prefix_sets {
30 self.storage_prefix_sets.entry(hashed_address).or_default().extend(prefix_set);
31 }
32 self.destroyed_accounts.extend(other.destroyed_accounts);
33 }
34
35 pub fn extend_ref(&mut self, other: &Self) {
37 self.account_prefix_set.extend_ref(&other.account_prefix_set);
38 for (hashed_address, prefix_set) in &other.storage_prefix_sets {
39 self.storage_prefix_sets.entry(*hashed_address).or_default().extend_ref(prefix_set);
40 }
41 self.destroyed_accounts.extend(other.destroyed_accounts.iter().copied());
42 }
43
44 pub fn freeze(self) -> TriePrefixSets {
48 TriePrefixSets {
49 account_prefix_set: self.account_prefix_set.freeze(),
50 storage_prefix_sets: self
51 .storage_prefix_sets
52 .into_iter()
53 .map(|(hashed_address, prefix_set)| (hashed_address, prefix_set.freeze()))
54 .collect(),
55 destroyed_accounts: self.destroyed_accounts,
56 }
57 }
58
59 pub fn clear(&mut self) {
61 self.destroyed_accounts.clear();
62 self.storage_prefix_sets.clear();
63 self.account_prefix_set.clear();
64 }
65}
66
67#[derive(Default, Debug, Clone)]
69pub struct TriePrefixSets {
70 pub account_prefix_set: PrefixSet,
72 pub storage_prefix_sets: B256Map<PrefixSet>,
75 pub destroyed_accounts: B256Set,
77}
78
79#[derive(PartialEq, Eq, Clone, Default, Debug)]
109pub struct PrefixSetMut {
110 all: bool,
113 keys: Vec<Nibbles>,
114}
115
116impl<I> From<I> for PrefixSetMut
117where
118 I: IntoIterator<Item = Nibbles>,
119{
120 fn from(value: I) -> Self {
121 Self { all: false, keys: value.into_iter().collect() }
122 }
123}
124
125impl PrefixSetMut {
126 pub fn with_capacity(capacity: usize) -> Self {
128 Self { all: false, keys: Vec::with_capacity(capacity) }
129 }
130
131 pub const fn all() -> Self {
133 Self { all: true, keys: Vec::new() }
134 }
135
136 pub fn insert(&mut self, nibbles: Nibbles) {
138 self.keys.push(nibbles);
139 }
140
141 pub fn extend(&mut self, other: Self) {
143 self.all |= other.all;
144 self.keys.extend(other.keys);
145 }
146
147 pub fn extend_ref(&mut self, other: &Self) {
149 self.all |= other.all;
150 self.keys.extend(other.keys.iter().copied());
151 }
152
153 pub fn append(&mut self, other: &mut Self) {
155 self.all |= other.all;
156 other.all = false;
157 self.keys.append(&mut other.keys);
158 }
159
160 pub fn extend_keys<I>(&mut self, keys: I)
162 where
163 I: IntoIterator<Item = Nibbles>,
164 {
165 self.keys.extend(keys);
166 }
167
168 pub fn iter(&self) -> core::slice::Iter<'_, Nibbles> {
170 self.keys.iter()
171 }
172
173 pub const fn len(&self) -> usize {
175 self.keys.len()
176 }
177
178 pub const fn is_empty(&self) -> bool {
180 !self.all && self.keys.is_empty()
181 }
182
183 pub fn clear(&mut self) {
185 self.all = false;
186 self.keys.clear();
187 }
188
189 pub fn freeze(mut self) -> PrefixSet {
193 if self.all {
194 PrefixSet { index: 0, all: true, keys: Arc::new(Vec::new()) }
195 } else {
196 self.keys.sort_unstable();
197 self.keys.dedup();
198 self.keys.shrink_to_fit();
200 PrefixSet { index: 0, all: false, keys: Arc::new(self.keys) }
201 }
202 }
203}
204
205impl<'a> IntoIterator for &'a PrefixSetMut {
206 type Item = &'a Nibbles;
207 type IntoIter = core::slice::Iter<'a, Nibbles>;
208 fn into_iter(self) -> Self::IntoIter {
209 self.iter()
210 }
211}
212
213#[derive(Debug, Default, Clone)]
217pub struct PrefixSet {
218 all: bool,
220 index: usize,
221 keys: Arc<Vec<Nibbles>>,
222}
223
224impl PrefixSet {
225 #[inline]
240 pub fn contains(&mut self, prefix: &Nibbles) -> bool {
241 if self.all {
242 return true
243 }
244
245 while self.index > 0 && &self.keys[self.index] > prefix {
246 self.index -= 1;
247 }
248
249 for (idx, key) in self.keys[self.index..].iter().enumerate() {
250 if key.starts_with(prefix) {
251 self.index += idx;
252 return true
253 }
254
255 if key > prefix {
256 self.index += idx;
257 return false
258 }
259 }
260
261 false
262 }
263
264 #[inline]
270 pub fn contains_range(&mut self, range: Range<&Nibbles>) -> bool {
271 if self.all {
272 return true
273 }
274
275 while self.index > 0 && &self.keys[self.index] >= range.end {
276 self.index -= 1;
277 }
278
279 for (idx, key) in self.keys[self.index..].iter().enumerate() {
280 if key >= range.start && key < range.end {
281 self.index += idx;
282 return true
283 }
284
285 if key >= range.end {
286 self.index += idx;
287 return false
288 }
289 }
290
291 false
292 }
293
294 pub fn iter(&self) -> core::slice::Iter<'_, Nibbles> {
296 self.keys.iter()
297 }
298
299 pub fn slice(&self) -> &[Nibbles] {
301 self.keys.as_slice()
302 }
303
304 pub const fn all(&self) -> bool {
306 self.all
307 }
308
309 pub fn len(&self) -> usize {
311 self.keys.len()
312 }
313
314 pub fn is_empty(&self) -> bool {
316 !self.all && self.keys.is_empty()
317 }
318}
319
320impl<'a> IntoIterator for &'a PrefixSet {
321 type Item = &'a Nibbles;
322 type IntoIter = core::slice::Iter<'a, Nibbles>;
323 fn into_iter(self) -> Self::IntoIter {
324 self.iter()
325 }
326}
327
328#[cfg(test)]
329mod tests {
330 use super::*;
331 use alloy_primitives::B256;
332
333 #[test]
334 fn test_contains_with_multiple_inserts_and_duplicates() {
335 let mut prefix_set_mut = PrefixSetMut::default();
336 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
337 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
338 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
339 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); let mut prefix_set = prefix_set_mut.freeze();
342 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
343 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
344 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
345 assert_eq!(prefix_set.len(), 3); }
347
348 #[test]
349 fn test_freeze_shrinks_capacity() {
350 let mut prefix_set_mut = PrefixSetMut::default();
351 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
352 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
353 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
354 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();
360 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
361 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
362 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
363 assert_eq!(prefix_set.keys.len(), 3); assert_eq!(prefix_set.keys.capacity(), 3); }
366
367 #[test]
368 fn test_freeze_shrinks_existing_capacity() {
369 let mut prefix_set_mut = PrefixSetMut::with_capacity(101);
371 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
372 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
373 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
374 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();
380 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
381 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
382 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
383 assert_eq!(prefix_set.keys.len(), 3); assert_eq!(prefix_set.keys.capacity(), 3); }
386
387 #[test]
388 fn test_prefix_set_all_extend() {
389 let mut prefix_set_mut = PrefixSetMut::default();
390 prefix_set_mut.extend(PrefixSetMut::all());
391 assert!(prefix_set_mut.all);
392 }
393
394 #[test]
395 fn test_prefix_set_slice_returns_frozen_keys() {
396 let path_a = Nibbles::from_nibbles([1, 2, 3]);
397 let path_b = Nibbles::from_nibbles([4, 5, 6]);
398 let mut prefix_set_mut = PrefixSetMut::default();
399 prefix_set_mut.insert(path_b);
400 prefix_set_mut.insert(path_a);
401 prefix_set_mut.insert(path_b);
402
403 let prefix_set = prefix_set_mut.freeze();
404 assert_eq!(prefix_set.slice(), &[path_a, path_b]);
405 }
406
407 #[test]
408 fn test_trie_prefix_sets_mut_extend_ref() {
409 let account_path = Nibbles::from_nibbles([1, 2]);
410 let storage_path = Nibbles::from_nibbles([3, 4]);
411 let storage_account = B256::with_last_byte(1);
412 let destroyed_account = B256::with_last_byte(2);
413 let other = TriePrefixSetsMut {
414 account_prefix_set: PrefixSetMut::from([account_path]),
415 storage_prefix_sets: B256Map::from_iter([(
416 storage_account,
417 PrefixSetMut::from([storage_path]),
418 )]),
419 destroyed_accounts: B256Set::from_iter([destroyed_account]),
420 };
421
422 let mut prefix_sets = TriePrefixSetsMut::default();
423 prefix_sets.extend_ref(&other);
424
425 let frozen = prefix_sets.freeze();
426 assert_eq!(frozen.account_prefix_set.slice(), &[account_path]);
427 assert_eq!(frozen.storage_prefix_sets[&storage_account].slice(), &[storage_path]);
428 assert!(frozen.destroyed_accounts.contains(&destroyed_account));
429 assert_eq!(other.account_prefix_set.len(), 1);
430 }
431}