1#![warn(missing_docs)]
22
23use codec::{Decode, Encode};
24use std::{cmp::Reverse, fmt};
25
26#[derive(Clone, Debug, PartialEq)]
28pub enum Error<E> {
29 Duplicate,
31 UnfinalizedAncestor,
33 Revert,
35 Client(E),
37}
38
39impl<E: std::error::Error> fmt::Display for Error<E> {
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 let message = match *self {
42 Error::Duplicate => "Hash already exists in Tree".into(),
43 Error::UnfinalizedAncestor => "Finalized descendent of Tree node without finalizing its ancestor(s) first".into(),
44 Error::Revert => "Tried to import or finalize node that is an ancestor of a previously finalized node".into(),
45 Error::Client(ref err) => format!("Client error: {}", err),
46 };
47 write!(f, "{}", message)
48 }
49}
50
51impl<E: std::error::Error> std::error::Error for Error<E> {}
52
53impl<E: std::error::Error> From<E> for Error<E> {
54 fn from(err: E) -> Error<E> {
55 Error::Client(err)
56 }
57}
58
59#[derive(Debug, PartialEq)]
61pub enum FinalizationResult<V> {
62 Changed(Option<V>),
64 Unchanged,
66}
67
68#[derive(Debug, PartialEq)]
70pub enum FilterAction {
71 Remove,
73 KeepNode,
75 KeepTree,
77}
78
79#[derive(Clone, Debug, Decode, Encode, PartialEq)]
88pub struct ForkTree<H, N, V> {
89 roots: Vec<Node<H, N, V>>,
90 best_finalized_number: Option<N>,
91}
92
93impl<H, N, V> ForkTree<H, N, V>
94where
95 H: PartialEq,
96 N: Ord,
97{
98 pub fn new() -> ForkTree<H, N, V> {
100 ForkTree { roots: Vec::new(), best_finalized_number: None }
101 }
102
103 pub fn rebalance(&mut self) {
113 self.roots.sort_by_key(|n| Reverse(n.max_depth()));
114 let mut stack: Vec<_> = self.roots.iter_mut().collect();
115 while let Some(node) = stack.pop() {
116 node.children.sort_by_key(|n| Reverse(n.max_depth()));
117 stack.extend(node.children.iter_mut());
118 }
119 }
120
121 pub fn import<F, E>(
135 &mut self,
136 hash: H,
137 number: N,
138 data: V,
139 is_descendent_of: &F,
140 ) -> Result<bool, Error<E>>
141 where
142 E: std::error::Error,
143 F: Fn(&H, &H) -> Result<bool, E>,
144 {
145 if let Some(ref best_finalized_number) = self.best_finalized_number {
146 if number <= *best_finalized_number {
147 return Err(Error::Revert);
148 }
149 }
150
151 let (children, is_root) =
152 match self.find_node_where_mut(&hash, &number, is_descendent_of, &|_| true)? {
153 Some(parent) => (&mut parent.children, false),
154 None => (&mut self.roots, true),
155 };
156
157 if children.iter().any(|elem| elem.hash == hash) {
158 return Err(Error::Duplicate);
159 }
160
161 children.push(Node { data, hash, number, children: Default::default() });
162
163 if children.len() == 1 {
164 self.rebalance();
166 }
167
168 Ok(is_root)
169 }
170
171 pub fn roots(&self) -> impl Iterator<Item = (&H, &N, &V)> {
173 self.roots.iter().map(|node| (&node.hash, &node.number, &node.data))
174 }
175
176 fn node_iter(&self) -> impl Iterator<Item = &Node<H, N, V>> {
177 ForkTreeIterator { stack: self.roots.iter().rev().collect() }
180 }
181
182 pub fn iter(&self) -> impl Iterator<Item = (&H, &N, &V)> {
184 self.node_iter().map(|node| (&node.hash, &node.number, &node.data))
185 }
186
187 pub fn map<VT, F>(self, f: &mut F) -> ForkTree<H, N, VT>
193 where
194 F: FnMut(&H, &N, V) -> VT,
195 {
196 let mut queue: Vec<_> =
197 self.roots.into_iter().rev().map(|node| (usize::MAX, node)).collect();
198 let mut next_queue = Vec::new();
199 let mut output = Vec::new();
200
201 while !queue.is_empty() {
202 for (parent_index, node) in queue.drain(..) {
203 let new_data = f(&node.hash, &node.number, node.data);
204 let new_node = Node {
205 hash: node.hash,
206 number: node.number,
207 data: new_data,
208 children: Vec::with_capacity(node.children.len()),
209 };
210
211 let node_id = output.len();
212 output.push((parent_index, new_node));
213
214 for child in node.children.into_iter().rev() {
215 next_queue.push((node_id, child));
216 }
217 }
218
219 std::mem::swap(&mut queue, &mut next_queue);
220 }
221
222 let mut roots = Vec::new();
223 while let Some((parent_index, new_node)) = output.pop() {
224 if parent_index == usize::MAX {
225 roots.push(new_node);
226 } else {
227 output[parent_index].1.children.push(new_node);
228 }
229 }
230
231 ForkTree { roots, best_finalized_number: self.best_finalized_number }
232 }
233
234 pub fn find_node_where<F, E, P>(
240 &self,
241 hash: &H,
242 number: &N,
243 is_descendent_of: &F,
244 predicate: &P,
245 ) -> Result<Option<&Node<H, N, V>>, Error<E>>
246 where
247 E: std::error::Error,
248 F: Fn(&H, &H) -> Result<bool, E>,
249 P: Fn(&V) -> bool,
250 {
251 let maybe_path = self.find_node_index_where(hash, number, is_descendent_of, predicate)?;
252 Ok(maybe_path.map(|path| {
253 let children =
254 path.iter().take(path.len() - 1).fold(&self.roots, |curr, &i| &curr[i].children);
255 &children[path[path.len() - 1]]
256 }))
257 }
258
259 pub fn find_node_where_mut<F, E, P>(
261 &mut self,
262 hash: &H,
263 number: &N,
264 is_descendent_of: &F,
265 predicate: &P,
266 ) -> Result<Option<&mut Node<H, N, V>>, Error<E>>
267 where
268 E: std::error::Error,
269 F: Fn(&H, &H) -> Result<bool, E>,
270 P: Fn(&V) -> bool,
271 {
272 let maybe_path = self.find_node_index_where(hash, number, is_descendent_of, predicate)?;
273 Ok(maybe_path.map(|path| {
274 let children = path
275 .iter()
276 .take(path.len() - 1)
277 .fold(&mut self.roots, |curr, &i| &mut curr[i].children);
278 &mut children[path[path.len() - 1]]
279 }))
280 }
281
282 pub fn find_node_index_where<F, E, P>(
297 &self,
298 hash: &H,
299 number: &N,
300 is_descendent_of: &F,
301 predicate: &P,
302 ) -> Result<Option<Vec<usize>>, Error<E>>
303 where
304 E: std::error::Error,
305 F: Fn(&H, &H) -> Result<bool, E>,
306 P: Fn(&V) -> bool,
307 {
308 let mut stack = vec![];
309 let mut root_idx = 0;
310 let mut found = false;
311 let mut is_descendent = false;
312
313 while root_idx < self.roots.len() {
314 if *number <= self.roots[root_idx].number {
315 root_idx += 1;
316 continue;
317 }
318 stack.push((&self.roots[root_idx], 0));
322 while let Some((node, i)) = stack.pop() {
323 if i < node.children.len() && !is_descendent {
324 stack.push((node, i + 1));
325 if node.children[i].number < *number {
326 stack.push((&node.children[i], 0));
327 }
328 } else if is_descendent || is_descendent_of(&node.hash, hash)? {
329 is_descendent = true;
330 if predicate(&node.data) {
331 found = true;
332 break;
333 }
334 }
335 }
336
337 if is_descendent {
340 break;
341 }
342 root_idx += 1;
343 }
344
345 Ok(if found {
346 let path: Vec<_> =
350 std::iter::once(root_idx).chain(stack.iter().map(|(_, i)| *i - 1)).collect();
351 Some(path)
352 } else {
353 None
354 })
355 }
356
357 pub fn prune<F, E, P>(
368 &mut self,
369 hash: &H,
370 number: &N,
371 is_descendent_of: &F,
372 predicate: &P,
373 ) -> Result<impl Iterator<Item = (H, N, V)>, Error<E>>
374 where
375 E: std::error::Error,
376 F: Fn(&H, &H) -> Result<bool, E>,
377 P: Fn(&V) -> bool,
378 {
379 let new_root_path =
380 match self.find_node_index_where(hash, number, is_descendent_of, predicate)? {
381 Some(path) => path,
382 None => return Ok(RemovedIterator { stack: Vec::new() }),
383 };
384
385 let mut removed = std::mem::take(&mut self.roots);
386
387 let root_siblings = new_root_path
389 .iter()
390 .take(new_root_path.len() - 1)
391 .fold(&mut removed, |curr, idx| &mut curr[*idx].children);
392 let root = root_siblings.remove(new_root_path[new_root_path.len() - 1]);
393 self.roots = vec![root];
394
395 let mut curr = &mut self.roots[0];
399 loop {
400 let mut maybe_ancestor_idx = None;
401 for (idx, child) in curr.children.iter().enumerate() {
402 if child.number < *number && is_descendent_of(&child.hash, hash)? {
403 maybe_ancestor_idx = Some(idx);
404 break;
405 }
406 }
407 let Some(ancestor_idx) = maybe_ancestor_idx else {
408 break;
410 };
411 let mut next_siblings = std::mem::take(&mut curr.children);
413 let next = next_siblings.remove(ancestor_idx);
414 curr.children = vec![next];
415 removed.append(&mut next_siblings);
416 curr = &mut curr.children[0];
417 }
418
419 let children = std::mem::take(&mut curr.children);
422 for child in children {
423 if child.number == *number && child.hash == *hash
424 || *number < child.number && is_descendent_of(hash, &child.hash)?
425 {
426 curr.children.push(child);
427 } else {
428 removed.push(child);
429 }
430 }
431
432 self.rebalance();
433
434 Ok(RemovedIterator { stack: removed })
435 }
436
437 pub fn finalize_root(&mut self, hash: &H) -> Option<V> {
441 self.roots
442 .iter()
443 .position(|node| node.hash == *hash)
444 .map(|position| self.finalize_root_at(position))
445 }
446
447 fn finalize_root_at(&mut self, position: usize) -> V {
449 let node = self.roots.swap_remove(position);
450 self.roots = node.children;
451 self.best_finalized_number = Some(node.number);
452 node.data
453 }
454
455 pub fn finalize<F, E>(
461 &mut self,
462 hash: &H,
463 number: N,
464 is_descendent_of: &F,
465 ) -> Result<FinalizationResult<V>, Error<E>>
466 where
467 E: std::error::Error,
468 F: Fn(&H, &H) -> Result<bool, E>,
469 {
470 if let Some(ref best_finalized_number) = self.best_finalized_number {
471 if number <= *best_finalized_number {
472 return Err(Error::Revert);
473 }
474 }
475
476 if let Some(root) = self.finalize_root(hash) {
478 return Ok(FinalizationResult::Changed(Some(root)));
479 }
480
481 for root in self.roots.iter() {
483 if number > root.number && is_descendent_of(&root.hash, hash)? {
484 return Err(Error::UnfinalizedAncestor);
485 }
486 }
487
488 let mut changed = false;
492 let roots = std::mem::take(&mut self.roots);
493
494 for root in roots {
495 if root.number > number && is_descendent_of(hash, &root.hash)? {
496 self.roots.push(root);
497 } else {
498 changed = true;
499 }
500 }
501
502 self.best_finalized_number = Some(number);
503
504 if changed {
505 Ok(FinalizationResult::Changed(None))
506 } else {
507 Ok(FinalizationResult::Unchanged)
508 }
509 }
510
511 pub fn finalize_with_ancestors<F, E>(
515 &mut self,
516 hash: &H,
517 number: N,
518 is_descendent_of: &F,
519 ) -> Result<FinalizationResult<V>, Error<E>>
520 where
521 E: std::error::Error,
522 F: Fn(&H, &H) -> Result<bool, E>,
523 {
524 if let Some(ref best_finalized_number) = self.best_finalized_number {
525 if number <= *best_finalized_number {
526 return Err(Error::Revert);
527 }
528 }
529
530 if let Some(root) = self.finalize_root(hash) {
532 return Ok(FinalizationResult::Changed(Some(root)));
533 }
534
535 let mut changed = false;
540 let mut idx = 0;
541 while idx != self.roots.len() {
542 let (is_finalized, is_descendant, is_ancestor) = {
543 let root = &self.roots[idx];
544 let is_finalized = root.hash == *hash;
545 let is_descendant =
546 !is_finalized && root.number > number && is_descendent_of(hash, &root.hash)?;
547 let is_ancestor = !is_finalized
548 && !is_descendant
549 && root.number < number
550 && is_descendent_of(&root.hash, hash)?;
551 (is_finalized, is_descendant, is_ancestor)
552 };
553
554 if is_finalized {
556 return Ok(FinalizationResult::Changed(Some(self.finalize_root_at(idx))));
557 }
558
559 if is_descendant {
561 idx += 1;
562 continue;
563 }
564
565 if is_ancestor {
567 let root = self.roots.swap_remove(idx);
568 self.roots.extend(root.children);
569 changed = true;
570 continue;
571 }
572
573 self.roots.swap_remove(idx);
575 changed = true;
576 }
577
578 self.best_finalized_number = Some(number);
579
580 if changed {
581 Ok(FinalizationResult::Changed(None))
582 } else {
583 Ok(FinalizationResult::Unchanged)
584 }
585 }
586
587 pub fn finalizes_any_with_descendent_if<F, P, E>(
597 &self,
598 hash: &H,
599 number: N,
600 is_descendent_of: &F,
601 predicate: P,
602 ) -> Result<Option<bool>, Error<E>>
603 where
604 E: std::error::Error,
605 F: Fn(&H, &H) -> Result<bool, E>,
606 P: Fn(&V) -> bool,
607 {
608 if let Some(ref best_finalized_number) = self.best_finalized_number {
609 if number <= *best_finalized_number {
610 return Err(Error::Revert);
611 }
612 }
613
614 for node in self.node_iter() {
618 if predicate(&node.data) && (node.hash == *hash || is_descendent_of(&node.hash, hash)?)
619 {
620 for child in node.children.iter() {
621 if child.number <= number
622 && (child.hash == *hash || is_descendent_of(&child.hash, hash)?)
623 {
624 return Err(Error::UnfinalizedAncestor);
625 }
626 }
627
628 return Ok(Some(self.roots.iter().any(|root| root.hash == node.hash)));
629 }
630 }
631
632 Ok(None)
633 }
634
635 pub fn finalize_with_descendent_if<F, P, E>(
643 &mut self,
644 hash: &H,
645 number: N,
646 is_descendent_of: &F,
647 predicate: P,
648 ) -> Result<FinalizationResult<V>, Error<E>>
649 where
650 E: std::error::Error,
651 F: Fn(&H, &H) -> Result<bool, E>,
652 P: Fn(&V) -> bool,
653 {
654 if let Some(ref best_finalized_number) = self.best_finalized_number {
655 if number <= *best_finalized_number {
656 return Err(Error::Revert);
657 }
658 }
659
660 let mut position = None;
664 for (i, root) in self.roots.iter().enumerate() {
665 if predicate(&root.data) && (root.hash == *hash || is_descendent_of(&root.hash, hash)?)
666 {
667 for child in root.children.iter() {
668 if child.number <= number
669 && (child.hash == *hash || is_descendent_of(&child.hash, hash)?)
670 {
671 return Err(Error::UnfinalizedAncestor);
672 }
673 }
674
675 position = Some(i);
676 break;
677 }
678 }
679
680 let node_data = position.map(|i| {
681 let node = self.roots.swap_remove(i);
682 self.roots = node.children;
683 self.best_finalized_number = Some(node.number);
684 node.data
685 });
686
687 let mut changed = false;
693 let roots = std::mem::take(&mut self.roots);
694
695 for root in roots {
696 let retain = root.number > number && is_descendent_of(hash, &root.hash)?
697 || root.number == number && root.hash == *hash
698 || is_descendent_of(&root.hash, hash)?;
699
700 if retain {
701 self.roots.push(root);
702 } else {
703 changed = true;
704 }
705 }
706
707 self.best_finalized_number = Some(number);
708
709 match (node_data, changed) {
710 (Some(data), _) => Ok(FinalizationResult::Changed(Some(data))),
711 (None, true) => Ok(FinalizationResult::Changed(None)),
712 (None, false) => Ok(FinalizationResult::Unchanged),
713 }
714 }
715
716 pub fn drain_filter<F>(&mut self, filter: F) -> impl Iterator<Item = (H, N, V)>
725 where
726 F: Fn(&H, &N, &V) -> FilterAction,
727 {
728 let mut removed = vec![];
729 let mut retained = Vec::new();
730
731 let mut queue: Vec<_> = std::mem::take(&mut self.roots)
732 .into_iter()
733 .rev()
734 .map(|node| (usize::MAX, node))
735 .collect();
736 let mut next_queue = Vec::new();
737
738 while !queue.is_empty() {
739 for (parent_idx, mut node) in queue.drain(..) {
740 match filter(&node.hash, &node.number, &node.data) {
741 FilterAction::KeepNode => {
742 let node_idx = retained.len();
743 let children = std::mem::take(&mut node.children);
744 retained.push((parent_idx, node));
745 for child in children.into_iter().rev() {
746 next_queue.push((node_idx, child));
747 }
748 },
749 FilterAction::KeepTree => {
750 retained.push((parent_idx, node));
751 },
752 FilterAction::Remove => {
753 removed.push(node);
754 },
755 }
756 }
757
758 std::mem::swap(&mut queue, &mut next_queue);
759 }
760
761 while let Some((parent_idx, node)) = retained.pop() {
762 if parent_idx == usize::MAX {
763 self.roots.push(node);
764 } else {
765 retained[parent_idx].1.children.push(node);
766 }
767 }
768
769 if !removed.is_empty() {
770 self.rebalance();
771 }
772 RemovedIterator { stack: removed }
773 }
774}
775
776use node_implementation::Node;
778
779mod node_implementation {
780 use super::*;
781
782 #[derive(Clone, Debug, Decode, Encode, PartialEq)]
783 pub struct Node<H, N, V> {
784 pub hash: H,
785 pub number: N,
786 pub data: V,
787 pub children: Vec<Node<H, N, V>>,
788 }
789
790 impl<H: PartialEq, N: Ord, V> Node<H, N, V> {
791 pub fn max_depth(&self) -> usize {
793 let mut max: usize = 0;
794 let mut stack = vec![(self, 0)];
795 while let Some((node, height)) = stack.pop() {
796 if height > max {
797 max = height;
798 }
799 node.children.iter().for_each(|n| stack.push((n, height + 1)));
800 }
801 max
802 }
803 }
804}
805
806struct ForkTreeIterator<'a, H, N, V> {
807 stack: Vec<&'a Node<H, N, V>>,
808}
809
810impl<'a, H, N, V> Iterator for ForkTreeIterator<'a, H, N, V> {
811 type Item = &'a Node<H, N, V>;
812
813 fn next(&mut self) -> Option<Self::Item> {
814 self.stack.pop().inspect(|node| {
815 self.stack.extend(node.children.iter().rev());
819 })
820 }
821}
822
823struct RemovedIterator<H, N, V> {
824 stack: Vec<Node<H, N, V>>,
825}
826
827impl<H, N, V> Iterator for RemovedIterator<H, N, V> {
828 type Item = (H, N, V);
829
830 fn next(&mut self) -> Option<Self::Item> {
831 self.stack.pop().map(|mut node| {
832 let children = std::mem::take(&mut node.children);
836
837 self.stack.extend(children.into_iter().rev());
838 (node.hash, node.number, node.data)
839 })
840 }
841}
842
843#[cfg(test)]
844mod test {
845 use crate::FilterAction;
846
847 use super::{Error, FinalizationResult, ForkTree};
848
849 #[derive(Debug, PartialEq)]
850 struct TestError;
851
852 impl std::fmt::Display for TestError {
853 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
854 write!(f, "TestError")
855 }
856 }
857
858 impl std::error::Error for TestError {}
859
860 fn test_pez_fork_tree<'a>(
861 ) -> (ForkTree<&'a str, u64, u32>, impl Fn(&&str, &&str) -> Result<bool, TestError>) {
862 let mut tree = ForkTree::new();
863
864 #[rustfmt::skip]
865 let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
883 let letters = vec!["B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"];
884 let block = block.to_uppercase();
887 match (*base, block) {
888 ("A", b) => Ok(letters.into_iter().any(|n| n == b)),
889 ("B" | "c", b) => Ok(b == "C" || b == "D" || b == "E"),
890 ("C", b) => Ok(b == "D" || b == "E"),
891 ("D", b) => Ok(b == "E"),
892 ("E", _) => Ok(false),
893 ("F", b) =>
894 Ok(b == "G" || b == "H" || b == "I" || b == "L" || b == "M" || b == "N" || b == "O"),
895 ("G", _) => Ok(false),
896 ("H", b) => Ok(b == "I" || b == "L" || b == "M" || b == "N" || b == "O"),
897 ("I", _) => Ok(false),
898 ("J", b) => Ok(b == "K"),
899 ("K", _) => Ok(false),
900 ("L", b) => Ok(b == "M" || b == "N" || b == "O"),
901 ("m", b) => Ok(b == "M" || b == "N"),
902 ("M", b) => Ok(b == "N"),
903 ("O", _) => Ok(false),
904 ("0", _) => Ok(true),
905 _ => Ok(false),
906 }
907 };
908
909 tree.import("A", 10, 1, &is_descendent_of).unwrap();
910 tree.import("B", 20, 2, &is_descendent_of).unwrap();
911 tree.import("C", 30, 3, &is_descendent_of).unwrap();
912 tree.import("D", 40, 4, &is_descendent_of).unwrap();
913 tree.import("E", 50, 5, &is_descendent_of).unwrap();
914 tree.import("F", 20, 2, &is_descendent_of).unwrap();
915 tree.import("G", 30, 3, &is_descendent_of).unwrap();
916 tree.import("H", 30, 3, &is_descendent_of).unwrap();
917 tree.import("I", 40, 4, &is_descendent_of).unwrap();
918 tree.import("L", 40, 4, &is_descendent_of).unwrap();
919 tree.import("M", 50, 5, &is_descendent_of).unwrap();
920 tree.import("O", 50, 5, &is_descendent_of).unwrap();
921 tree.import("J", 20, 2, &is_descendent_of).unwrap();
922 tree.import("K", 30, 3, &is_descendent_of).unwrap();
923
924 (tree, is_descendent_of)
925 }
926
927 #[test]
928 fn import_doesnt_revert() {
929 let (mut tree, is_descendent_of) = test_pez_fork_tree();
930
931 tree.finalize_root(&"A");
932
933 assert_eq!(tree.best_finalized_number, Some(10));
934
935 assert_eq!(tree.import("A", 10, 1, &is_descendent_of), Err(Error::Revert));
936 }
937
938 #[test]
939 fn import_doesnt_add_duplicates() {
940 let (mut tree, is_descendent_of) = test_pez_fork_tree();
941
942 assert_eq!(tree.import("A", 10, 1, &is_descendent_of), Err(Error::Duplicate));
943
944 assert_eq!(tree.import("I", 40, 4, &is_descendent_of), Err(Error::Duplicate));
945
946 assert_eq!(tree.import("G", 30, 3, &is_descendent_of), Err(Error::Duplicate));
947
948 assert_eq!(tree.import("K", 30, 3, &is_descendent_of), Err(Error::Duplicate));
949 }
950
951 #[test]
952 fn finalize_root_works() {
953 let finalize_a = || {
954 let (mut tree, ..) = test_pez_fork_tree();
955
956 assert_eq!(tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(), vec![("A", 10)]);
957
958 tree.finalize_root(&"A");
960
961 assert_eq!(
962 tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(),
963 vec![("B", 20), ("F", 20), ("J", 20)],
964 );
965
966 tree
967 };
968
969 {
970 let mut tree = finalize_a();
971
972 tree.finalize_root(&"B");
974
975 assert_eq!(tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(), vec![("C", 30)],);
976
977 assert!(tree.roots.len() == 1);
979 }
980
981 {
982 let mut tree = finalize_a();
983
984 tree.finalize_root(&"J");
986
987 assert_eq!(tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(), vec![("K", 30)],);
988
989 assert!(tree.roots.len() == 1);
991 }
992 }
993
994 #[test]
995 fn finalize_works() {
996 let (mut tree, is_descendent_of) = test_pez_fork_tree();
997
998 let original_roots = tree.roots.clone();
999
1000 assert_eq!(tree.finalize(&"0", 0, &is_descendent_of), Ok(FinalizationResult::Unchanged));
1002
1003 assert_eq!(tree.roots, original_roots);
1004
1005 assert_eq!(
1007 tree.finalize(&"A", 10, &is_descendent_of),
1008 Ok(FinalizationResult::Changed(Some(1))),
1009 );
1010
1011 assert_eq!(
1012 tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(),
1013 vec![("B", 20), ("F", 20), ("J", 20)],
1014 );
1015
1016 assert_eq!(tree.best_finalized_number, Some(10));
1018
1019 assert_eq!(tree.finalize(&"Z", 10, &is_descendent_of), Err(Error::Revert));
1020
1021 assert_eq!(tree.finalize(&"H", 30, &is_descendent_of), Err(Error::UnfinalizedAncestor));
1023
1024 assert_eq!(
1026 tree.finalize(&"F", 20, &is_descendent_of),
1027 Ok(FinalizationResult::Changed(Some(2))),
1028 );
1029
1030 assert_eq!(
1031 tree.finalize(&"H", 30, &is_descendent_of),
1032 Ok(FinalizationResult::Changed(Some(3))),
1033 );
1034
1035 assert_eq!(
1036 tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(),
1037 vec![("L", 40), ("I", 40)],
1038 );
1039
1040 assert_eq!(
1042 tree.finalize(&"Z", 50, &is_descendent_of),
1043 Ok(FinalizationResult::Changed(None)),
1044 );
1045
1046 assert!(tree.roots.is_empty());
1047 }
1048
1049 #[test]
1050 fn finalize_with_ancestor_works() {
1051 let (mut tree, is_descendent_of) = test_pez_fork_tree();
1052
1053 let original_roots = tree.roots.clone();
1054
1055 assert_eq!(
1057 tree.finalize_with_ancestors(&"0", 0, &is_descendent_of),
1058 Ok(FinalizationResult::Unchanged),
1059 );
1060
1061 assert_eq!(tree.roots, original_roots);
1062
1063 assert_eq!(
1065 tree.finalize_with_ancestors(&"A", 10, &is_descendent_of),
1066 Ok(FinalizationResult::Changed(Some(1))),
1067 );
1068
1069 assert_eq!(
1070 tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(),
1071 vec![("B", 20), ("F", 20), ("J", 20)],
1072 );
1073
1074 assert_eq!(
1079 tree.finalize_with_ancestors(&"H", 30, &is_descendent_of),
1080 Ok(FinalizationResult::Changed(Some(3))),
1081 );
1082
1083 assert_eq!(
1084 tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(),
1085 vec![("L", 40), ("I", 40)],
1086 );
1087
1088 assert_eq!(tree.best_finalized_number, Some(30));
1089
1090 assert_eq!(
1096 tree.finalize_with_ancestors(&"N", 60, &is_descendent_of),
1097 Ok(FinalizationResult::Changed(None)),
1098 );
1099
1100 assert_eq!(tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(), vec![],);
1101
1102 assert_eq!(tree.best_finalized_number, Some(60));
1103 }
1104
1105 #[test]
1106 fn finalize_with_descendent_works() {
1107 #[derive(Debug, PartialEq)]
1108 struct Change {
1109 effective: u64,
1110 }
1111
1112 let (mut tree, is_descendent_of) = {
1113 let mut tree = ForkTree::new();
1114
1115 let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
1116 match (*base, *block) {
1124 ("A0", b) => Ok(b == "B" || b == "C" || b == "D" || b == "E" || b == "G"),
1125 ("A1", _) => Ok(false),
1126 ("C", b) => Ok(b == "D"),
1127 ("D", b) => Ok(b == "E" || b == "F" || b == "G"),
1128 ("E", b) => Ok(b == "F"),
1129 _ => Ok(false),
1130 }
1131 };
1132
1133 let is_root = tree.import("A0", 1, Change { effective: 5 }, &is_descendent_of).unwrap();
1134 assert!(is_root);
1135 let is_root = tree.import("A1", 1, Change { effective: 5 }, &is_descendent_of).unwrap();
1136 assert!(is_root);
1137 let is_root =
1138 tree.import("D", 10, Change { effective: 10 }, &is_descendent_of).unwrap();
1139 assert!(!is_root);
1140 let is_root =
1141 tree.import("E", 15, Change { effective: 50 }, &is_descendent_of).unwrap();
1142 assert!(!is_root);
1143
1144 (tree, is_descendent_of)
1145 };
1146
1147 assert_eq!(
1148 tree.finalizes_any_with_descendent_if(
1149 &"B",
1150 2,
1151 &is_descendent_of,
1152 |c| c.effective <= 2,
1153 ),
1154 Ok(None),
1155 );
1156
1157 assert_eq!(
1159 tree.finalize_with_descendent_if(&"D", 10, &is_descendent_of, |c| c.effective <= 10),
1160 Err(Error::UnfinalizedAncestor)
1161 );
1162
1163 assert_eq!(
1166 tree.finalizes_any_with_descendent_if(&"D", 10, &is_descendent_of, |c| c.effective
1167 == 10),
1168 Ok(Some(false)),
1169 );
1170
1171 assert_eq!(
1173 tree.finalizes_any_with_descendent_if(&"E", 15, &is_descendent_of, |c| c.effective
1174 == 10),
1175 Err(Error::UnfinalizedAncestor)
1176 );
1177
1178 assert_eq!(
1181 tree.finalize_with_descendent_if(&"B", 2, &is_descendent_of, |c| c.effective <= 2),
1182 Ok(FinalizationResult::Changed(None)),
1183 );
1184
1185 assert_eq!(tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(), vec![("A0", 1)],);
1186
1187 assert_eq!(
1189 tree.finalizes_any_with_descendent_if(
1190 &"C",
1191 5,
1192 &is_descendent_of,
1193 |c| c.effective <= 5,
1194 ),
1195 Ok(Some(true)),
1196 );
1197
1198 assert_eq!(
1199 tree.finalize_with_descendent_if(&"C", 5, &is_descendent_of, |c| c.effective <= 5),
1200 Ok(FinalizationResult::Changed(Some(Change { effective: 5 }))),
1201 );
1202
1203 assert_eq!(tree.roots().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(), vec![("D", 10)],);
1204
1205 assert_eq!(
1207 tree.finalizes_any_with_descendent_if(&"F", 100, &is_descendent_of, |c| c.effective
1208 <= 100,),
1209 Err(Error::UnfinalizedAncestor),
1210 );
1211
1212 assert_eq!(
1214 tree.finalizes_any_with_descendent_if(&"G", 100, &is_descendent_of, |c| c.effective
1215 <= 100),
1216 Ok(Some(true)),
1217 );
1218
1219 assert_eq!(
1220 tree.finalize_with_descendent_if(&"G", 100, &is_descendent_of, |c| c.effective <= 100),
1221 Ok(FinalizationResult::Changed(Some(Change { effective: 10 }))),
1222 );
1223
1224 assert_eq!(tree.roots().count(), 0);
1226 }
1227
1228 #[test]
1229 fn iter_iterates_in_preorder() {
1230 let (tree, ..) = test_pez_fork_tree();
1231 assert_eq!(
1232 tree.iter().map(|(h, n, _)| (*h, *n)).collect::<Vec<_>>(),
1233 vec![
1234 ("A", 10),
1235 ("B", 20),
1236 ("C", 30),
1237 ("D", 40),
1238 ("E", 50),
1239 ("F", 20),
1240 ("H", 30),
1241 ("L", 40),
1242 ("M", 50),
1243 ("O", 50),
1244 ("I", 40),
1245 ("G", 30),
1246 ("J", 20),
1247 ("K", 30),
1248 ],
1249 );
1250 }
1251
1252 #[test]
1253 fn minimizes_calls_to_is_descendent_of() {
1254 use std::sync::atomic::{AtomicUsize, Ordering};
1255
1256 let n_is_descendent_of_calls = AtomicUsize::new(0);
1257
1258 let is_descendent_of = |_: &&str, _: &&str| -> Result<bool, TestError> {
1259 n_is_descendent_of_calls.fetch_add(1, Ordering::SeqCst);
1260 Ok(true)
1261 };
1262
1263 {
1264 let mut tree = ForkTree::new();
1268 let letters = vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
1269
1270 for (i, letter) in letters.iter().enumerate() {
1271 tree.import::<_, TestError>(*letter, i, i, &|_, _| Ok(true)).unwrap();
1272 }
1273
1274 assert_eq!(
1277 tree.finalizes_any_with_descendent_if(&"L", 11, &is_descendent_of, |i| *i == 10,),
1278 Ok(Some(false)),
1279 );
1280
1281 assert_eq!(n_is_descendent_of_calls.load(Ordering::SeqCst), 1);
1282 }
1283
1284 n_is_descendent_of_calls.store(0, Ordering::SeqCst);
1285
1286 {
1287 let mut tree = ForkTree::new();
1291 let letters = vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
1292
1293 for (i, letter) in letters.iter().enumerate() {
1294 tree.import::<_, TestError>(*letter, i, i, &|_, _| Ok(false)).unwrap();
1295 }
1296
1297 assert_eq!(
1300 tree.finalize_with_descendent_if(&"L", 11, &is_descendent_of, |i| *i == 10,),
1301 Ok(FinalizationResult::Changed(Some(10))),
1302 );
1303
1304 assert_eq!(n_is_descendent_of_calls.load(Ordering::SeqCst), 1);
1305 }
1306 }
1307
1308 #[test]
1309 fn map_works() {
1310 let (mut tree, _) = test_pez_fork_tree();
1311
1312 let is_descendent_of = |_: &&str, _: &&str| -> Result<bool, TestError> { Ok(false) };
1314 let is_root = tree.import("A1", 10, 1, &is_descendent_of).unwrap();
1315 assert!(is_root);
1316 let is_root = tree.import("A2", 10, 1, &is_descendent_of).unwrap();
1317 assert!(is_root);
1318
1319 let old_tree = tree.clone();
1320 let new_tree = tree.map(&mut |hash, _, _| hash.to_owned());
1321
1322 assert!(new_tree.iter().all(|(hash, _, data)| hash == data));
1324 assert_eq!(
1325 old_tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1326 new_tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1327 );
1328 }
1329
1330 #[test]
1331 fn prune_works_for_in_tree_hashes() {
1332 let (mut tree, is_descendent_of) = test_pez_fork_tree();
1333
1334 let removed = tree.prune(&"C", &30, &is_descendent_of, &|_| true).unwrap();
1335
1336 assert_eq!(tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(), vec!["B"]);
1337
1338 assert_eq!(
1339 tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1340 vec!["B", "C", "D", "E"],
1341 );
1342
1343 assert_eq!(
1344 removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(),
1345 vec!["A", "F", "H", "L", "M", "O", "I", "G", "J", "K"]
1346 );
1347
1348 let removed = tree.prune(&"E", &50, &is_descendent_of, &|_| true).unwrap();
1349
1350 assert_eq!(tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(), vec!["D"]);
1351
1352 assert_eq!(tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(), vec!["D", "E"]);
1353
1354 assert_eq!(removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(), vec!["B", "C"]);
1355 }
1356
1357 #[test]
1358 fn prune_works_for_out_of_tree_hashes() {
1359 let (mut tree, is_descendent_of) = test_pez_fork_tree();
1360
1361 let removed = tree.prune(&"c", &25, &is_descendent_of, &|_| true).unwrap();
1362
1363 assert_eq!(tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(), vec!["B"]);
1364
1365 assert_eq!(
1366 tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1367 vec!["B", "C", "D", "E"],
1368 );
1369
1370 assert_eq!(
1371 removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(),
1372 vec!["A", "F", "H", "L", "M", "O", "I", "G", "J", "K"]
1373 );
1374 }
1375
1376 #[test]
1377 fn prune_works_for_not_direct_ancestor() {
1378 let (mut tree, is_descendent_of) = test_pez_fork_tree();
1379
1380 let removed = tree.prune(&"m", &45, &is_descendent_of, &|height| *height == 3).unwrap();
1382
1383 assert_eq!(tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(), vec!["H"]);
1384
1385 assert_eq!(tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(), vec!["H", "L", "M"],);
1386
1387 assert_eq!(
1388 removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(),
1389 vec!["O", "I", "A", "B", "C", "D", "E", "F", "G", "J", "K"]
1390 );
1391 }
1392
1393 #[test]
1394 fn prune_works_for_far_away_ancestor() {
1395 let (mut tree, is_descendent_of) = test_pez_fork_tree();
1396
1397 let removed = tree.prune(&"m", &45, &is_descendent_of, &|height| *height == 2).unwrap();
1398
1399 assert_eq!(tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(), vec!["F"]);
1400
1401 assert_eq!(
1402 tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1403 vec!["F", "H", "L", "M"],
1404 );
1405
1406 assert_eq!(
1407 removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(),
1408 vec!["O", "I", "G", "A", "B", "C", "D", "E", "J", "K"]
1409 );
1410 }
1411
1412 #[test]
1413 fn find_node_backtracks_after_finding_highest_descending_node() {
1414 let mut tree = ForkTree::new();
1415
1416 let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
1421 match (*base, *block) {
1422 ("A", b) => Ok(b == "B" || b == "C" || b == "D"),
1423 ("B", b) | ("C", b) => Ok(b == "D"),
1424 ("0", _) => Ok(true),
1425 _ => Ok(false),
1426 }
1427 };
1428
1429 tree.import("A", 1, 1, &is_descendent_of).unwrap();
1430 tree.import("B", 2, 2, &is_descendent_of).unwrap();
1431 tree.import("C", 2, 4, &is_descendent_of).unwrap();
1432
1433 let node = tree.find_node_where(&"D", &3, &is_descendent_of, &|data| *data < 3).unwrap();
1437
1438 assert_eq!(node.unwrap().hash, "B");
1439 }
1440
1441 #[test]
1442 fn rebalance_works() {
1443 let (mut tree, _) = test_pez_fork_tree();
1444
1445 assert_eq!(
1449 tree.iter().map(|(h, _, _)| *h).collect::<Vec<_>>(),
1450 vec!["A", "B", "C", "D", "E", "F", "H", "L", "M", "O", "I", "G", "J", "K"],
1451 );
1452
1453 let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
1455 match (*base, *block) {
1456 (b, "P") => Ok(vec!["A", "F", "H", "L", "O"].into_iter().any(|n| n == b)),
1457 _ => Ok(false),
1458 }
1459 };
1460
1461 tree.import("P", 60, 6, &is_descendent_of).unwrap();
1462
1463 assert_eq!(
1467 tree.iter().map(|(h, _, _)| *h).collect::<Vec<_>>(),
1468 ["A", "F", "H", "L", "O", "P", "M", "I", "G", "B", "C", "D", "E", "J", "K"]
1469 );
1470 }
1471
1472 #[test]
1473 fn drain_filter_works() {
1474 let (mut tree, _) = test_pez_fork_tree();
1475
1476 let filter = |h: &&str, _: &u64, _: &u32| match *h {
1477 "A" | "B" | "F" | "G" => FilterAction::KeepNode,
1478 "C" => FilterAction::KeepTree,
1479 "H" | "J" => FilterAction::Remove,
1480 _ => panic!("Unexpected filtering for node: {}", *h),
1481 };
1482
1483 let removed = tree.drain_filter(filter);
1484
1485 assert_eq!(
1486 tree.iter().map(|(h, _, _)| *h).collect::<Vec<_>>(),
1487 ["A", "B", "C", "D", "E", "F", "G"]
1488 );
1489
1490 assert_eq!(
1491 removed.map(|(h, _, _)| h).collect::<Vec<_>>(),
1492 ["H", "L", "M", "O", "I", "J", "K"]
1493 );
1494 }
1495
1496 #[test]
1497 fn find_node_index_works() {
1498 let (tree, is_descendent_of) = test_pez_fork_tree();
1499
1500 let path = tree
1501 .find_node_index_where(&"D", &40, &is_descendent_of, &|_| true)
1502 .unwrap()
1503 .unwrap();
1504 assert_eq!(path, [0, 0, 0]);
1505
1506 let path = tree
1507 .find_node_index_where(&"O", &50, &is_descendent_of, &|_| true)
1508 .unwrap()
1509 .unwrap();
1510 assert_eq!(path, [0, 1, 0, 0]);
1511
1512 let path = tree
1513 .find_node_index_where(&"N", &60, &is_descendent_of, &|_| true)
1514 .unwrap()
1515 .unwrap();
1516 assert_eq!(path, [0, 1, 0, 0, 0]);
1517 }
1518
1519 #[test]
1520 fn find_node_index_with_predicate_works() {
1521 let is_descendent_of = |parent: &char, child: &char| match *parent {
1522 'A' => Ok(['B', 'C', 'D', 'E', 'F'].contains(child)),
1523 'B' => Ok(['C', 'D'].contains(child)),
1524 'C' => Ok(['D'].contains(child)),
1525 'E' => Ok(['F'].contains(child)),
1526 'D' | 'F' => Ok(false),
1527 _ => Err(TestError),
1528 };
1529
1530 let mut tree: ForkTree<char, u8, bool> = ForkTree::new();
1533 tree.import('A', 1, true, &is_descendent_of).unwrap();
1534 tree.import('B', 2, false, &is_descendent_of).unwrap();
1535 tree.import('C', 3, true, &is_descendent_of).unwrap();
1536 tree.import('D', 4, false, &is_descendent_of).unwrap();
1537
1538 tree.import('E', 2, true, &is_descendent_of).unwrap();
1539 tree.import('F', 3, false, &is_descendent_of).unwrap();
1540
1541 let path = tree
1542 .find_node_index_where(&'D', &4, &is_descendent_of, &|&value| !value)
1543 .unwrap()
1544 .unwrap();
1545 assert_eq!(path, [0, 0]);
1546
1547 let path = tree
1548 .find_node_index_where(&'D', &4, &is_descendent_of, &|&value| value)
1549 .unwrap()
1550 .unwrap();
1551 assert_eq!(path, [0, 0, 0]);
1552
1553 let path = tree
1554 .find_node_index_where(&'F', &3, &is_descendent_of, &|&value| !value)
1555 .unwrap();
1556 assert_eq!(path, None);
1557
1558 let path = tree
1559 .find_node_index_where(&'F', &3, &is_descendent_of, &|&value| value)
1560 .unwrap()
1561 .unwrap();
1562 assert_eq!(path, [0, 1]);
1563 }
1564
1565 #[test]
1566 fn find_node_works() {
1567 let (tree, is_descendent_of) = test_pez_fork_tree();
1568
1569 let node = tree.find_node_where(&"B", &20, &is_descendent_of, &|_| true).unwrap().unwrap();
1570 assert_eq!((node.hash, node.number), ("A", 10));
1571
1572 let node = tree.find_node_where(&"D", &40, &is_descendent_of, &|_| true).unwrap().unwrap();
1573 assert_eq!((node.hash, node.number), ("C", 30));
1574
1575 let node = tree.find_node_where(&"O", &50, &is_descendent_of, &|_| true).unwrap().unwrap();
1576 assert_eq!((node.hash, node.number), ("L", 40));
1577
1578 let node = tree.find_node_where(&"N", &60, &is_descendent_of, &|_| true).unwrap().unwrap();
1579 assert_eq!((node.hash, node.number), ("M", 50));
1580 }
1581
1582 #[test]
1583 fn post_order_traversal_requirement() {
1584 let (mut tree, is_descendent_of) = test_pez_fork_tree();
1585
1586 let is_descendent_of_for_post_order = |parent: &&str, child: &&str| match *parent {
1589 "A" => Err(TestError),
1590 "K" if *child == "Z" => Ok(true),
1591 _ => is_descendent_of(parent, child),
1592 };
1593
1594 let path = tree
1596 .find_node_index_where(&"N", &60, &is_descendent_of_for_post_order, &|_| true)
1597 .unwrap()
1598 .unwrap();
1599 assert_eq!(path, [0, 1, 0, 0, 0]);
1600
1601 let res = tree.import(&"Z", 100, 10, &is_descendent_of_for_post_order);
1603 assert_eq!(res, Ok(false));
1604 assert_eq!(
1605 tree.iter().map(|node| *node.0).collect::<Vec<_>>(),
1606 vec!["A", "B", "C", "D", "E", "F", "H", "L", "M", "O", "I", "G", "J", "K", "Z"],
1607 );
1608 }
1609}