diem_jellyfish_merkle/iterator/mod.rs
1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8//! This module implements `JellyfishMerkleIterator`. Initialized with a version
9//! and a key, the iterator generates all the key-value pairs in this version of
10//! the tree, starting from the smallest key that is greater or equal to the
11//! given key, by performing a depth first traversal on the tree.
12
13#[cfg(test)]
14mod iterator_test;
15
16use crate::{
17 nibble_path::NibblePath,
18 node_type::{InternalNode, Node, NodeKey},
19 TreeReader,
20};
21use anyhow::{format_err, Result};
22use diem_crypto::HashValue;
23use diem_nibble::Nibble;
24use diem_types::transaction::Version;
25use std::{marker::PhantomData, sync::Arc};
26
27/// `NodeVisitInfo` keeps track of the status of an internal node during the
28/// iteration process. It indicates which ones of its children have been
29/// visited.
30#[derive(Debug)]
31struct NodeVisitInfo {
32 /// The key to this node.
33 node_key: NodeKey,
34
35 /// The node itself.
36 node: InternalNode,
37
38 /// The bitmap indicating which children exist. It is generated by running
39 /// `self.node.generate_bitmaps().0` and cached here.
40 children_bitmap: u16,
41
42 /// This integer always has exactly one 1-bit. The position of the 1-bit
43 /// (from LSB) indicates the next child to visit in the iteration
44 /// process. All the ones on the left have already been visited. All
45 /// the chilren on the right (including this one) have not been visited
46 /// yet.
47 next_child_to_visit: u16,
48}
49
50impl NodeVisitInfo {
51 /// Constructs a new `NodeVisitInfo` with given node key and node.
52 /// `next_child_to_visit` will be set to the leftmost child.
53 fn new(node_key: NodeKey, node: InternalNode) -> Self {
54 let (children_bitmap, _) = node.generate_bitmaps();
55 Self {
56 node_key,
57 node,
58 children_bitmap,
59 next_child_to_visit: 1 << children_bitmap.trailing_zeros(),
60 }
61 }
62
63 /// Same as `new` but points `next_child_to_visit` to a specific location.
64 /// If the child corresponding to `next_child_to_visit` does not exist,
65 /// set it to the next one on the right.
66 fn new_next_child_to_visit(
67 node_key: NodeKey, node: InternalNode, next_child_to_visit: Nibble,
68 ) -> Self {
69 let (children_bitmap, _) = node.generate_bitmaps();
70 let mut next_child_to_visit = 1 << u8::from(next_child_to_visit);
71 while next_child_to_visit & children_bitmap == 0 {
72 next_child_to_visit <<= 1;
73 }
74 Self {
75 node_key,
76 node,
77 children_bitmap,
78 next_child_to_visit,
79 }
80 }
81
82 /// Whether the next child to visit is the rightmost one.
83 fn is_rightmost(&self) -> bool {
84 assert!(
85 self.next_child_to_visit.leading_zeros()
86 >= self.children_bitmap.leading_zeros()
87 );
88 self.next_child_to_visit.leading_zeros()
89 == self.children_bitmap.leading_zeros()
90 }
91
92 /// Advances `next_child_to_visit` to the next child on the right.
93 fn advance(&mut self) {
94 assert!(!self.is_rightmost(), "Advancing past rightmost child.");
95 self.next_child_to_visit <<= 1;
96 while self.next_child_to_visit & self.children_bitmap == 0 {
97 self.next_child_to_visit <<= 1;
98 }
99 }
100}
101
102/// The `JellyfishMerkleIterator` implementation.
103pub struct JellyfishMerkleIterator<R, V> {
104 /// The storage engine from which we can read nodes using node keys.
105 reader: Arc<R>,
106
107 /// The version of the tree this iterator is running on.
108 version: Version,
109
110 /// The stack used for depth first traversal.
111 parent_stack: Vec<NodeVisitInfo>,
112
113 /// Whether the iteration has finished. Usually this can be determined by
114 /// checking whether `self.parent_stack` is empty. But in case of a
115 /// tree with a single leaf, we need this additional bit.
116 done: bool,
117
118 phantom_value: PhantomData<V>,
119}
120
121impl<R, V> JellyfishMerkleIterator<R, V>
122where
123 R: TreeReader<V>,
124 V: crate::Value,
125{
126 /// Constructs a new iterator. This puts the internal state in the correct
127 /// position, so the following `next` call will yield the smallest key
128 /// that is greater or equal to `starting_key`.
129 pub fn new(
130 reader: Arc<R>, version: Version, starting_key: HashValue,
131 ) -> Result<Self> {
132 let mut parent_stack = vec![];
133 let mut done = false;
134
135 let mut current_node_key = NodeKey::new_empty_path(version);
136 let nibble_path = NibblePath::new(starting_key.to_vec());
137 let mut nibble_iter = nibble_path.nibbles();
138
139 while let Node::Internal(internal_node) =
140 reader.get_node(¤t_node_key)?
141 {
142 let child_index =
143 nibble_iter.next().expect("Should have enough nibbles.");
144 match internal_node.child(child_index) {
145 Some(child) => {
146 // If this child exists, we just push the node onto stack
147 // and repeat.
148 parent_stack.push(NodeVisitInfo::new_next_child_to_visit(
149 current_node_key.clone(),
150 internal_node.clone(),
151 child_index,
152 ));
153 current_node_key = current_node_key
154 .gen_child_node_key(child.version, child_index);
155 }
156 None => {
157 let (bitmap, _) = internal_node.generate_bitmaps();
158 if u32::from(u8::from(child_index))
159 < 15 - bitmap.leading_zeros()
160 {
161 // If this child does not exist and there's another
162 // child on the right, we
163 // set the child on the right to be the next one to
164 // visit.
165 parent_stack.push(
166 NodeVisitInfo::new_next_child_to_visit(
167 current_node_key,
168 internal_node,
169 child_index,
170 ),
171 );
172 } else {
173 // Otherwise we have done visiting this node. Go
174 // backward and clean up the
175 // stack.
176 Self::cleanup_stack(&mut parent_stack);
177 }
178 return Ok(Self {
179 reader,
180 version,
181 parent_stack,
182 done,
183 phantom_value: PhantomData,
184 });
185 }
186 }
187 }
188
189 match reader.get_node(¤t_node_key)? {
190 Node::Internal(_) => {
191 unreachable!("Should have reached the bottom of the tree.")
192 }
193 Node::Leaf(leaf_node) => {
194 if leaf_node.account_key() < starting_key {
195 Self::cleanup_stack(&mut parent_stack);
196 if parent_stack.is_empty() {
197 done = true;
198 }
199 }
200 }
201 Node::Null => done = true,
202 }
203
204 Ok(Self {
205 reader,
206 version,
207 parent_stack,
208 done,
209 phantom_value: PhantomData,
210 })
211 }
212
213 fn cleanup_stack(parent_stack: &mut Vec<NodeVisitInfo>) {
214 while let Some(info) = parent_stack.last_mut() {
215 if info.is_rightmost() {
216 parent_stack.pop();
217 } else {
218 info.advance();
219 break;
220 }
221 }
222 }
223}
224
225impl<R, V> Iterator for JellyfishMerkleIterator<R, V>
226where
227 R: TreeReader<V>,
228 V: crate::Value,
229{
230 type Item = Result<(HashValue, V)>;
231
232 fn next(&mut self) -> Option<Self::Item> {
233 if self.done {
234 return None;
235 }
236
237 if self.parent_stack.is_empty() {
238 let root_node_key = NodeKey::new_empty_path(self.version);
239 match self.reader.get_node(&root_node_key) {
240 Ok(Node::Leaf(leaf_node)) => {
241 // This means the entire tree has a single leaf node. The
242 // key of this leaf node is greater or
243 // equal to `starting_key` (otherwise we would have set
244 // `done` to true in `new`). Return the
245 // node and mark `self.done` so next time we return
246 // None.
247 self.done = true;
248 return Some(Ok((
249 leaf_node.account_key(),
250 leaf_node.value().clone(),
251 )));
252 }
253 Ok(Node::Internal(_)) => {
254 // This means `starting_key` is bigger than every key in
255 // this tree, or we have iterated past
256 // the last key.
257 return None;
258 }
259 Ok(Node::Null) => {
260 unreachable!("We would have set done to true in new.")
261 }
262 Err(err) => return Some(Err(err)),
263 }
264 }
265
266 loop {
267 let last_visited_node_info = self
268 .parent_stack
269 .last()
270 .expect("We have checked that self.parent_stack is not empty.");
271 let child_index = Nibble::from(
272 last_visited_node_info.next_child_to_visit.trailing_zeros()
273 as u8,
274 );
275 let node_key = last_visited_node_info.node_key.gen_child_node_key(
276 last_visited_node_info
277 .node
278 .child(child_index)
279 .expect("Child should exist.")
280 .version,
281 child_index,
282 );
283 match self.reader.get_node(&node_key) {
284 Ok(Node::Internal(internal_node)) => {
285 let visit_info =
286 NodeVisitInfo::new(node_key, internal_node);
287 self.parent_stack.push(visit_info);
288 }
289 Ok(Node::Leaf(leaf_node)) => {
290 let ret =
291 (leaf_node.account_key(), leaf_node.value().clone());
292 Self::cleanup_stack(&mut self.parent_stack);
293 return Some(Ok(ret));
294 }
295 Ok(Node::Null) => {
296 return Some(Err(format_err!(
297 "Should not reach a null node."
298 )))
299 }
300 Err(err) => return Some(Err(err)),
301 }
302 }
303 }
304}