@@ -371,6 +371,49 @@ describe('Simple tests on leaf nodes', () =>
371371 } ) ;
372372} ) ;
373373
374+ // Tests relating to `isShared` and cloning.
375+ // Tests on this subject that do not care about the specific interior structure of the tree
376+ // (and are thus maxNodeSize agnostic) can be added to testBTree to be testing on different branching factors instead.
377+ describe ( "cloning and sharing tests" , ( ) => {
378+ test ( "Regression test for failing to propagate shared when removing top two layers" , ( ) => {
379+ // This tests make a full 3 layer tree (height = 2), so use a small branching factor.
380+ const maxNodeSize = 4 ;
381+ const tree = new BTree < number , number > (
382+ undefined ,
383+ simpleComparator ,
384+ maxNodeSize
385+ ) ;
386+ // Build a 3 layer complete tree, all values 0.
387+ for (
388+ let index = 0 ;
389+ index < maxNodeSize * maxNodeSize * maxNodeSize ;
390+ index ++
391+ ) {
392+ tree . set ( index , 0 ) ;
393+ }
394+ // Leaf nodes don't count, so this is depth 2
395+ expect ( tree . height ) . toBe ( 2 ) ;
396+
397+ // Edit the tree so it has a node in the second layer with exactly one child (key 0).
398+ tree . deleteRange ( 1 , maxNodeSize * maxNodeSize , false ) ;
399+ expect ( tree . height ) . toBe ( 2 ) ;
400+
401+ // Make a clone that should never be mutated.
402+ const clone = tree . clone ( ) ;
403+
404+ // Mutate the original tree in such a way that clone gets mutated due to incorrect is shared tracking.
405+ // Delete everything outside of the internal node with only one child, so its child becomes the new root.
406+ tree . deleteRange ( maxNodeSize , Number . POSITIVE_INFINITY , false ) ;
407+ expect ( tree . height ) . toBe ( 0 ) ;
408+
409+ // Modify original
410+ tree . set ( 0 , 1 ) ;
411+
412+ // Check that clone is not modified as well:
413+ expect ( clone . get ( 0 ) ) . toBe ( 0 ) ;
414+ } ) ;
415+ } ) ;
416+
374417describe ( 'B+ tree with fanout 32' , testBTree . bind ( null , 32 ) ) ;
375418describe ( 'B+ tree with fanout 10' , testBTree . bind ( null , 10 ) ) ;
376419describe ( 'B+ tree with fanout 4' , testBTree . bind ( null , 4 ) ) ;
0 commit comments