1use super::TrieCursor;
2use crate::{BranchNodeCompact, Nibbles};
3use reth_storage_errors::db::DatabaseError;
4use std::cmp::Ordering;
5use tracing::trace;
6
7pub fn cmp(a: &Nibbles, b: &Nibbles) -> Ordering {
23 if a.len() == b.len() {
25 return a.cmp(b)
26 }
27
28 let common_prefix_len = a.common_prefix_length(b);
30 if a.len() == common_prefix_len {
31 return Ordering::Greater
32 } else if b.len() == common_prefix_len {
33 return Ordering::Less
34 }
35
36 a.get_unchecked(common_prefix_len).cmp(&b.get_unchecked(common_prefix_len))
39}
40
41#[derive(Debug)]
47pub struct DepthFirstTrieIterator<C: TrieCursor> {
48 cursor: C,
50 initialized: bool,
52 stack: Vec<(Nibbles, BranchNodeCompact)>,
54 next: Vec<(Nibbles, BranchNodeCompact)>,
56 complete: bool,
58}
59
60impl<C: TrieCursor> DepthFirstTrieIterator<C> {
61 pub fn new(cursor: C) -> Self {
63 Self {
64 cursor,
65 initialized: false,
66 stack: Default::default(),
67 next: Default::default(),
68 complete: false,
69 }
70 }
71
72 fn push(&mut self, path: Nibbles, node: BranchNodeCompact) {
73 loop {
74 match self.stack.last() {
75 None => {
76 self.stack.push((path, node));
79 break
80 }
81 Some((top_path, _)) if path.starts_with(top_path) => {
82 self.stack.push((path, node));
86 break
87 }
88 Some((_, _)) => {
89 self.next.push(self.stack.pop().expect("stack is not empty"));
93 }
94 }
95 }
96
97 self.next.reverse();
100 }
101
102 fn fill_next(&mut self) -> Result<(), DatabaseError> {
103 debug_assert!(self.next.is_empty());
104
105 loop {
106 let Some((path, node)) = (if self.initialized {
107 self.cursor.next()?
108 } else {
109 self.initialized = true;
110 self.cursor.seek(Nibbles::new())?
111 }) else {
112 self.complete = true;
116 self.next = core::mem::take(&mut self.stack);
117 return Ok(())
118 };
119
120 trace!(
121 target: "trie::trie_cursor::depth_first",
122 ?path,
123 "Iterated from cursor",
124 );
125
126 self.push(path, node);
127 if !self.next.is_empty() {
128 return Ok(())
129 }
130 }
131 }
132}
133
134impl<C: TrieCursor> Iterator for DepthFirstTrieIterator<C> {
135 type Item = Result<(Nibbles, BranchNodeCompact), DatabaseError>;
136
137 fn next(&mut self) -> Option<Self::Item> {
138 loop {
139 if let Some(next) = self.next.pop() {
140 return Some(Ok(next))
141 }
142
143 if self.complete {
144 return None
145 }
146
147 if let Err(err) = self.fill_next() {
148 return Some(Err(err))
149 }
150 }
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157 use crate::trie_cursor::{mock::MockTrieCursorFactory, TrieCursorFactory};
158 use alloy_trie::TrieMask;
159 use std::{collections::BTreeMap, sync::Arc};
160
161 fn create_test_node(state_nibbles: &[u8], tree_nibbles: &[u8]) -> BranchNodeCompact {
162 let mut state_mask = TrieMask::default();
163 for &nibble in state_nibbles {
164 state_mask.set_bit(nibble);
165 }
166
167 let mut tree_mask = TrieMask::default();
168 for &nibble in tree_nibbles {
169 tree_mask.set_bit(nibble);
170 }
171
172 BranchNodeCompact {
173 state_mask,
174 tree_mask,
175 hash_mask: TrieMask::default(),
176 hashes: Arc::new(vec![]),
177 root_hash: None,
178 }
179 }
180
181 #[test]
182 fn test_depth_first_cmp() {
183 let child = Nibbles::from_nibbles([0x1, 0x1]);
185 let parent = Nibbles::from_nibbles([0x1]);
186 assert_eq!(cmp(&child, &parent), Ordering::Less);
187 assert_eq!(cmp(&parent, &child), Ordering::Greater);
188
189 let deep = Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]);
191 let ancestor = Nibbles::from_nibbles([0x1, 0x2]);
192 assert_eq!(cmp(&deep, &ancestor), Ordering::Less);
193 assert_eq!(cmp(&ancestor, &deep), Ordering::Greater);
194
195 let sibling1 = Nibbles::from_nibbles([0x1, 0x2]);
197 let sibling2 = Nibbles::from_nibbles([0x1, 0x3]);
198 assert_eq!(cmp(&sibling1, &sibling2), Ordering::Less);
199 assert_eq!(cmp(&sibling2, &sibling1), Ordering::Greater);
200
201 let branch1 = Nibbles::from_nibbles([0x1]);
203 let branch2 = Nibbles::from_nibbles([0x2]);
204 assert_eq!(cmp(&branch1, &branch2), Ordering::Less);
205 assert_eq!(cmp(&branch2, &branch1), Ordering::Greater);
206
207 let empty = Nibbles::new();
209 let non_empty = Nibbles::from_nibbles([0x0]);
210 assert_eq!(cmp(&non_empty, &empty), Ordering::Less);
211 assert_eq!(cmp(&empty, &non_empty), Ordering::Greater);
212
213 let same1 = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
215 let same2 = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
216 assert_eq!(cmp(&same1, &same2), Ordering::Equal);
217 }
218
219 #[test]
220 fn test_depth_first_ordering_complex() {
221 let mut paths = [
223 Nibbles::from_nibbles([0x1]), Nibbles::from_nibbles([0x2]), Nibbles::from_nibbles([0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x2]), ];
228
229 paths.reverse();
231
232 paths.sort_by(cmp);
234
235 assert_eq!(paths[0], Nibbles::from_nibbles([0x1, 0x1])); assert_eq!(paths[1], Nibbles::from_nibbles([0x1, 0x2])); assert_eq!(paths[2], Nibbles::from_nibbles([0x1])); assert_eq!(paths[3], Nibbles::from_nibbles([0x2])); }
241
242 #[test]
243 fn test_depth_first_ordering_tree() {
244 let mut paths = vec![
246 Nibbles::new(), Nibbles::from_nibbles([0x1]), Nibbles::from_nibbles([0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x1, 0x2]), Nibbles::from_nibbles([0x1, 0x2]), Nibbles::from_nibbles([0x2]), Nibbles::from_nibbles([0x2, 0x1]), ];
255
256 paths.reverse();
258
259 paths.sort_by(cmp);
261
262 assert_eq!(paths[0], Nibbles::from_nibbles([0x1, 0x1, 0x1])); assert_eq!(paths[1], Nibbles::from_nibbles([0x1, 0x1, 0x2])); assert_eq!(paths[2], Nibbles::from_nibbles([0x1, 0x1])); assert_eq!(paths[3], Nibbles::from_nibbles([0x1, 0x2])); assert_eq!(paths[4], Nibbles::from_nibbles([0x1])); assert_eq!(paths[5], Nibbles::from_nibbles([0x2, 0x1])); assert_eq!(paths[6], Nibbles::from_nibbles([0x2])); assert_eq!(paths[7], Nibbles::new()); }
274
275 #[test]
276 fn test_empty_trie() {
277 let factory = MockTrieCursorFactory::new(BTreeMap::new(), Default::default());
278 let cursor = factory.account_trie_cursor().unwrap();
279 let mut iter = DepthFirstTrieIterator::new(cursor);
280 assert!(iter.next().is_none());
281 }
282
283 #[test]
284 fn test_single_node() {
285 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
286 let node = create_test_node(&[0x4], &[0x5]);
287
288 let mut nodes = BTreeMap::new();
289 nodes.insert(path, node.clone());
290 let factory = MockTrieCursorFactory::new(nodes, Default::default());
291 let cursor = factory.account_trie_cursor().unwrap();
292 let mut iter = DepthFirstTrieIterator::new(cursor);
293
294 let result = iter.next().unwrap().unwrap();
295 assert_eq!(result.0, path);
296 assert_eq!(result.1, node);
297 assert!(iter.next().is_none());
298 }
299
300 #[test]
301 fn test_depth_first_order() {
302 let nodes = vec![
311 (Nibbles::default(), create_test_node(&[], &[0x1, 0x2])),
313 (Nibbles::from_nibbles([0x1]), create_test_node(&[], &[0x2, 0x3])),
315 (Nibbles::from_nibbles([0x1, 0x2]), create_test_node(&[0xF], &[])),
317 (Nibbles::from_nibbles([0x1, 0x3]), create_test_node(&[0xF], &[])),
318 (Nibbles::from_nibbles([0x2]), create_test_node(&[], &[0x4])),
320 (Nibbles::from_nibbles([0x2, 0x4]), create_test_node(&[0xF], &[])),
322 ];
323
324 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
325 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
326 let cursor = factory.account_trie_cursor().unwrap();
327 let iter = DepthFirstTrieIterator::new(cursor);
328
329 let expected_order = vec![
338 Nibbles::from_nibbles([0x1, 0x2]),
339 Nibbles::from_nibbles([0x1, 0x3]),
340 Nibbles::from_nibbles([0x1]),
341 Nibbles::from_nibbles([0x2, 0x4]),
342 Nibbles::from_nibbles([0x2]),
343 Nibbles::default(),
344 ];
345
346 let mut actual_order = Vec::new();
347 for result in iter {
348 let (path, _) = result.unwrap();
349 actual_order.push(path);
350 }
351
352 assert_eq!(actual_order, expected_order);
353 }
354
355 #[test]
356 fn test_complex_tree() {
357 let nodes = vec![
359 (Nibbles::default(), create_test_node(&[], &[0x0, 0x5, 0xA, 0xF])),
361 (Nibbles::from_nibbles([0x0]), create_test_node(&[], &[0x1, 0x2])),
363 (Nibbles::from_nibbles([0x0, 0x1]), create_test_node(&[0x3], &[])),
364 (Nibbles::from_nibbles([0x0, 0x2]), create_test_node(&[0x4], &[])),
365 (Nibbles::from_nibbles([0x5]), create_test_node(&[0xB], &[])),
367 (Nibbles::from_nibbles([0xA]), create_test_node(&[], &[0xB])),
369 (Nibbles::from_nibbles([0xA, 0xB]), create_test_node(&[], &[0xC])),
370 (Nibbles::from_nibbles([0xA, 0xB, 0xC]), create_test_node(&[0xD], &[])),
371 (Nibbles::from_nibbles([0xF]), create_test_node(&[0xE], &[])),
373 ];
374
375 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
376 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
377 let cursor = factory.account_trie_cursor().unwrap();
378 let iter = DepthFirstTrieIterator::new(cursor);
379
380 let expected_order = vec![
382 Nibbles::from_nibbles([0x0, 0x1]), Nibbles::from_nibbles([0x0, 0x2]), Nibbles::from_nibbles([0x0]), Nibbles::from_nibbles([0x5]), Nibbles::from_nibbles([0xA, 0xB, 0xC]), Nibbles::from_nibbles([0xA, 0xB]), Nibbles::from_nibbles([0xA]), Nibbles::from_nibbles([0xF]), Nibbles::default(), ];
392
393 let mut actual_order = Vec::new();
394 for result in iter {
395 let (path, _node) = result.unwrap();
396 actual_order.push(path);
397 }
398
399 assert_eq!(actual_order, expected_order);
400 }
401}