reth_engine_tree/tree/payload_processor/
configured_sparse_trie.rs

1//! Configured sparse trie enum for switching between serial and parallel implementations.
2
3use alloy_primitives::B256;
4use reth_trie::{Nibbles, TrieNode};
5use reth_trie_sparse::{
6    errors::SparseTrieResult, provider::TrieNodeProvider, LeafLookup, LeafLookupError,
7    RevealedSparseNode, SerialSparseTrie, SparseTrieInterface, SparseTrieUpdates, TrieMasks,
8};
9use reth_trie_sparse_parallel::ParallelSparseTrie;
10use std::borrow::Cow;
11
12/// Enum for switching between serial and parallel sparse trie implementations.
13///
14/// This type allows runtime selection between different sparse trie implementations,
15/// providing flexibility in choosing the appropriate implementation based on workload
16/// characteristics.
17#[derive(Debug)]
18pub(crate) enum ConfiguredSparseTrie {
19    /// Serial implementation of the sparse trie.
20    Serial(Box<SerialSparseTrie>),
21    /// Parallel implementation of the sparse trie.
22    Parallel(Box<ParallelSparseTrie>),
23}
24
25impl From<SerialSparseTrie> for ConfiguredSparseTrie {
26    fn from(trie: SerialSparseTrie) -> Self {
27        Self::Serial(Box::new(trie))
28    }
29}
30
31impl From<ParallelSparseTrie> for ConfiguredSparseTrie {
32    fn from(trie: ParallelSparseTrie) -> Self {
33        Self::Parallel(Box::new(trie))
34    }
35}
36
37impl Default for ConfiguredSparseTrie {
38    fn default() -> Self {
39        Self::Serial(Default::default())
40    }
41}
42
43impl SparseTrieInterface for ConfiguredSparseTrie {
44    fn with_root(
45        self,
46        root: TrieNode,
47        masks: TrieMasks,
48        retain_updates: bool,
49    ) -> SparseTrieResult<Self> {
50        match self {
51            Self::Serial(trie) => {
52                trie.with_root(root, masks, retain_updates).map(|t| Self::Serial(Box::new(t)))
53            }
54            Self::Parallel(trie) => {
55                trie.with_root(root, masks, retain_updates).map(|t| Self::Parallel(Box::new(t)))
56            }
57        }
58    }
59
60    fn with_updates(self, retain_updates: bool) -> Self {
61        match self {
62            Self::Serial(trie) => Self::Serial(Box::new(trie.with_updates(retain_updates))),
63            Self::Parallel(trie) => Self::Parallel(Box::new(trie.with_updates(retain_updates))),
64        }
65    }
66
67    fn reserve_nodes(&mut self, additional: usize) {
68        match self {
69            Self::Serial(trie) => trie.reserve_nodes(additional),
70            Self::Parallel(trie) => trie.reserve_nodes(additional),
71        }
72    }
73
74    fn reveal_node(
75        &mut self,
76        path: Nibbles,
77        node: TrieNode,
78        masks: TrieMasks,
79    ) -> SparseTrieResult<()> {
80        match self {
81            Self::Serial(trie) => trie.reveal_node(path, node, masks),
82            Self::Parallel(trie) => trie.reveal_node(path, node, masks),
83        }
84    }
85
86    fn reveal_nodes(&mut self, nodes: Vec<RevealedSparseNode>) -> SparseTrieResult<()> {
87        match self {
88            Self::Serial(trie) => trie.reveal_nodes(nodes),
89            Self::Parallel(trie) => trie.reveal_nodes(nodes),
90        }
91    }
92
93    fn update_leaf<P: TrieNodeProvider>(
94        &mut self,
95        full_path: Nibbles,
96        value: Vec<u8>,
97        provider: P,
98    ) -> SparseTrieResult<()> {
99        match self {
100            Self::Serial(trie) => trie.update_leaf(full_path, value, provider),
101            Self::Parallel(trie) => trie.update_leaf(full_path, value, provider),
102        }
103    }
104
105    fn remove_leaf<P: TrieNodeProvider>(
106        &mut self,
107        full_path: &Nibbles,
108        provider: P,
109    ) -> SparseTrieResult<()> {
110        match self {
111            Self::Serial(trie) => trie.remove_leaf(full_path, provider),
112            Self::Parallel(trie) => trie.remove_leaf(full_path, provider),
113        }
114    }
115
116    fn root(&mut self) -> B256 {
117        match self {
118            Self::Serial(trie) => trie.root(),
119            Self::Parallel(trie) => trie.root(),
120        }
121    }
122
123    fn update_subtrie_hashes(&mut self) {
124        match self {
125            Self::Serial(trie) => trie.update_subtrie_hashes(),
126            Self::Parallel(trie) => trie.update_subtrie_hashes(),
127        }
128    }
129
130    fn get_leaf_value(&self, full_path: &Nibbles) -> Option<&Vec<u8>> {
131        match self {
132            Self::Serial(trie) => trie.get_leaf_value(full_path),
133            Self::Parallel(trie) => trie.get_leaf_value(full_path),
134        }
135    }
136
137    fn find_leaf(
138        &self,
139        full_path: &Nibbles,
140        expected_value: Option<&Vec<u8>>,
141    ) -> Result<LeafLookup, LeafLookupError> {
142        match self {
143            Self::Serial(trie) => trie.find_leaf(full_path, expected_value),
144            Self::Parallel(trie) => trie.find_leaf(full_path, expected_value),
145        }
146    }
147
148    fn take_updates(&mut self) -> SparseTrieUpdates {
149        match self {
150            Self::Serial(trie) => trie.take_updates(),
151            Self::Parallel(trie) => trie.take_updates(),
152        }
153    }
154
155    fn wipe(&mut self) {
156        match self {
157            Self::Serial(trie) => trie.wipe(),
158            Self::Parallel(trie) => trie.wipe(),
159        }
160    }
161
162    fn clear(&mut self) {
163        match self {
164            Self::Serial(trie) => trie.clear(),
165            Self::Parallel(trie) => trie.clear(),
166        }
167    }
168
169    fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
170        match self {
171            Self::Serial(trie) => trie.updates_ref(),
172            Self::Parallel(trie) => trie.updates_ref(),
173        }
174    }
175}