@@ -229,7 +229,10 @@ impl<H, N, V> ForkTree<H, N, V> where
229229 number = n;
230230 data = d;
231231 } ,
232- None => return Ok ( false ) ,
232+ None => {
233+ self . rebalance ( ) ;
234+ return Ok ( false ) ;
235+ } ,
233236 }
234237 }
235238
@@ -251,7 +254,9 @@ impl<H, N, V> ForkTree<H, N, V> where
251254 }
252255
253256 fn node_iter ( & self ) -> impl Iterator < Item =& Node < H , N , V > > {
254- ForkTreeIterator { stack : self . roots . iter ( ) . collect ( ) }
257+ // we need to reverse the order of roots to maintain the expected
258+ // ordering since the iterator uses a stack to track state.
259+ ForkTreeIterator { stack : self . roots . iter ( ) . rev ( ) . collect ( ) }
255260 }
256261
257262 /// Iterates the nodes in the tree in pre-order.
@@ -939,6 +944,10 @@ mod test {
939944 // — J - K
940945 //
941946 // (where N is not a part of fork tree)
947+ //
948+ // NOTE: the tree will get automatically rebalance on import and won't be laid out like the
949+ // diagram above. the children will be ordered by subtree depth and the longest branches
950+ // will be on the leftmost side of the tree.
942951 let is_descendent_of = |base : & & str , block : & & str | -> Result < bool , TestError > {
943952 let letters = vec ! [ "B" , "C" , "D" , "E" , "F" , "G" , "H" , "I" , "J" , "K" , "L" , "M" , "O" ] ;
944953 match ( * base, * block) {
@@ -1132,7 +1141,7 @@ mod test {
11321141
11331142 assert_eq ! (
11341143 tree. roots( ) . map( |( h, n, _) | ( h. clone( ) , n. clone( ) ) ) . collect:: <Vec <_>>( ) ,
1135- vec![ ( "I " , 4 ) , ( "L " , 4 ) ] ,
1144+ vec![ ( "L " , 4 ) , ( "I " , 4 ) ] ,
11361145 ) ;
11371146
11381147 // finalizing a node from another fork that isn't part of the tree clears the tree
@@ -1180,7 +1189,7 @@ mod test {
11801189
11811190 assert_eq ! (
11821191 tree. roots( ) . map( |( h, n, _) | ( h. clone( ) , n. clone( ) ) ) . collect:: <Vec <_>>( ) ,
1183- vec![ ( "I " , 4 ) , ( "L " , 4 ) ] ,
1192+ vec![ ( "L " , 4 ) , ( "I " , 4 ) ] ,
11841193 ) ;
11851194
11861195 assert_eq ! (
@@ -1354,11 +1363,11 @@ mod test {
13541363 vec![
13551364 ( "A" , 1 ) ,
13561365 ( "B" , 2 ) , ( "C" , 3 ) , ( "D" , 4 ) , ( "E" , 5 ) ,
1357- ( "F" , 2 ) ,
1366+ ( "F" , 2 ) , ( "H" , 3 ) , ( "L" , 4 ) , ( "M" , 5 ) ,
1367+ ( "O" , 5 ) ,
1368+ ( "I" , 4 ) ,
13581369 ( "G" , 3 ) ,
1359- ( "H" , 3 ) , ( "I" , 4 ) ,
1360- ( "L" , 4 ) , ( "M" , 5 ) , ( "O" , 5 ) ,
1361- ( "J" , 2 ) , ( "K" , 3 )
1370+ ( "J" , 2 ) , ( "K" , 3 ) ,
13621371 ] ,
13631372 ) ;
13641373 }
@@ -1480,7 +1489,7 @@ mod test {
14801489
14811490 assert_eq ! (
14821491 removed. map( |( hash, _, _) | hash) . collect:: <Vec <_>>( ) ,
1483- vec![ "A" , "F" , "G " , "H " , "I " , "L " , "M " , "O " , "J" , "K" ]
1492+ vec![ "A" , "F" , "H " , "L " , "M " , "O " , "I " , "G " , "J" , "K" ]
14841493 ) ;
14851494
14861495 let removed = tree. prune (
@@ -1545,19 +1554,30 @@ mod test {
15451554 fn tree_rebalance ( ) {
15461555 let ( mut tree, _) = test_fork_tree ( ) ;
15471556
1557+ // the tree is automatically rebalanced on import, therefore we should iterate in preorder
1558+ // exploring the longest forks first. check the ascii art above to understand the expected
1559+ // output below.
15481560 assert_eq ! (
15491561 tree. iter( ) . map( |( h, _, _) | * h) . collect:: <Vec <_>>( ) ,
1550- vec![ "A" , "B" , "C" , "D" , "E" , "F" , "G " , "H " , "I " , "L " , "M " , "O " , "J" , "K" ] ,
1562+ vec![ "A" , "B" , "C" , "D" , "E" , "F" , "H " , "L " , "M " , "O " , "I " , "G " , "J" , "K" ] ,
15511563 ) ;
15521564
1553- // after rebalancing the tree we should iterate in preorder exploring
1554- // the longest forks first. check the ascii art above to understand the
1555- // expected output below.
1556- tree. rebalance ( ) ;
1565+ // let's add a block "P" which is a descendent of block "O"
1566+ let is_descendent_of = |base : & & str , block : & & str | -> Result < bool , TestError > {
1567+ match ( * base, * block) {
1568+ ( b, "P" ) => Ok ( vec ! [ "A" , "F" , "L" , "O" ] . into_iter ( ) . any ( |n| n == b) ) ,
1569+ _ => Ok ( false ) ,
1570+ }
1571+ } ;
1572+
1573+ tree. import ( "P" , 6 , ( ) , & is_descendent_of) . unwrap ( ) ;
15571574
1575+ // this should re-order the tree, since the branch "A -> B -> C -> D -> E" is no longer tied
1576+ // with 5 blocks depth. additionally "O" should be visited before "M" now, since it has one
1577+ // descendent "P" which makes that branch 6 blocks long.
15581578 assert_eq ! (
15591579 tree. iter( ) . map( |( h, _, _) | * h) . collect:: <Vec <_>>( ) ,
1560- [ "A" , "B " , "C " , "D " , "E " , "F " , "H " , "L " , "M " , "O " , "I " , "G " , "J" , "K" ]
1580+ [ "A" , "F " , "H " , "L " , "O " , "P " , "M " , "I " , "G " , "B " , "C " , "D" , "E ", "J" , "K" ]
15611581 ) ;
15621582 }
15631583}
0 commit comments