mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-08 03:01:12 -04:00
perf(trie): box subtries in parallel sparse trie (#16938)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use crate::{blinded::BlindedProvider, SparseNode, SparseTrieUpdates, TrieMasks};
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use alloy_primitives::{map::HashMap, B256};
|
||||
use alloy_trie::TrieMask;
|
||||
use reth_execution_errors::SparseTrieResult;
|
||||
use reth_trie_common::{
|
||||
prefix_set::{PrefixSet, PrefixSetMut},
|
||||
@@ -20,7 +21,7 @@ pub struct ParallelSparseTrie {
|
||||
/// This contains the trie nodes for the upper part of the trie.
|
||||
upper_subtrie: SparseSubtrie,
|
||||
/// An array containing the subtries at the second level of the trie.
|
||||
subtries: [Option<SparseSubtrie>; 256],
|
||||
lower_subtries: Box<[Option<SparseSubtrie>; 256]>,
|
||||
/// Optional tracking of trie updates for later use.
|
||||
updates: Option<SparseTrieUpdates>,
|
||||
}
|
||||
@@ -29,7 +30,7 @@ impl Default for ParallelSparseTrie {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
upper_subtrie: SparseSubtrie::default(),
|
||||
subtries: [const { None }; 256],
|
||||
lower_subtries: Box::new([const { None }; 256]),
|
||||
updates: None,
|
||||
}
|
||||
}
|
||||
@@ -171,7 +172,7 @@ impl ParallelSparseTrie {
|
||||
let mut prefix_set_iter = prefix_set_clone.into_iter();
|
||||
|
||||
let mut subtries = Vec::new();
|
||||
for subtrie in &mut self.subtries {
|
||||
for subtrie in self.lower_subtries.iter_mut() {
|
||||
if let Some(subtrie) = subtrie.take_if(|subtrie| prefix_set.contains(&subtrie.path)) {
|
||||
let prefix_set = if prefix_set.all() {
|
||||
PrefixSetMut::all()
|
||||
@@ -208,6 +209,10 @@ pub struct SparseSubtrie {
|
||||
path: Nibbles,
|
||||
/// The map from paths to sparse trie nodes within this subtrie.
|
||||
nodes: HashMap<Nibbles, SparseNode>,
|
||||
/// When a branch is set, the corresponding child subtree is stored in the database.
|
||||
branch_node_tree_masks: HashMap<Nibbles, TrieMask>,
|
||||
/// When a bit is set, the corresponding child is stored as a hash in the database.
|
||||
branch_node_hash_masks: HashMap<Nibbles, TrieMask>,
|
||||
/// Map from leaf key paths to their values.
|
||||
/// All values are stored here instead of directly in leaf nodes.
|
||||
values: HashMap<Nibbles, Vec<u8>>,
|
||||
@@ -295,9 +300,9 @@ mod tests {
|
||||
let subtrie_3_index = path_subtrie_index_unchecked(&subtrie_3.path);
|
||||
|
||||
// Add subtries at specific positions
|
||||
trie.subtries[subtrie_1_index] = Some(subtrie_1.clone());
|
||||
trie.subtries[subtrie_2_index] = Some(subtrie_2.clone());
|
||||
trie.subtries[subtrie_3_index] = Some(subtrie_3);
|
||||
trie.lower_subtries[subtrie_1_index] = Some(subtrie_1.clone());
|
||||
trie.lower_subtries[subtrie_2_index] = Some(subtrie_2.clone());
|
||||
trie.lower_subtries[subtrie_3_index] = Some(subtrie_3);
|
||||
|
||||
// Create a prefix set with the keys that match only the second subtrie
|
||||
let mut prefix_set = PrefixSetMut::from([
|
||||
@@ -328,10 +333,10 @@ mod tests {
|
||||
]
|
||||
)]
|
||||
);
|
||||
assert!(trie.subtries[subtrie_2_index].is_none());
|
||||
assert!(trie.lower_subtries[subtrie_2_index].is_none());
|
||||
|
||||
// First subtrie should remain unchanged
|
||||
assert_eq!(trie.subtries[subtrie_1_index], Some(subtrie_1));
|
||||
assert_eq!(trie.lower_subtries[subtrie_1_index], Some(subtrie_1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -346,9 +351,9 @@ mod tests {
|
||||
let subtrie_3_index = path_subtrie_index_unchecked(&subtrie_3.path);
|
||||
|
||||
// Add subtries at specific positions
|
||||
trie.subtries[subtrie_1_index] = Some(subtrie_1.clone());
|
||||
trie.subtries[subtrie_2_index] = Some(subtrie_2.clone());
|
||||
trie.subtries[subtrie_3_index] = Some(subtrie_3.clone());
|
||||
trie.lower_subtries[subtrie_1_index] = Some(subtrie_1.clone());
|
||||
trie.lower_subtries[subtrie_2_index] = Some(subtrie_2.clone());
|
||||
trie.lower_subtries[subtrie_3_index] = Some(subtrie_3.clone());
|
||||
|
||||
// Create a prefix set that matches any key
|
||||
let mut prefix_set = PrefixSetMut::all().freeze();
|
||||
@@ -362,7 +367,7 @@ mod tests {
|
||||
.collect::<Vec<_>>(),
|
||||
vec![(subtrie_1, true), (subtrie_2, true), (subtrie_3, true)]
|
||||
);
|
||||
assert!(trie.subtries.iter().all(Option::is_none));
|
||||
assert!(trie.lower_subtries.iter().all(Option::is_none));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user