Skip to content

Commit 71f009d

Browse files
Rjectedshekhirin
andauthored
feat(trie): add clear method to PrefixSetMut, RevealedSparseTrie, SparseTrieUpdates (#16179)
Co-authored-by: Alexey Shekhirin <[email protected]>
1 parent b15c1c8 commit 71f009d

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

crates/trie/common/src/prefix_set.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ impl PrefixSetMut {
136136
self.keys.is_empty()
137137
}
138138

139+
/// Clears the inner vec for reuse, setting `all` to `false`.
140+
pub fn clear(&mut self) {
141+
self.all = false;
142+
self.keys.clear();
143+
}
144+
139145
/// Returns a `PrefixSet` with the same elements as this set.
140146
///
141147
/// If not yet sorted, the elements will be sorted and deduplicated.

crates/trie/sparse/src/trie.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,22 @@ pub enum LeafLookup {
13171317
}
13181318

13191319
impl<P: BlindedProvider> RevealedSparseTrie<P> {
1320+
/// This clears all data structures in the sparse trie, keeping the backing data structures
1321+
/// allocated.
1322+
///
1323+
/// This is useful for reusing the trie without needing to reallocate memory.
1324+
pub fn clear(&mut self) {
1325+
self.nodes.clear();
1326+
self.branch_node_tree_masks.clear();
1327+
self.branch_node_hash_masks.clear();
1328+
self.values.clear();
1329+
self.prefix_set.clear();
1330+
if let Some(updates) = self.updates.as_mut() {
1331+
updates.clear()
1332+
}
1333+
self.rlp_buf.clear();
1334+
}
1335+
13201336
/// Attempts to find a leaf node at the specified path.
13211337
///
13221338
/// This method traverses the trie from the root down to the given path, checking
@@ -2019,6 +2035,15 @@ impl SparseTrieUpdates {
20192035
pub fn wiped() -> Self {
20202036
Self { wiped: true, ..Default::default() }
20212037
}
2038+
2039+
/// Clears the updates, but keeps the backing data structures allocated.
2040+
///
2041+
/// Sets `wiped` to `false`.
2042+
pub fn clear(&mut self) {
2043+
self.updated_nodes.clear();
2044+
self.removed_nodes.clear();
2045+
self.wiped = false;
2046+
}
20222047
}
20232048

20242049
#[cfg(test)]
@@ -3616,6 +3641,35 @@ mod tests {
36163641
assert_eq!(sparse.root(), EMPTY_ROOT_HASH);
36173642
}
36183643

3644+
#[test]
3645+
fn sparse_trie_clear() {
3646+
// tests that if we fill a sparse trie with some nodes and then clear it, it has the same
3647+
// contents as an empty sparse trie
3648+
let mut sparse = RevealedSparseTrie::default();
3649+
let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3650+
sparse
3651+
.update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone())
3652+
.unwrap();
3653+
sparse
3654+
.update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone())
3655+
.unwrap();
3656+
sparse
3657+
.update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone())
3658+
.unwrap();
3659+
sparse.update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value).unwrap();
3660+
3661+
sparse.clear();
3662+
3663+
// we have to update the root hash to be an empty one, because the `Default` impl of
3664+
// `RevealedSparseTrie` sets the root hash to `EMPTY_ROOT_HASH` in the constructor.
3665+
//
3666+
// The default impl is only used in tests.
3667+
sparse.nodes.insert(Nibbles::default(), SparseNode::Empty);
3668+
3669+
let empty_trie = RevealedSparseTrie::default();
3670+
assert_eq!(empty_trie, sparse);
3671+
}
3672+
36193673
#[test]
36203674
fn sparse_trie_display() {
36213675
let mut sparse = RevealedSparseTrie::default();

0 commit comments

Comments
 (0)