1use 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
32pub 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 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 pub fn lookup_mut(&mut self, key: &K, key_len: usize) -> Option<&mut V> {
61 use std::mem::transmute;
65 unsafe { transmute(self.lookup(key, key_len)) }
66 }
67
68 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 key_len - key_idx < node.skip_len as usize {
77 return None;
78 }
79
80 if node.skip_prefix != key.bit_slice(key_idx, key_idx + node.skip_len as usize) {
82 return None;
83 }
84
85 if node.skip_len as usize == key_len - key_idx {
87 return node.data.as_ref();
88 } else {
89 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; }
96 None => { return None; }
97 }
98 }
99 } }
101
102 #[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 #[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 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 if masked_prefix != key_slice {
127 let diff = (masked_prefix ^ key_slice).trailing_zeros();
128
129 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; 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 tmp.skip_len = diff as u8;
153 tmp.skip_prefix = tmp.skip_prefix.mask(diff);
154 idx += 1 + diff;
156 node = &mut **insert.as_mut().unwrap();
157 }
158 else {
160 let slice_len = key_len - idx;
161 if node.skip_len as usize > slice_len {
164 let child_l = node.child_l.take();
166 let child_r = node.child_r.take();
167 let value_neighbor = node.data.take();
168 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 node.skip_len = slice_len as u8;
180 node.skip_prefix = key_slice;
181 node.data = Some(value);
182 return true;
183 }
184 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 else {
197 let tmp = node; 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 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 node = &mut **subtree.as_mut().unwrap();
213 } } } }
217
218 pub fn delete(&mut self, key: &K, key_len: usize) -> Option<V> {
221 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 key_len < tree.skip_len as usize {
232 return (false, None);
233 }
234
235 if tree.skip_prefix != key.mask(tree.skip_len as usize) {
237 return (false, None);
238 }
239
240 if tree.skip_len as usize == key_len {
242 let ret = tree.data.take();
244 let bit = tree.child_r.is_some();
245 if tree.child_l.is_some() && tree.child_r.is_some() {
247 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; 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 (None, None) => { return (true, ret); }
269 }
270 }
271
272 let next_bit = key.bit(tree.skip_len as usize);
274 let ret = {
278 let target = if next_bit { &mut tree.child_r } else { &mut tree.child_l };
279
280 if target.is_none() {
282 return (false, None);
283 }
284 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 if tree.data.is_some() {
298 return (false, ret);
301 }
302
303 match (tree.child_r.is_some(), tree.child_l.take(), tree.child_r.take()) {
304 (_, 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 (bit, Some(child), None) | (bit, None, Some(child)) => {
312 let child = *child; 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 (_, None, None) => {
328 (true, ret)
329 }
330 }
331 }
332 let (_, ret) = recurse(self, key, key_len);
333 ret
334 }
335
336 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 pub fn iter(&self) -> Items<K, V> {
349 Items {
350 node: Some(self),
351 parents: vec![],
352 started: false
353 }
354 }
355
356 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 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 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 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 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
431pub 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
438pub 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 !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 while self.node.is_some() {
465 let mut node = self.node.take();
466 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 } 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 if self.node.is_some() && self.node.unwrap().data.is_some() {
484 break;
485 }
486 } 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 !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 while !self.node.is_null() {
516 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 } 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 if !self.node.is_null() && unsafe { (*self.node).data.is_some() } {
534 break;
535 }
536 } 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 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 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 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 let mut tree = PatriciaTree::new();
614 let mut hashes = vec![];
615 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 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 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 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 for n in tree.iter() {
656 assert!(data[*n].is_some());
657 data[*n] = None;
658 }
659
660 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 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 for n in tree.mut_iter() {
678 *n = n_elems - *n - 1;
679 }
680
681 for n in tree.mut_iter() {
683 assert!(data[*n].is_some());
684 data[*n] = None;
685 }
686
687 assert!(data.iter().all(|opt| opt.is_none()));
689 }
690
691 #[test]
692 fn patricia_serialize_test() {
693 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 let serialized = serialize(&tree);
704 let deserialized: Result<PatriciaTree<Uint128, u32>, _> = deserialize(&serialized);
706 assert!(deserialized.is_ok());
707 let new_tree = deserialized.unwrap();
708
709 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