bitcoin_chain/
patricia_tree.rs

1// Rust Bitcoin Library
2// Written in 2014 by
3//     Andrew Poelstra <apoelstra@wpsoftware.net>
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! # Patricia/Radix Trie 
16//!
17//! A Patricia trie is a trie in which nodes with only one child are
18//! merged with the child, giving huge space savings for sparse tries.
19//! A radix tree is more general, working with keys that are arbitrary
20//! strings; a Patricia tree uses bitstrings.
21//!
22
23use std::fmt::Debug;
24use std::marker;
25use std::{cmp, fmt, ops, ptr};
26
27use bitcoin::consensus::{Decodable, Encodable, Encoder, Decoder};
28use bitcoin::util::BitArray;
29use bitcoin::consensus::encode;
30
31
32/// Patricia troo
33pub struct PatriciaTree<K: Copy, V> {
34    data: Option<V>,
35    child_l: Option<Box<PatriciaTree<K, V>>>,
36    child_r: Option<Box<PatriciaTree<K, V>>>,
37    skip_prefix: K,
38    skip_len: u8
39}
40
41impl<K, V> PatriciaTree<K, V>
42    where K: Copy + BitArray + cmp::Eq +
43             ops::BitXor<K, Output=K> +
44             ops::Add<K, Output=K> +
45             ops::Shr<usize, Output=K> +
46             ops::Shl<usize, Output=K>
47{
48    /// Constructs a new Patricia tree
49    pub fn new() -> PatriciaTree<K, V> {
50        PatriciaTree {
51            data: None,
52            child_l: None,
53            child_r: None,
54            skip_prefix: BitArray::zero(),
55            skip_len: 0
56        }
57    }
58
59    /// Lookup a value by exactly matching `key` and return a referenc
60    pub fn lookup_mut(&mut self, key: &K, key_len: usize) -> Option<&mut V> {
61        // Caution: `lookup_mut` never modifies its self parameter (in fact its
62        // internal recursion uses a non-mutable self, so we are OK to just
63        // transmute our self pointer into a mutable self before passing it in.
64        use std::mem::transmute;
65        unsafe { transmute(self.lookup(key, key_len)) }
66    }
67
68    /// Lookup a value by exactly matching `key` and return a mutable reference
69    pub fn lookup(&self, key: &K, key_len: usize) -> Option<&V> {
70        let mut node = self;
71        let mut key_idx = 0;
72
73        loop {
74            // If the search key is shorter than the node prefix, there is no
75            // way we can match, so fail.
76            if key_len - key_idx < node.skip_len as usize {
77                return None;
78            }
79
80            // Key fails to match prefix --- no match
81            if node.skip_prefix != key.bit_slice(key_idx, key_idx + node.skip_len as usize) {
82                return None;
83            }
84
85            // Key matches prefix: if they are an exact match, return the data
86            if node.skip_len as usize == key_len - key_idx {
87                return node.data.as_ref();
88            } else {
89                // Key matches prefix: search key longer than node key, recurse
90                key_idx += 1 + node.skip_len as usize;
91                let subtree = if key.bit(key_idx - 1) { &node.child_r } else { &node.child_l };
92                match *subtree {
93                    Some(ref bx) => {
94                        node = &**bx;    // bx is a &Box<U> here, so &**bx gets &U
95                    }
96                    None => { return None; }
97                }
98            }
99        } // end loop
100    }
101
102    /// Inserts a value with key `key`, returning true on success. If a value is already
103    /// stored against `key`, do nothing and return false.
104    #[inline]
105    pub fn insert(&mut self, key: &K, key_len: usize, value: V) -> bool {
106        self.real_insert(key, key_len, value, false)
107    }
108
109    /// Inserts a value with key `key`, returning true on success. If a value is already
110    /// stored against `key`, overwrite it and return false.
111    #[inline]
112    pub fn insert_or_update(&mut self, key: &K, key_len: usize, value: V) -> bool {
113        self.real_insert(key, key_len, value, true)
114    }
115
116    fn real_insert(&mut self, key: &K, key_len: usize, value: V, overwrite: bool) -> bool {
117        let mut node = self;
118        let mut idx = 0;
119        loop {
120            // Mask in case search key is shorter than node key
121            let slice_len = cmp::min(node.skip_len as usize, key_len - idx);
122            let masked_prefix = node.skip_prefix.mask(slice_len);
123            let key_slice = key.bit_slice(idx, idx + slice_len);
124
125            // Prefixes do not match: split key
126            if masked_prefix != key_slice {
127                let diff = (masked_prefix ^ key_slice).trailing_zeros();
128
129                // Remove the old node's children
130                let child_l = node.child_l.take();
131                let child_r = node.child_r.take();
132                let value_neighbor = node.data.take();
133                let tmp = node;    // borrowck hack
134                let (insert, neighbor) = if key_slice.bit(diff)
135                                              { (&mut tmp.child_r, &mut tmp.child_l) }
136                                         else { (&mut tmp.child_l, &mut tmp.child_r) };
137                *insert = Some(Box::new(PatriciaTree {
138                    data: None,
139                    child_l: None,
140                    child_r: None,
141                    skip_prefix: key.bit_slice(idx + diff + 1, key_len),
142                    skip_len: (key_len - idx - diff - 1) as u8
143                }));
144                *neighbor = Some(Box::new(PatriciaTree {
145                    data: value_neighbor,
146                    child_l: child_l,
147                    child_r: child_r,
148                    skip_prefix: tmp.skip_prefix >> (diff + 1),
149                    skip_len: tmp.skip_len - diff as u8 - 1
150                }));
151                // Chop the prefix down
152                tmp.skip_len = diff as u8;
153                tmp.skip_prefix = tmp.skip_prefix.mask(diff);
154                // Recurse
155                idx += 1 + diff;
156                node = &mut **insert.as_mut().unwrap();
157            }
158            // Prefixes match
159            else {
160                let slice_len = key_len - idx;
161                // Search key is shorter than skip prefix: truncate the prefix and attach
162                // the old data as a child
163                if node.skip_len as usize > slice_len {
164                    // Remove the old node's children
165                    let child_l = node.child_l.take();
166                    let child_r = node.child_r.take();
167                    let value_neighbor = node.data.take();
168                    // Put the old data in a new child, with the remainder of the prefix
169                    let new_child = if node.skip_prefix.bit(slice_len)
170                                         { &mut node.child_r } else { &mut node.child_l };
171                    *new_child = Some(Box::new(PatriciaTree {
172                        data: value_neighbor,
173                        child_l: child_l,
174                        child_r: child_r,
175                        skip_prefix: node.skip_prefix >> (slice_len + 1),
176                        skip_len: node.skip_len - slice_len as u8 - 1
177                    }));
178                    // Chop the prefix down and put the new data in place
179                    node.skip_len = slice_len as u8;
180                    node.skip_prefix = key_slice;
181                    node.data = Some(value);
182                    return true;
183                }
184                // If we have an exact match, great, insert it
185                else if node.skip_len as usize == slice_len {
186                    if node.data.is_none() {
187                        node.data = Some(value);
188                        return true;
189                    }
190                    if overwrite {
191                        node.data = Some(value);
192                    }
193                    return false;
194                }
195                // Search key longer than node key, recurse
196                else {
197                    let tmp = node;    // hack to appease borrowck
198                    idx += tmp.skip_len as usize + 1;
199                    let subtree = if key.bit(idx - 1)
200                                      { &mut tmp.child_r } else { &mut tmp.child_l };
201                    // Recurse, adding a new node if necessary
202                    if subtree.is_none() {
203                        *subtree = Some(Box::new(PatriciaTree {
204                            data: None,
205                            child_l: None,
206                            child_r: None,
207                            skip_prefix: key.bit_slice(idx, key_len),
208                            skip_len: (key_len - idx) as u8
209                        }));
210                    }
211                    // subtree.get_mut_ref is a &mut Box<U> here, so &mut ** gets a &mut U
212                    node = &mut **subtree.as_mut().unwrap();
213                } // end search_len vs prefix len
214            } // end if prefixes match
215        } // end loop
216    }
217
218    /// Deletes a value with key `key`, returning it on success. If no value with
219    /// the given key is found, return None
220    pub fn delete(&mut self, key: &K, key_len: usize) -> Option<V> {
221        /// Return value is (deletable, actual return value), where `deletable` is true
222        /// is true when the entire node can be deleted (i.e. it has no children)
223        fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
224            where K: Copy + BitArray + cmp::Eq +
225                     ops::Add<K, Output=K> +
226                     ops::Shr<usize, Output=K> +
227                     ops::Shl<usize, Output=K>
228        {
229            // If the search key is shorter than the node prefix, there is no
230            // way we can match, so fail.
231            if key_len < tree.skip_len as usize {
232                return (false, None);
233            }
234
235            // Key fails to match prefix --- no match
236            if tree.skip_prefix != key.mask(tree.skip_len as usize) {
237                return (false, None);
238            }
239
240            // If we are here, the key matches the prefix
241            if tree.skip_len as usize == key_len {
242                // Exact match -- delete and return
243                let ret = tree.data.take();
244                let bit = tree.child_r.is_some();
245                // First try to consolidate if there is only one child
246                if tree.child_l.is_some() && tree.child_r.is_some() {
247                    // Two children means we cannot consolidate or delete
248                    return (false, ret);
249                }
250                match (tree.child_l.take(), tree.child_r.take()) {
251                    (Some(_), Some(_)) => unreachable!(),
252                    (Some(child), None) | (None, Some(child)) => {
253                        let child = *child;  /* workaround for rustc #28536 */
254                        let PatriciaTree { data, child_l, child_r, skip_len, skip_prefix } = child;
255                        tree.data = data;
256                        tree.child_l = child_l;
257                        tree.child_r = child_r;
258                        let new_bit = if bit { let ret: K = BitArray::one();
259                                               ret << (tree.skip_len as usize) }
260                                      else   { BitArray::zero() };
261                        tree.skip_prefix = tree.skip_prefix + 
262                                           new_bit +
263                                           (skip_prefix << (1 + tree.skip_len as usize));
264                        tree.skip_len += 1 + skip_len;
265                        return (false, ret);
266                    }
267                    // No children means this node is deletable
268                    (None, None) => { return (true, ret); }
269                }
270            }
271
272            // Otherwise, the key is longer than the prefix and we need to recurse
273            let next_bit = key.bit(tree.skip_len as usize);
274            // Recursively get the return value. This awkward scope is required
275            // to shorten the time we mutably borrow the node's children -- we
276            // might want to borrow the sibling later, so the borrow needs to end.
277            let ret = {
278                let target = if next_bit { &mut tree.child_r } else { &mut tree.child_l };
279
280                // If we can't recurse, fail
281                if target.is_none() {
282                    return (false, None);
283                }
284                // Otherwise, do it
285                let (delete_child, ret) = recurse(&mut **target.as_mut().unwrap(),
286                                                  &(*key >> (tree.skip_len as usize + 1)),
287                                                  key_len - tree.skip_len as usize - 1);
288                if delete_child {
289                    target.take();
290                }
291                ret
292            };
293
294            // The above block may have deleted the target. If we now have only one
295            // child, merge it into the parent. (If we have no children, mark this
296            // node for deletion.)
297            if tree.data.is_some() {
298                // First though, if this is a data node, we can neither delete nor
299                // consolidate it.
300                return (false, ret);
301            }
302
303            match (tree.child_r.is_some(), tree.child_l.take(), tree.child_r.take()) {
304                // Two children? Can't do anything, just sheepishly put them back
305                (_, Some(child_l), Some(child_r)) => {
306                    tree.child_l = Some(child_l);
307                    tree.child_r = Some(child_r);
308                    (false, ret)
309                }
310                // One child? Consolidate
311                (bit, Some(child), None) | (bit, None, Some(child)) => {
312                    let child = *child;  /* workaround for rustc #28536 */
313                    let PatriciaTree { data, child_l, child_r, skip_len, skip_prefix } = child;
314                    tree.data = data;
315                    tree.child_l = child_l;
316                    tree.child_r = child_r;
317                    let new_bit = if bit { let ret: K = BitArray::one();
318                                           ret << (tree.skip_len as usize) }
319                                  else { BitArray::zero() };
320                    tree.skip_prefix = tree.skip_prefix + 
321                                       new_bit +
322                                       (skip_prefix << (1 + tree.skip_len as usize));
323                    tree.skip_len += 1 + skip_len;
324                    (false, ret)
325                }
326                // No children? Delete
327                (_, None, None) => {
328                    (true, ret)
329                }
330            }
331        }
332        let (_, ret) = recurse(self, key, key_len);
333        ret
334    }
335
336    /// Count all the nodes
337    pub fn node_count(&self) -> usize {
338        fn recurse<K: Copy, V>(node: &Option<Box<PatriciaTree<K, V>>>) -> usize {
339            match *node {
340                Some(ref node) => { 1 + recurse(&node.child_l) + recurse(&node.child_r) }
341                None => 0
342            }
343        }
344        1 + recurse(&self.child_l) + recurse(&self.child_r)
345    }
346
347    /// Returns an iterator over all elements in the tree
348    pub fn iter(&self) -> Items<K, V> {
349        Items {
350            node: Some(self),
351            parents: vec![],
352            started: false
353        }
354    }
355
356    /// Returns a mutable iterator over all elements in the tree
357    pub fn mut_iter(&mut self) -> MutItems<K, V> {
358        MutItems {
359            node: self as *mut _,
360            parents: vec![],
361            started: false,
362            marker: marker::PhantomData
363        }
364    }
365}
366
367impl<K: Copy + BitArray, V: Debug> Debug for PatriciaTree<K, V> {
368    /// Print the entire tree
369    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
370        fn recurse<K, V>(tree: &PatriciaTree<K, V>, f: &mut fmt::Formatter, depth: usize) -> Result<(), fmt::Error>
371            where K: Copy + BitArray, V: Debug
372        {
373            for i in 0..tree.skip_len as usize {
374                try!(write!(f, "{:}", if tree.skip_prefix.bit(i) { 1 } else { 0 }));
375            }
376            try!(writeln!(f, ": {:?}", tree.data));
377            // left gets no indentation
378            if let Some(ref t) = tree.child_l {
379                for _ in 0..(depth + tree.skip_len as usize) {
380                    try!(write!(f, "-"));
381                }
382                try!(write!(f, "0"));
383                try!(recurse(&**t, f, depth + tree.skip_len as usize + 1));
384            }
385            // right one gets indentation
386            if let Some(ref t) = tree.child_r {
387                for _ in 0..(depth + tree.skip_len as usize) {
388                    try!(write!(f, "_"));
389                }
390                try!(write!(f, "1"));
391                try!(recurse(&**t, f, depth + tree.skip_len as usize + 1));
392            }
393            Ok(())
394        }
395        recurse(self, f, 0)
396    }
397}
398
399impl<S, K, V> Encodable<S> for PatriciaTree<K, V>
400    where S: Encoder,
401          K: Copy + Encodable<S>,
402          V: Encodable<S>
403{
404    fn consensus_encode(&self, s: &mut S) -> Result<(), encode::Error> {
405        // Depth-first serialization: serialize self, then children
406        try!(self.skip_prefix.consensus_encode(s));
407        try!(self.skip_len.consensus_encode(s));
408        try!(self.data.consensus_encode(s));
409        try!(self.child_l.consensus_encode(s));
410        try!(self.child_r.consensus_encode(s));
411        Ok(())
412    }
413}
414
415impl<D, K, V> Decodable<D> for PatriciaTree<K, V>
416    where D: Decoder,
417          K: Copy + Decodable<D>,
418          V: Decodable<D>
419{
420    fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, encode::Error> {
421        Ok(PatriciaTree {
422            skip_prefix: try!(Decodable::consensus_decode(d)),
423            skip_len: try!(Decodable::consensus_decode(d)),
424            data: try!(Decodable::consensus_decode(d)),
425            child_l: try!(Decodable::consensus_decode(d)),
426            child_r: try!(Decodable::consensus_decode(d))
427        })
428    }
429}
430
431/// Iterator
432pub struct Items<'tree, K: Copy + 'tree, V: 'tree> {
433    started: bool,
434    node: Option<&'tree PatriciaTree<K, V>>,
435    parents: Vec<&'tree PatriciaTree<K, V>>
436}
437
438/// Mutable iterator
439pub struct MutItems<'tree, K: Copy + 'tree, V: 'tree> {
440    started: bool,
441    node: *mut PatriciaTree<K, V>,
442    parents: Vec<*mut PatriciaTree<K, V>>,
443    marker: marker::PhantomData<&'tree PatriciaTree<K, V>>
444}
445
446impl<'a, K: Copy, V> Iterator for Items<'a, K, V> {
447    type Item = &'a V;
448
449    fn next(&mut self) -> Option<&'a V> {
450        fn borrow_opt<K: Copy, V>(opt_ptr: &Option<Box<PatriciaTree<K, V>>>) -> Option<&PatriciaTree<K, V>> {
451            opt_ptr.as_ref().map(|b| &**b)
452        }
453
454        // If we haven't started, maybe return the "last" return value,
455        // which will be the root node.
456        if !self.started {
457            if self.node.is_some() && (**self.node.as_ref().unwrap()).data.is_some() {
458                return self.node.unwrap().data.as_ref();
459            }
460            self.started = true;
461        }
462
463        // Find next data-containing node
464        while self.node.is_some() {
465            let mut node = self.node.take();
466            // Try to go left
467            let child_l = borrow_opt(&node.unwrap().child_l);
468            if child_l.is_some() {
469                self.parents.push(node.unwrap());
470                self.node = child_l;
471            // Try to go right, going back up the tree if necessary
472            } else {
473                while node.is_some() {
474                    let child_r = borrow_opt(&node.unwrap().child_r);
475                    if child_r.is_some() {
476                        self.node = child_r;
477                        break;
478                    }
479                    node = self.parents.pop();
480                }
481            }
482            // Stop if we've found data.
483            if self.node.is_some() && self.node.unwrap().data.is_some() {
484                break;
485            }
486        } // end loop
487        // Return data
488        self.node.and_then(|node| node.data.as_ref())
489    }
490}
491
492impl<'a, K: Copy, V> Iterator for MutItems<'a, K, V> {
493    type Item = &'a mut V;
494
495    fn next(&mut self) -> Option<&'a mut V> {
496        fn borrow_opt<K: Copy, V>(opt_ptr: &Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> {
497            match *opt_ptr {
498                Some(ref data) => &**data as *const _ as *mut _,
499                None => ptr::null_mut()
500            }
501        }
502
503        // If we haven't started, maybe return the "last" return value,
504        // which will be the root node.
505        if !self.started {
506            unsafe {
507                if !self.node.is_null() && (*self.node).data.is_some() {
508                    return (*self.node).data.as_mut();
509                }
510            }
511            self.started = true;
512        }
513
514        // Find next data-containing node
515        while !self.node.is_null() {
516            // Try to go left
517            let child_l = unsafe { borrow_opt(&(*self.node).child_l) };
518            if !child_l.is_null() {
519                self.parents.push(self.node);
520                self.node = child_l;
521            // Try to go right, going back up the tree if necessary
522            } else {
523                while !self.node.is_null() {
524                    let child_r = unsafe { borrow_opt(&(*self.node).child_r) };
525                    if !child_r.is_null() {
526                        self.node = child_r;
527                        break;
528                    }
529                    self.node = self.parents.pop().unwrap_or(ptr::null_mut());
530                }
531            }
532            // Stop if we've found data.
533            if !self.node.is_null() && unsafe { (*self.node).data.is_some() } {
534                break;
535            }
536        } // end loop
537        // Return data
538        if !self.node.is_null() {
539            unsafe { (*self.node).data.as_mut() }
540        } else { 
541            None
542        }
543    }
544}
545
546#[cfg(test)]
547mod tests {
548    use super::PatriciaTree;
549    use bitcoin::util::hash::Sha256dHash;
550    use bitcoin::util::uint::Uint128;
551    use bitcoin::util::uint::Uint256;
552    use bitcoin::util::BitArray;
553    use bitcoin::consensus::serialize;
554    use bitcoin::consensus::deserialize;
555
556    #[test]
557    fn patricia_single_insert_lookup_delete_test() {
558        let mut key = Uint256::from_u64(0xDEADBEEFDEADBEEF).unwrap();
559        key = key + (key << 64);
560
561        let mut tree = PatriciaTree::new();
562        tree.insert(&key, 100, 100u32);
563        tree.insert(&key, 120, 100u32);
564
565        assert_eq!(tree.lookup(&key, 100), Some(&100u32));
566        assert_eq!(tree.lookup(&key, 101), None);
567        assert_eq!(tree.lookup(&key, 99), None);
568        assert_eq!(tree.delete(&key, 100), Some(100u32));
569    }
570
571    #[test]
572    fn patricia_insert_lookup_delete_test() {
573        let mut tree = PatriciaTree::new();
574        let mut hashes = vec![];
575        for i in 0u32..5000 {
576            let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
577            tree.insert(&hash, 250, i);
578            hashes.push(hash);
579        }
580
581        // Check that all inserts are correct
582        for (n, hash) in hashes.iter().enumerate() {
583            let ii = n as u32;
584            let ret = tree.lookup(hash, 250);
585            assert_eq!(ret, Some(&ii));
586        }
587
588        // Delete all the odd-numbered nodes
589        for (n, hash) in hashes.iter().enumerate() {
590            if n % 2 == 1 {
591                let ii = n as u32;
592                let ret = tree.delete(hash, 250);
593                assert_eq!(ret, Some(ii));
594            }
595        }
596
597        // Confirm all is correct
598        for (n, hash) in hashes.iter().enumerate() {
599            let ii = n as u32;
600            let ret = tree.lookup(hash, 250);
601            if n % 2 == 0 {
602                assert_eq!(ret, Some(&ii));
603            } else {
604                assert_eq!(ret, None);
605            }
606        }
607    }
608
609    #[test]
610    fn patricia_insert_substring_keys() {
611        // This test uses a bunch of keys that are substrings of each other
612        // to make sure insertion and deletion does not lose data
613        let mut tree = PatriciaTree::new();
614        let mut hashes = vec![];
615        // Start by inserting a bunch of chunder
616        for i in 1u32..500 {
617            let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
618            tree.insert(&hash, 128, i * 1000);
619            hashes.push(hash);
620        }
621        // Do the actual test -- note that we also test insertion and deletion
622        // at the root here.
623        for i in 0u32..10 {
624            tree.insert(&BitArray::zero(), i as usize, i);
625        }
626        for i in 0u32..10 {
627            let m = tree.lookup(&BitArray::zero(), i as usize);
628            assert_eq!(m, Some(&i));
629        }
630        for i in 0u32..10 {
631            let m = tree.delete(&BitArray::zero(), i as usize);
632            assert_eq!(m, Some(i));
633        }
634        // Check that the chunder was unharmed
635        for (n, hash) in hashes.iter().enumerate() {
636            let ii = ((n + 1) * 1000) as u32;
637            let ret = tree.lookup(hash, 128);
638            assert_eq!(ret, Some(&ii));
639        }
640    }
641
642    #[test]
643    fn patricia_iter_test() {
644        let n_elems = 5000;
645        let mut tree = PatriciaTree::new();
646        let mut data = vec![None; n_elems];
647        // Start by inserting a bunch of stuff
648        for i in 0..n_elems {
649            let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
650            tree.insert(&hash, 128, i);
651            data[i] = Some(());
652        }
653
654        // Iterate over and try to get everything
655        for n in tree.iter() {
656            assert!(data[*n].is_some());
657            data[*n] = None;
658        }
659
660        // Check that we got everything
661        assert!(data.iter().all(|opt| opt.is_none()));
662    }
663
664    #[test]
665    fn patricia_mut_iter_test() {
666        let n_elems = 5000;
667        let mut tree = PatriciaTree::new();
668        let mut data = vec![None; n_elems];
669        // Start by inserting a bunch of stuff
670        for i in 0..n_elems {
671            let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
672            tree.insert(&hash, 128, i);
673            data[i] = Some(());
674        }
675
676        // Iterate over and flip all the values
677        for n in tree.mut_iter() {
678            *n = n_elems - *n - 1;
679        }
680
681        // Iterate over and try to get everything
682        for n in tree.mut_iter() {
683            assert!(data[*n].is_some());
684            data[*n] = None;
685        }
686
687        // Check that we got everything
688        assert!(data.iter().all(|opt| opt.is_none()));
689    }
690
691    #[test]
692    fn patricia_serialize_test() {
693        // Build a tree
694        let mut tree = PatriciaTree::new();
695        let mut hashes = vec![];
696        for i in 0u32..5000 {
697            let hash = Sha256dHash::from_data(&[(i / 0x100) as u8, (i % 0x100) as u8]).into_le().low_128();
698            tree.insert(&hash, 250, i);
699            hashes.push(hash);
700        }
701
702        // Serialize it
703        let serialized = serialize(&tree);
704        // Deserialize it
705        let deserialized: Result<PatriciaTree<Uint128, u32>, _> = deserialize(&serialized);
706        assert!(deserialized.is_ok());
707        let new_tree = deserialized.unwrap();
708
709        // Check that all inserts are still there
710        for (n, hash) in hashes.iter().enumerate() {
711            let ii = n as u32;
712            let ret = new_tree.lookup(hash, 250);
713            assert_eq!(ret, Some(&ii));
714        }
715    }
716}
717