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(&current_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(&current_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}