basecoin_store/avl/
tree.rs

1use core::borrow::Borrow;
2use core::cmp::Ordering;
3
4use ics23::commitment_proof::Proof;
5use ics23::{CommitmentProof, ExistenceProof, HashOp, InnerOp, NonExistenceProof};
6use tendermint::hash::Hash;
7
8use super::proof::{get_leaf_op, EMPTY_CHILD};
9use super::AvlNode;
10use crate::avl::node::{as_node_ref, NodeRef};
11use crate::avl::AsBytes;
12
13/// An AVL Tree that supports `get` and `insert` operation and can be used to prove existence of a
14/// given key-value couple.
15#[derive(PartialEq, Eq, Debug, Clone)]
16pub struct AvlTree<K: Ord + AsBytes, V> {
17    pub root: NodeRef<K, V>,
18}
19
20impl<K: Ord + AsBytes, V: Borrow<[u8]>> AvlTree<K, V> {
21    /// Return an empty AVL tree.
22    pub fn new() -> Self {
23        AvlTree { root: None }
24    }
25
26    /// Return the hash of the merkle tree root, if it has at least one node.
27    pub fn root_hash(&self) -> Option<&Hash> {
28        Some(&self.root.as_ref()?.merkle_hash)
29    }
30
31    /// Return the value corresponding to the key, if it exists.
32    pub fn get<Q>(&self, key: &Q) -> Option<&V>
33    where
34        K: Borrow<Q>,
35        Q: Ord + ?Sized,
36    {
37        let mut node_ref = &self.root;
38        while let Some(ref node) = node_ref {
39            match node.key.borrow().cmp(key) {
40                Ordering::Greater => node_ref = &node.left,
41                Ordering::Less => node_ref = &node.right,
42                Ordering::Equal => return Some(&node.value),
43            }
44        }
45        None
46    }
47
48    /// Insert a value into the AVL tree, this operation runs in amortized O(log(n)).
49    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
50        let node_ref = &mut self.root;
51        AvlTree::insert_rec(node_ref, key, value)
52    }
53
54    /// Insert a value in the tree.
55    fn insert_rec(node_ref: &mut NodeRef<K, V>, key: K, value: V) -> Option<V> {
56        if let Some(node) = node_ref {
57            let old_value = match node.key.cmp(&key) {
58                Ordering::Greater => AvlTree::insert_rec(&mut node.left, key, value),
59                Ordering::Less => AvlTree::insert_rec(&mut node.right, key, value),
60                Ordering::Equal => Some(node.set_value(value)),
61            };
62            node.update();
63            // Note: when old_value is None, balancing not necessary.
64            // But we do it anyway as general rule.
65            AvlTree::balance_node(node_ref);
66            old_value
67        } else {
68            *node_ref = as_node_ref(key, value);
69            None
70        }
71    }
72
73    /// Remove a value from the AVL tree, this operation runs in amortized O(log(n)).
74    pub fn remove(&mut self, key: K) -> Option<V> {
75        let node_ref = &mut self.root;
76        AvlTree::remove_rec(node_ref, key).map(|node| node.value)
77    }
78
79    /// Remove a value from the tree.
80    ///
81    /// Find the sub-tree whose root to be removed. Then, use [`Self::remove_root`].
82    fn remove_rec(node_ref: &mut NodeRef<K, V>, key: K) -> NodeRef<K, V> {
83        let node = node_ref.as_deref_mut()?;
84
85        let removed_value = match node.key.cmp(&key) {
86            Ordering::Greater => AvlTree::remove_rec(&mut node.left, key),
87            Ordering::Less => AvlTree::remove_rec(&mut node.right, key),
88            Ordering::Equal => AvlTree::remove_root(node_ref),
89        };
90
91        if let Some(node) = node_ref {
92            if removed_value.is_some() {
93                // need to update, as root node is updated
94                // Note: if removed_value is None, nothing is removed.
95                // So no need to update and balance.
96                node.update();
97                AvlTree::balance_node(node_ref);
98            }
99        }
100
101        removed_value
102    }
103
104    /// Removes the root node in the tree, if it exists.
105    ///
106    /// Since we are removing the root node, we need to replace it with a new node.
107    /// The new node is chosen as follows:
108    /// - If the root node has no children, the new node is `None`.
109    /// - If the root node has only one child, the new node is the child.
110    /// - If the root node has both children.
111    ///   - If left child is shorter: the new node is the leftmost node in the right subtree.
112    ///     Also, the root node's children are set to the new node's children.
113    ///   - If right child is shorter, vice versa.
114    ///
115    /// Never called on an empty tree.
116    fn remove_root(node_ref: &mut NodeRef<K, V>) -> NodeRef<K, V> {
117        let node = node_ref.as_deref_mut()?;
118
119        let substitute_node_ref = if node.right.is_none() {
120            // there is no right node, replace the root node with the left node.
121            // substitute_node_ref <- node.left
122            node.left.take()
123        } else if node.left.is_none() {
124            // there is no left node, replace the root node with the right node.
125            // substitute_node_ref <- node.right
126            node.right.take()
127        } else if node.balance_factor() <= 0 {
128            // both left and right nodes exist.
129            // left.height <= right.height; right skewed.
130            // removing from right subtree is better.
131
132            // Remove the leftmost node in the right subtree and replace the current.
133            let mut leftmost_node_ref = AvlTree::remove_leftmost(&mut node.right);
134            // leftmost_node_ref.right <- node_ref.right
135            // leftmost_node_ref.left <- node_ref.left
136            if let Some(leftmost_node) = leftmost_node_ref.as_mut() {
137                // removed leftmost node must be a leaf; it is an invariant.
138                // assert!(leftmost_node.right.is_none() && leftmost_node.left.is_none());
139
140                leftmost_node.right = node.right.take();
141                leftmost_node.left = node.left.take();
142            }
143            // substitute_node_ref <- leftmost_node_ref
144            leftmost_node_ref
145        } else {
146            // node.balance_factor() > 0
147            // both left and right nodes exist.
148            // left.height > right.height; left skewed.
149            // removing from left subtree is better.
150
151            // Remove the rightmost node in the left subtree and replace the current.
152            let mut rightmost_node_ref = AvlTree::remove_rightmost(&mut node.left);
153            // rightmost_node_ref.right <- node_ref.right
154            // rightmost_node_ref.left <- node_ref.left
155            if let Some(rightmost_node) = rightmost_node_ref.as_mut() {
156                // removed rightmost node must be a leaf; it is an invariant.
157                // assert!(rightmost_node.right.is_none() && rightmost_node.left.is_none());
158
159                rightmost_node.right = node.right.take();
160                rightmost_node.left = node.left.take();
161            }
162            // substitute_node_ref <- rightmost_node_ref
163            rightmost_node_ref
164        };
165
166        // removed_node <- node_ref <- substitute_node_ref
167        let removed_node = std::mem::replace(node_ref, substitute_node_ref);
168
169        if let Some(node) = node_ref {
170            // need to update, as top node is replaced
171            node.update();
172            AvlTree::balance_node(node_ref);
173        }
174
175        removed_node
176    }
177
178    /// Removes the leftmost key in the tree, if it exists.
179    fn remove_leftmost(node_ref: &mut NodeRef<K, V>) -> NodeRef<K, V> {
180        let node = node_ref.as_deref_mut()?;
181
182        if node.left.is_none() {
183            let right_node = node.right.take();
184            // removed_node <- node_ref <- right_node
185            std::mem::replace(node_ref, right_node)
186
187            // no need to update, as the new node (right_node) is already updated
188        } else {
189            let removed_node = AvlTree::remove_leftmost(&mut node.left);
190
191            // need to update, as left node is updated
192            node.update();
193            AvlTree::balance_node(node_ref);
194
195            removed_node
196        }
197    }
198
199    /// Removes the rightmost key in the tree, if it exists.
200    fn remove_rightmost(node_ref: &mut NodeRef<K, V>) -> NodeRef<K, V> {
201        let node = node_ref.as_deref_mut()?;
202
203        if node.right.is_none() {
204            let left_node = node.left.take();
205            // removed_node <- node_ref <- left_node
206            std::mem::replace(node_ref, left_node)
207
208            // no need to update, as the new node (left_node) is already updated
209        } else {
210            let removed_node = AvlTree::remove_rightmost(&mut node.right);
211
212            // need to update, as right node is updated
213            node.update();
214            AvlTree::balance_node(node_ref);
215
216            removed_node
217        }
218    }
219
220    /// Return an existence proof for the given element, if it exists.
221    /// Otherwise return a non-existence proof.
222    pub fn get_proof<Q>(&self, key: &Q) -> CommitmentProof
223    where
224        K: Borrow<Q>,
225        Q: Ord + AsBytes + ?Sized,
226    {
227        let proof = Self::get_proof_rec(key, &self.root);
228        CommitmentProof { proof: Some(proof) }
229    }
230
231    fn get_local_existence_proof(node: &AvlNode<K, V>) -> ExistenceProof {
232        ExistenceProof {
233            key: node.key.as_bytes().as_ref().to_owned(),
234            value: node.value.borrow().to_owned(),
235            leaf: Some(get_leaf_op()),
236            path: vec![InnerOp {
237                hash: HashOp::Sha256.into(),
238                prefix: node.left_hash().unwrap_or(&EMPTY_CHILD).to_vec(),
239                suffix: node.right_hash().unwrap_or(&EMPTY_CHILD).to_vec(),
240            }],
241        }
242    }
243
244    /// Recursively build a proof of existence or non-existence for the desired value.
245    fn get_proof_rec<Q>(key: &Q, node: &NodeRef<K, V>) -> Proof
246    where
247        K: Borrow<Q>,
248        Q: Ord + AsBytes + ?Sized,
249    {
250        if let Some(node) = node {
251            match node.key.borrow().cmp(key) {
252                Ordering::Greater => {
253                    let prefix = vec![];
254                    let mut suffix = Vec::with_capacity(64);
255                    suffix.extend(node.hash.as_bytes());
256                    suffix.extend(node.right_hash().unwrap_or(&EMPTY_CHILD));
257                    let inner = InnerOp {
258                        hash: HashOp::Sha256.into(),
259                        prefix,
260                        suffix,
261                    };
262                    match Self::get_proof_rec(key, &node.left) {
263                        Proof::Exist(mut proof) => {
264                            proof.path.push(inner);
265                            Proof::Exist(proof)
266                        }
267                        Proof::Nonexist(mut proof) => {
268                            if let Some(right) = proof.right.as_mut() {
269                                // right-neighbor already found
270                                right.path.push(inner.clone());
271                            }
272                            if let Some(left) = proof.left.as_mut() {
273                                // left-neighbor already found
274                                left.path.push(inner);
275                            }
276                            if proof.right.is_none() {
277                                // found the right-neighbor
278                                proof.right = Some(Self::get_local_existence_proof(node));
279                            }
280                            Proof::Nonexist(proof)
281                        }
282                        _ => unreachable!(),
283                    }
284                }
285                Ordering::Less => {
286                    let suffix = vec![];
287                    let mut prefix = Vec::with_capacity(64);
288                    prefix.extend(node.left_hash().unwrap_or(&EMPTY_CHILD));
289                    prefix.extend(node.hash.as_bytes());
290                    let inner = InnerOp {
291                        hash: HashOp::Sha256.into(),
292                        prefix,
293                        suffix,
294                    };
295                    match Self::get_proof_rec(key, &node.right) {
296                        Proof::Exist(mut proof) => {
297                            proof.path.push(inner);
298                            Proof::Exist(proof)
299                        }
300                        Proof::Nonexist(mut proof) => {
301                            if let Some(right) = proof.right.as_mut() {
302                                // right-neighbor already found
303                                right.path.push(inner.clone());
304                            }
305                            if let Some(left) = proof.left.as_mut() {
306                                // left-neighbor already found
307                                left.path.push(inner);
308                            }
309                            if proof.left.is_none() {
310                                // found the left-neighbor
311                                proof.left = Some(Self::get_local_existence_proof(node));
312                            }
313                            Proof::Nonexist(proof)
314                        }
315                        _ => unreachable!(),
316                    }
317                }
318                Ordering::Equal => Proof::Exist(Self::get_local_existence_proof(node)),
319            }
320        } else {
321            Proof::Nonexist(NonExistenceProof {
322                key: key.as_bytes().as_ref().to_owned(),
323                left: None,
324                right: None,
325            })
326        }
327    }
328
329    /// Rebalance the AVL tree by performing rotations, if needed.
330    fn balance_node(node_ref: &mut NodeRef<K, V>) {
331        let node = node_ref
332            .as_mut()
333            .expect("[AVL]: Empty node in node balance");
334        let balance_factor = node.balance_factor();
335        if balance_factor >= 2 {
336            let left = node
337                .left
338                .as_mut()
339                .expect("[AVL]: Unexpected empty left node");
340            if left.balance_factor() < 1 {
341                AvlTree::rotate_left(&mut node.left);
342            }
343            AvlTree::rotate_right(node_ref);
344        } else if balance_factor <= -2 {
345            let right = node
346                .right
347                .as_mut()
348                .expect("[AVL]: Unexpected empty right node");
349            if right.balance_factor() > -1 {
350                AvlTree::rotate_right(&mut node.right);
351            }
352            AvlTree::rotate_left(node_ref);
353        }
354    }
355
356    /// Performs a right rotation.
357    pub fn rotate_right(root: &mut NodeRef<K, V>) {
358        let mut node = root.take().expect("[AVL]: Empty root in right rotation");
359        let mut left = node.left.take().expect("[AVL]: Unexpected right rotation");
360        let mut left_right = left.right.take();
361        core::mem::swap(&mut node.left, &mut left_right);
362        node.update();
363        core::mem::swap(&mut left.right, &mut Some(node));
364        left.update();
365        core::mem::swap(root, &mut Some(left));
366    }
367
368    /// Perform a left rotation.
369    pub fn rotate_left(root: &mut NodeRef<K, V>) {
370        let mut node = root.take().expect("[AVL]: Empty root in left rotation");
371        let mut right = node.right.take().expect("[AVL]: Unexpected left rotation");
372        let mut right_left = right.left.take();
373        core::mem::swap(&mut node.right, &mut right_left);
374        node.update();
375        core::mem::swap(&mut right.left, &mut Some(node));
376        right.update();
377        core::mem::swap(root, &mut Some(right))
378    }
379
380    /// Return a list of the keys present in the tree.
381    pub fn get_keys(&self) -> Vec<&K> {
382        let mut keys = Vec::new();
383        Self::get_keys_rec(&self.root, &mut keys);
384        keys
385    }
386
387    fn get_keys_rec<'a>(node_ref: &'a NodeRef<K, V>, keys: &mut Vec<&'a K>) {
388        if let Some(node) = node_ref {
389            Self::get_keys_rec(&node.left, keys);
390            keys.push(&node.key);
391            Self::get_keys_rec(&node.right, keys);
392        }
393    }
394}
395
396impl<K: Ord + AsBytes, V: Borrow<[u8]>> Default for AvlTree<K, V> {
397    fn default() -> Self {
398        Self::new()
399    }
400}