1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.mavibot.btree;
21
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29
30 import java.io.IOException;
31 import java.lang.reflect.Array;
32 import java.util.ArrayList;
33 import java.util.HashSet;
34 import java.util.List;
35 import java.util.Random;
36 import java.util.Set;
37
38 import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
39 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
40 import org.apache.directory.mavibot.btree.serializer.IntSerializer;
41 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
42 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
43 import org.junit.Ignore;
44 import org.junit.Test;
45
46
47
48
49
50
51
52 public class InMemoryBTreeTest
53 {
54
55 private static int[] sortedValues = new int[]
56 {
57 0, 1, 2, 4, 5, 6, 8, 9, 11, 12,
58 13, 14, 16, 19, 21, 22, 23, 25, 26, 28,
59 30, 31, 32, 34, 36, 37, 38, 39, 41, 42,
60 44, 45, 47, 50, 52, 53, 54, 55, 56, 58,
61 59, 60, 63, 64, 67, 68, 70, 72, 73, 74,
62 76, 77, 79, 80, 81, 82, 85, 88, 89, 90,
63 92, 93, 95, 97, 98, 100, 101, 102, 103, 104,
64 105, 106, 107, 109, 110, 111, 112, 117, 118, 120,
65 121, 128, 129, 130, 131, 132, 135, 136, 137, 138,
66 139, 140, 141, 142, 143, 146, 147, 148, 149, 150,
67 152, 154, 156, 160, 161, 162, 163, 165, 167, 168,
68 169, 171, 173, 174, 175, 176, 177, 178, 179, 180,
69 181, 182, 183, 189, 190, 193, 194, 195, 199, 200,
70 202, 203, 205, 206, 207, 208, 209, 210, 212, 215,
71 216, 217, 219, 220, 222, 223, 224, 225, 226, 227,
72 228, 230, 231, 235, 236, 238, 239, 241, 242, 243,
73 245, 246, 247, 249, 250, 251, 252, 254, 256, 257,
74 258, 259, 261, 262, 263, 264, 266, 268, 272, 273,
75 274, 276, 277, 278, 279, 282, 283, 286, 289, 290,
76 292, 293, 294, 296, 298, 299, 300, 301, 303, 305,
77 308, 310, 316, 317, 318, 319, 322, 323, 324, 326,
78 327, 329, 331, 333, 334, 335, 336, 337, 338, 339,
79 340, 341, 346, 347, 348, 349, 350, 351, 352, 353,
80 355, 356, 357, 358, 359, 361, 365, 366, 373, 374,
81 375, 379, 380, 381, 382, 384, 385, 387, 388, 389,
82 390, 392, 393, 395, 396, 397, 398, 399, 400, 401,
83 404, 405, 406, 407, 410, 411, 412, 416, 417, 418,
84 420, 421, 422, 424, 426, 427, 428, 430, 431, 432,
85 433, 436, 439, 441, 443, 444, 445, 446, 447, 448,
86 449, 450, 451, 452, 453, 454, 455, 456, 458, 459,
87 464, 466, 469, 470, 471, 472, 475, 477, 478, 482,
88 483, 484, 485, 486, 488, 490, 491, 492, 493, 495,
89 496, 497, 500, 502, 503, 504, 505, 506, 507, 509,
90 510, 514, 516, 518, 520, 521, 523, 524, 526, 527,
91 528, 529, 530, 532, 533, 535, 538, 539, 540, 542,
92 543, 544, 546, 547, 549, 550, 551, 553, 554, 558,
93 559, 561, 563, 564, 566, 567, 568, 569, 570, 571,
94 572, 576, 577, 578, 580, 582, 583, 586, 588, 589,
95 590, 592, 593, 596, 597, 598, 599, 600, 601, 604,
96 605, 606, 607, 609, 610, 613, 615, 617, 618, 619,
97 620, 621, 626, 627, 628, 631, 632, 633, 635, 636,
98 637, 638, 639, 640, 641, 643, 645, 647, 648, 649,
99 650, 651, 652, 653, 655, 656, 658, 659, 660, 662,
100 666, 669, 673, 674, 675, 676, 677, 678, 680, 681,
101 682, 683, 685, 686, 687, 688, 689, 690, 691, 692,
102 693, 694, 696, 698, 699, 700, 701, 705, 708, 709,
103 711, 713, 714, 715, 719, 720, 723, 725, 726, 727,
104 728, 731, 732, 733, 734, 735, 736, 739, 740, 743,
105 744, 745, 746, 747, 749, 750, 752, 753, 762, 763,
106 765, 766, 768, 770, 772, 773, 774, 776, 777, 779,
107 782, 784, 785, 788, 790, 791, 793, 794, 795, 798,
108 799, 800, 801, 803, 804, 805, 808, 810, 812, 813,
109 814, 816, 818, 821, 822, 823, 824, 827, 828, 829,
110 831, 832, 833, 834, 835, 837, 838, 839, 840, 843,
111 846, 847, 849, 852, 853, 854, 856, 857, 859, 860,
112 863, 864, 865, 866, 867, 868, 869, 872, 873, 877,
113 880, 881, 882, 883, 887, 888, 889, 890, 891, 894,
114 895, 897, 898, 899, 902, 904, 905, 907, 908, 910,
115 911, 912, 915, 916, 917, 918, 919, 923, 925, 926,
116 927, 928, 929, 930, 932, 935, 936, 937, 938, 939,
117 944, 945, 947, 952, 953, 954, 955, 956, 957, 958,
118 960, 967, 970, 971, 972, 974, 975, 976, 978, 979,
119 980, 981, 983, 984, 985, 987, 988, 989, 991, 995
120 };
121
122
123
124
125
126 private boolean checkTreeLong( Set<Long> expected, BTree<Long, String> btree ) throws IOException
127 {
128
129
130 for ( Long key : expected )
131 {
132 try
133 {
134 btree.get( key );
135 }
136 catch ( KeyNotFoundException knfe )
137 {
138 return false;
139 }
140 }
141
142 return true;
143 }
144
145
146
147
148
149
150
151
152
153 @Test
154 public void testPageInsert() throws Exception
155 {
156 Set<Long> expected = new HashSet<Long>();
157 List<Long> added = new ArrayList<Long>();
158
159 Random random = new Random( System.nanoTime() );
160
161 int nbError = 0;
162
163 long l1 = System.currentTimeMillis();
164 int n = 0;
165 long delta = l1;
166 int nbTrees = 1000;
167 int nbElems = 1000;
168
169 for ( int j = 0; j < nbTrees; j++ )
170 {
171 BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
172 StringSerializer.INSTANCE );
173 btree.setPageSize( 32 );
174
175 for ( int i = 0; i < nbElems; i++ )
176 {
177 Long key = ( long ) random.nextInt( 1024 );
178 String value = "V" + key;
179 expected.add( key );
180 added.add( key );
181
182
183
184 try
185 {
186 btree.insert( key, value );
187 }
188 catch ( Exception e )
189 {
190 e.printStackTrace();
191 System.out.println( btree );
192 System.out.println( "Error while adding " + value );
193 nbError++;
194 btree.close();
195
196 return;
197 }
198 }
199
200 assertTrue( checkTreeLong( expected, btree ) );
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 if ( j % 10000 == 0 )
224 {
225 if ( n > 0 )
226 {
227 long t0 = System.currentTimeMillis();
228 System.out.println( "Delta" + n + ": " + ( t0 - delta ) );
229 delta = t0;
230 }
231
232 n++;
233 }
234
235 expected.clear();
236 added.clear();
237
238 btree.close();
239 }
240
241 long l2 = System.currentTimeMillis();
242
243 System.out.println( "Delta : " + ( l2 - l1 ) + ", nbError = " + nbError
244 + ", Nb insertion per second : " + ( nbTrees * nbElems * 1000 ) / ( l2 - l1 ) );
245 }
246
247
248
249
250
251
252
253
254
255
256 @Test
257 public void testPageDeleteRandom() throws IOException
258 {
259 Set<Long> expected = new HashSet<Long>();
260 List<Long> added = new ArrayList<Long>();
261
262 Random random = new Random( System.nanoTime() );
263
264 int nbError = 0;
265
266 long l1 = System.currentTimeMillis();
267 int n = 0;
268 long delta = l1;
269 int nbTrees = 1000;
270 int nbElems = 1000;
271
272 for ( int j = 0; j < nbTrees; j++ )
273 {
274 BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
275 StringSerializer.INSTANCE );
276 btree.setPageSize( 8 );
277
278 for ( int i = 0; i < nbElems; i++ )
279 {
280 Long key = ( long ) random.nextInt( 1024 );
281 String value = "V" + key;
282 expected.add( key );
283 added.add( key );
284
285
286
287 try
288 {
289 btree.insert( key, value );
290 }
291 catch ( Exception e )
292 {
293 e.printStackTrace();
294 System.out.println( btree );
295 System.out.println( "Error while adding " + value );
296 nbError++;
297 btree.close();
298
299 return;
300 }
301 }
302
303 assertTrue( checkTreeLong( expected, btree ) );
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328 for ( long element : expected )
329 {
330
331
332
333 Tuple<Long, String> tuple = btree.delete( element );
334
335 if ( tuple == null )
336 {
337 System.out.println( btree );
338 }
339
340 assertEquals( Long.valueOf( element ), tuple.getKey() );
341
342 checkNull( btree, element );
343
344
345 }
346
347 if ( j % 10000 == 0 )
348 {
349 if ( n > 0 )
350 {
351 long t0 = System.currentTimeMillis();
352 System.out.println( "Delta" + n + ": " + ( t0 - delta ) );
353 delta = t0;
354 }
355
356 n++;
357
358 }
359
360 expected.clear();
361 added.clear();
362
363 btree.close();
364 }
365
366 long l2 = System.currentTimeMillis();
367
368 System.out.println( "Delta : " + ( l2 - l1 ) + ", nbError = " + nbError
369 + ", Nb deletion per second : " + ( nbTrees * nbElems * 1000 ) / ( l2 - l1 ) );
370 }
371
372
373 @Test
374 public void testDeleteDebug() throws IOException
375 {
376 long[] values = new long[]
377 {
378 148, 746, 525, 327, 1, 705, 171, 1023, 769, 1021,
379 128, 772, 744, 771, 925, 884, 346, 519, 989, 350,
380 649, 895, 464, 164, 190, 298, 203, 69, 483, 38,
381 266, 83, 88, 285, 879, 342, 231, 432, 722, 432,
382 258, 307, 237, 151, 43, 36, 135, 166, 325, 886,
383 878, 307, 925, 835, 800, 895, 519, 947, 703, 27,
384 324, 668, 40, 943, 804, 230, 223, 584, 828, 575,
385 69, 955, 344, 325, 896, 423, 855, 783, 225, 447,
386 28, 23, 262, 679, 782, 517, 412, 878, 641, 940,
387 368, 245, 1005, 226, 939, 320, 396, 437, 373, 61
388 };
389
390 BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
391 StringSerializer.INSTANCE );
392 btree.setPageSize( 8 );
393
394 for ( long value : values )
395 {
396 String strValue = "V" + value;
397
398 try
399 {
400 btree.insert( value, strValue );
401 }
402 catch ( Exception e )
403 {
404 e.printStackTrace();
405 System.out.println( btree );
406 System.out.println( "Error while adding " + value );
407 btree.close();
408
409 return;
410 }
411 }
412
413 long[] deletes = new long[]
414 {
415 1,
416 828,
417 285,
418 804,
419 258,
420 262,
421 };
422
423 for ( long value : deletes )
424 {
425 Tuple<Long, String> tuple = btree.delete( value );
426
427 if ( tuple != null )
428 {
429 assertEquals( Long.valueOf( value ), tuple.getKey() );
430 }
431
432 checkNull( btree, value );
433 }
434
435 btree.close();
436 }
437
438
439
440
441
442 @Test
443 public void testPageDelete() throws Exception
444 {
445 Set<Long> expected = new HashSet<Long>();
446 List<Long> added = new ArrayList<Long>();
447
448 Random random = new Random( System.nanoTime() );
449
450 BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
451 StringSerializer.INSTANCE );
452 btree.setPageSize( 8 );
453
454
455 for ( int i = 0; i < 8; i++ )
456 {
457 Long key = ( long ) random.nextInt( 1024 );
458 String value = "V" + key;
459 added.add( key );
460
461 try
462 {
463 btree.insert( key, value );
464 }
465 catch ( Exception e )
466 {
467 e.printStackTrace();
468 System.out.println( btree );
469 System.out.println( "Error while adding " + value );
470 btree.close();
471
472 return;
473 }
474 }
475
476 assertTrue( checkTreeLong( expected, btree ) );
477
478
479 for ( long key : added )
480 {
481
482 try
483 {
484 btree.delete( key );
485 }
486 catch ( Exception e )
487 {
488 e.printStackTrace();
489 System.out.println( btree );
490 System.out.println( "Error while deleting " + key );
491 btree.close();
492
493 return;
494 }
495
496 assertTrue( checkTreeLong( expected, btree ) );
497 }
498
499 btree.close();
500 }
501
502
503
504
505
506
507 @Test
508 @Ignore("This is a debug test")
509 public void testPageInsertDebug() throws Exception
510 {
511 BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
512 StringSerializer.INSTANCE );
513 btree.setPageSize( 4 );
514
515 Long[] elems = new Long[]
516 {
517 235L, 135L, 247L, 181L, 12L, 112L, 117L, 253L,
518 37L, 158L, 56L, 118L, 184L, 101L, 173L, 126L,
519 61L, 81L, 140L, 173L, 32L, 163L, 224L, 114L,
520 133L, 18L, 14L, 82L, 107L, 219L, 244L, 255L,
521 6L, 103L, 170L, 151L, 134L, 196L, 155L, 97L,
522 80L, 122L, 89L, 253L, 33L, 101L, 56L, 168L,
523 253L, 187L, 99L, 58L, 151L, 206L, 34L, 96L,
524 20L, 188L, 143L, 150L, 76L, 111L, 234L, 66L,
525 12L, 194L, 164L, 190L, 19L, 192L, 161L, 147L,
526 92L, 89L, 237L, 187L, 250L, 13L, 233L, 34L,
527 187L, 232L, 248L, 237L, 129L, 1L, 233L, 252L,
528 18L, 98L, 56L, 121L, 162L, 233L, 29L, 48L,
529 176L, 48L, 182L, 130L
530 };
531
532 int size = 0;
533 for ( Long elem : elems )
534 {
535 size++;
536 String value = "V" + elem;
537 btree.insert( elem, value );
538
539 System.out.println( "Adding " + elem + " :\n" + btree );
540
541 for ( int i = 0; i < size; i++ )
542 {
543 try
544 {
545 btree.get( elems[i] );
546 }
547 catch ( KeyNotFoundException knfe )
548 {
549 System.out.println( "Bad tree, missing " + elems[i] + ", " + btree );
550 }
551 }
552
553 if ( size == 27 )
554 {
555 System.out.println( btree );
556 }
557
558 }
559
560
561
562 btree.close();
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614 @Test
615 public void testBrowseForward() throws Exception
616 {
617
618 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
619 StringSerializer.INSTANCE );
620 btree.setPageSize( 8 );
621
622
623 for ( int value : sortedValues )
624 {
625 String strValue = "V" + value;
626
627 btree.insert( value, strValue );
628 }
629
630
631 for ( int key : sortedValues )
632 {
633 String value = btree.get( key );
634
635 assertNotNull( value );
636 }
637
638
639 int pos = 10;
640 TupleCursor<Integer, String> cursor = btree.browseFrom( sortedValues[pos] );
641
642 while ( cursor.hasNext() )
643 {
644 Tuple<Integer, String> tuple = cursor.next();
645
646 assertNotNull( tuple );
647 Integer val = sortedValues[pos];
648 Integer res = tuple.getKey();
649 assertEquals( val, res );
650 pos++;
651 }
652
653 cursor.close();
654
655
656 cursor = btree.browseFrom( 7 );
657
658
659 pos = 6;
660
661 while ( cursor.hasNext() )
662 {
663 Tuple<Integer, String> tuple = cursor.next();
664
665 assertNotNull( tuple );
666 Integer val = sortedValues[pos];
667 Integer res = tuple.getKey();
668 assertEquals( val, res );
669 pos++;
670 }
671
672 cursor.close();
673
674
675 cursor = btree.browse();
676
677 pos = 0;
678
679 while ( cursor.hasNext() )
680 {
681 Tuple<Integer, String> tuple = cursor.next();
682
683 assertNotNull( tuple );
684 Integer val = sortedValues[pos];
685 Integer res = tuple.getKey();
686 assertEquals( val, res );
687 pos++;
688 }
689
690 cursor.close();
691 btree.close();
692 }
693
694
695
696
697
698
699 @Test
700 public void testBrowseBackward() throws Exception
701 {
702
703 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
704 StringSerializer.INSTANCE );
705 btree.setPageSize( 8 );
706
707
708 for ( int value : sortedValues )
709 {
710 String strValue = "V" + value;
711
712 btree.insert( value, strValue );
713 }
714
715
716 for ( int key : sortedValues )
717 {
718 String value = btree.get( key );
719
720 assertNotNull( value );
721 }
722
723
724 int pos = 10;
725 TupleCursor<Integer, String> cursor = btree.browseFrom( sortedValues[pos] );
726
727 while ( cursor.hasPrev() )
728 {
729 Tuple<Integer, String> tuple = cursor.prev();
730
731 pos--;
732
733 assertNotNull( tuple );
734 Integer val = sortedValues[pos];
735 Integer res = tuple.getKey();
736 assertEquals( val, res );
737 }
738
739 cursor.close();
740
741
742 cursor = btree.browseFrom( 7 );
743
744
745 pos = 6;
746
747 while ( cursor.hasPrev() )
748 {
749 Tuple<Integer, String> tuple = cursor.prev();
750
751 pos--;
752 assertNotNull( tuple );
753 Integer val = sortedValues[pos];
754 Integer res = tuple.getKey();
755 assertEquals( val, res );
756 }
757
758 cursor.close();
759
760
761 cursor = btree.browse();
762
763 pos = 0;
764
765 assertFalse( cursor.hasPrev() );
766
767 cursor.close();
768 btree.close();
769 }
770
771
772
773
774
775 @Test
776 public void testBrowseEmptyTree() throws Exception
777 {
778
779 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
780 StringSerializer.INSTANCE );
781 btree.setPageSize( 8 );
782
783 TupleCursor<Integer, String> cursor = btree.browse();
784
785 assertFalse( cursor.hasNext() );
786 assertFalse( cursor.hasPrev() );
787
788 cursor.close();
789 btree.close();
790 }
791
792
793
794
795
796 @Test
797 public void testBrowseForwardBackward() throws Exception
798 {
799
800 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
801 StringSerializer.INSTANCE );
802 btree.setPageSize( 4 );
803
804 for ( int i = 0; i < 16; i++ )
805 {
806 String strValue = "V" + i;
807 btree.insert( i, strValue );
808 }
809
810
811 TupleCursor<Integer, String> cursor = btree.browseFrom( 8 );
812
813 assertTrue( cursor.hasNext() );
814
815
816 assertEquals( 8, cursor.next().getKey().intValue() );
817
818
819 assertEquals( 9, cursor.next().getKey().intValue() );
820
821
822 assertEquals( 10, cursor.next().getKey().intValue() );
823
824
825 assertEquals( 11, cursor.next().getKey().intValue() );
826
827
828 assertEquals( 12, cursor.next().getKey().intValue() );
829
830 assertTrue( cursor.hasPrev() );
831
832
833 assertEquals( 11, cursor.prev().getKey().intValue() );
834
835
836 assertEquals( 10, cursor.prev().getKey().intValue() );
837
838
839 assertEquals( 9, cursor.prev().getKey().intValue() );
840
841
842 assertEquals( 8, cursor.prev().getKey().intValue() );
843
844
845 assertEquals( 7, cursor.prev().getKey().intValue() );
846
847 cursor.close();
848 btree.close();
849 }
850
851
852
853
854
855 @Test
856 public void testDeleteFromFullLeaves() throws Exception
857 {
858
859 BTree<Integer, String> btree = createTwoLevelBTreeFullLeaves();
860
861
862
863
864 btree.delete( 1 );
865
866 checkNull( btree, 1 );
867
868 btree.insert( 1, "V1" );
869
870 btree.delete( 3 );
871
872 checkNull( btree, 3 );
873
874 btree.insert( 3, "V3" );
875
876 btree.delete( 4 );
877
878 checkNull( btree, 4 );
879
880 btree.insert( 4, "V4" );
881
882 btree.delete( 11 );
883
884 checkNull( btree, 11 );
885
886 btree.insert( 11, "V11" );
887
888 btree.delete( 20 );
889
890 checkNull( btree, 20 );
891
892 btree.insert( 20, "V20" );
893
894 btree.delete( 0 );
895
896 checkNull( btree, 0 );
897
898 btree.delete( 5 );
899
900 checkNull( btree, 5 );
901
902 btree.delete( 9 );
903
904 checkNull( btree, 9 );
905
906 btree.close();
907 }
908
909
910
911
912
913 @Test
914 public void testExist() throws IOException, KeyNotFoundException
915 {
916
917 BTree<Integer, String> btree = createTwoLevelBTreeFullLeaves();
918
919 for ( int i = 1; i < 21; i++ )
920 {
921 assertTrue( btree.hasKey( 5 ) );
922 }
923
924 assertFalse( btree.hasKey( 0 ) );
925 assertFalse( btree.hasKey( 21 ) );
926
927 btree.close();
928 }
929
930
931
932
933
934 @Test
935 public void testDeleteBorrowFromSibling() throws Exception
936 {
937
938 BTree<Integer, String> btree = createTwoLevelBTreeFullLeaves();
939
940
941
942 btree.delete( 3 );
943 btree.delete( 4 );
944
945
946 btree.delete( 19 );
947 btree.delete( 20 );
948
949
950 btree.delete( 11 );
951 btree.delete( 12 );
952
953
954 btree.delete( 1 );
955
956 checkNull( btree, 1 );
957
958
959 btree.delete( 18 );
960
961 checkNull( btree, 18 );
962
963
964 btree.delete( 5 );
965
966 checkNull( btree, 5 );
967
968
969 btree.delete( 16 );
970
971 checkNull( btree, 16 );
972
973 btree.close();
974
975
976 btree = createMultiLevelBTreeLeavesHalfFull();
977
978
979 btree.insert( 8, "V8" );
980 btree.insert( 9, "V9" );
981
982
983 btree.delete( 2 );
984
985 checkNull( btree, 2 );
986
987 btree.delete( 6 );
988
989 checkNull( btree, 6 );
990
991
992 btree.insert( 96, "V96" );
993 btree.insert( 97, "V97" );
994
995
996 btree.delete( 98 );
997
998 checkNull( btree, 98 );
999
1000 btree.delete( 99 );
1001
1002 checkNull( btree, 99 );
1003
1004
1005 btree.insert( 48, "V48" );
1006
1007 btree.delete( 42 );
1008
1009 checkNull( btree, 42 );
1010
1011 btree.insert( 72, "V72" );
1012
1013 btree.delete( 67 );
1014
1015 checkNull( btree, 67 );
1016
1017 btree.close();
1018 }
1019
1020
1021
1022
1023
1024
1025 @Test
1026 public void testBrowseNonExistingKey() throws Exception
1027 {
1028
1029 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
1030 StringSerializer.INSTANCE );
1031 btree.setPageSize( 8 );
1032 for ( int i = 0; i < 11; i++ )
1033 {
1034 btree.insert( i, String.valueOf( i ) );
1035 }
1036
1037 for ( int i = 0; i < 11; i++ )
1038 {
1039 assertNotNull( btree.get( i ) );
1040 }
1041
1042 assertTrue( btree.hasKey( 8 ) );
1043 assertFalse( btree.hasKey( 11 ) );
1044
1045 TupleCursor<Integer, String> cursor = btree.browseFrom( 11 );
1046 assertFalse( cursor.hasNext() );
1047
1048 btree.close();
1049 }
1050
1051
1052 private Page<Integer, String> createLeaf( BTree<Integer, String> btree, long revision,
1053 Tuple<Integer, String>... tuples )
1054 {
1055 InMemoryLeaf<Integer, String> leaf = new InMemoryLeaf<Integer, String>( btree );
1056 int pos = 0;
1057 leaf.setRevision( revision );
1058 leaf.setNbElems( tuples.length );
1059 leaf.setKeys( new KeyHolder[leaf.getNbElems()] );
1060 leaf.values = ( InMemoryValueHolder<String>[] ) Array
1061 .newInstance( InMemoryValueHolder.class, leaf.getNbElems() );
1062
1063 for ( Tuple<Integer, String> tuple : tuples )
1064 {
1065 leaf.setKey( pos, new KeyHolder<Integer>( tuple.getKey() ) );
1066 leaf.values[pos] = new InMemoryValueHolder<String>( btree, tuple.getValue() );
1067 pos++;
1068 }
1069
1070 return leaf;
1071 }
1072
1073
1074 private void addPage( BTree<Integer, String> btree, InMemoryNode<Integer, String> node, Page<Integer, String> page,
1075 int pos )
1076 throws EndOfFileExceededException, IOException
1077 {
1078 Tuple<Integer, String> leftmost = page.findLeftMost();
1079
1080 if ( pos > 0 )
1081 {
1082 node.setKey( pos - 1, new KeyHolder<Integer>( leftmost.getKey() ) );
1083 }
1084
1085 node.setPageHolder( pos, new PageHolder<Integer, String>( btree, page ) );
1086 }
1087
1088
1089
1090
1091
1092 private BTree<Integer, String> createTwoLevelBTreeFullLeaves() throws IOException
1093 {
1094 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
1095 StringSerializer.INSTANCE );
1096 btree.setPageSize( 4 );
1097
1098
1099 int[] keys = new int[]
1100 { 1, 2, 5, 6, 3, 4, 9, 10, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 19, 20 };
1101
1102 for ( int key : keys )
1103 {
1104 String value = "V" + key;
1105 btree.insert( key, value );
1106 }
1107
1108 return btree;
1109 }
1110
1111
1112
1113
1114
1115 private BTree<Integer, String> createTwoLevelBTreeHalfFullLeaves() throws IOException
1116 {
1117 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
1118 StringSerializer.INSTANCE );
1119 btree.setPageSize( 4 );
1120
1121
1122 int[] keys = new int[]
1123 { 1, 2, 17, 18, 13, 14, 9, 10, 5, 6, 3 };
1124
1125 for ( int key : keys )
1126 {
1127 String value = "V" + key;
1128 btree.insert( key, value );
1129 }
1130
1131
1132 btree.delete( 3 );
1133
1134 return btree;
1135 }
1136
1137
1138 private Set<Integer> EXPECTED1 = new HashSet<Integer>();
1139
1140
1141
1142
1143
1144 private BTree<Integer, String> createMultiLevelBTreeLeavesHalfFull() throws IOException
1145 {
1146
1147 int pageSize = 4;
1148
1149 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
1150 StringSerializer.INSTANCE,
1151 pageSize );
1152
1153 InMemoryNode<Integer, String> root = new InMemoryNode<Integer, String>( btree, 1L, pageSize );
1154
1155
1156 int counter = 1;
1157 for ( int i = 0; i < pageSize + 1; i++ )
1158 {
1159 InMemoryNode<Integer, String> node = new InMemoryNode<Integer, String>( btree, 1L, pageSize );
1160
1161 for ( int j = 0; j < pageSize + 1; j++ )
1162 {
1163 int even = counter * 2;
1164
1165 @SuppressWarnings("unchecked")
1166 Page<Integer, String> leaf = createLeaf(
1167 btree,
1168 1L,
1169 new Tuple<Integer, String>( even, "v" + even ),
1170 new Tuple<Integer, String>( even + 1, "v" + ( even + 1 ) )
1171 );
1172
1173 counter += 2;
1174
1175 addPage( btree, node, leaf, j );
1176
1177 EXPECTED1.add( even );
1178 EXPECTED1.add( even + 1 );
1179 }
1180
1181 addPage( btree, root, node, i );
1182 }
1183
1184 ( ( AbstractBTree<Integer, String> ) btree ).setRootPage( root );
1185
1186 return btree;
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196 private void checkRemoval( BTree<Integer, String> btree, int element, Set<Integer> expected ) throws IOException, KeyNotFoundException
1197 {
1198 Tuple<Integer, String> removed = btree.delete( element );
1199 assertEquals( element, removed.getKey().intValue() );
1200 assertEquals( "v" + element, removed.getValue() );
1201
1202 checkNull( btree, element );
1203
1204 expected.remove( element );
1205 checkTree( btree, expected );
1206 }
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 private void checkTree( BTree<Integer, String> btree, Set<Integer> expected ) throws KeyNotFoundException
1217 {
1218 try
1219 {
1220 TupleCursor<Integer, String> cursor = btree.browse();
1221 Integer value = null;
1222
1223 while ( cursor.hasNext() )
1224 {
1225 Tuple<Integer, String> tuple = cursor.next();
1226
1227 if ( value == null )
1228 {
1229 value = tuple.getKey();
1230 }
1231 else
1232 {
1233 assertTrue( value < tuple.getKey() );
1234 value = tuple.getKey();
1235 }
1236
1237 assertTrue( expected.contains( value ) );
1238 expected.remove( value );
1239 }
1240
1241 assertEquals( 0, expected.size() );
1242 }
1243 catch ( IOException ioe )
1244 {
1245 fail();
1246 }
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257 private void delete( BTree<Integer, String> btree, Set<Integer> expected, int... values ) throws IOException
1258 {
1259 for ( int value : values )
1260 {
1261 btree.delete( value );
1262 expected.remove( value );
1263 }
1264 }
1265
1266
1267
1268
1269
1270
1271 @Test
1272 public void testDeleteMultiLevelsLeadingToLeafMerge() throws Exception
1273 {
1274 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1275
1276
1277 Tuple<Integer, String> removed = btree.delete( 2 );
1278 assertEquals( 2, removed.getKey().intValue() );
1279 assertEquals( "v2", removed.getValue() );
1280 checkNull( btree, 2 );
1281
1282
1283 removed = btree.delete( 7 );
1284 assertEquals( 7, removed.getKey().intValue() );
1285 assertEquals( "v7", removed.getValue() );
1286 checkNull( btree, 7 );
1287
1288
1289 removed = btree.delete( 6 );
1290 assertEquals( 6, removed.getKey().intValue() );
1291 assertEquals( "v6", removed.getValue() );
1292 checkNull( btree, 6 );
1293
1294
1295 removed = btree.delete( 11 );
1296 assertEquals( 11, removed.getKey().intValue() );
1297 assertEquals( "v11", removed.getValue() );
1298 checkNull( btree, 11 );
1299
1300
1301 removed = btree.delete( 99 );
1302 assertEquals( 99, removed.getKey().intValue() );
1303 assertEquals( "v99", removed.getValue() );
1304 checkNull( btree, 99 );
1305
1306
1307 removed = btree.delete( 98 );
1308 assertEquals( 98, removed.getKey().intValue() );
1309 assertEquals( "v98", removed.getValue() );
1310 checkNull( btree, 98 );
1311
1312
1313 removed = btree.delete( 94 );
1314 assertEquals( 94, removed.getKey().intValue() );
1315 assertEquals( "v94", removed.getValue() );
1316 checkNull( btree, 94 );
1317
1318
1319 removed = btree.delete( 95 );
1320 assertEquals( 95, removed.getKey().intValue() );
1321 assertEquals( "v95", removed.getValue() );
1322 checkNull( btree, 95 );
1323
1324
1325 removed = btree.delete( 22 );
1326 assertEquals( 22, removed.getKey().intValue() );
1327 assertEquals( "v22", removed.getValue() );
1328 checkNull( btree, 22 );
1329
1330
1331 removed = btree.delete( 27 );
1332 assertEquals( 27, removed.getKey().intValue() );
1333 assertEquals( "v27", removed.getValue() );
1334 checkNull( btree, 27 );
1335
1336
1337 removed = btree.delete( 70 );
1338 assertEquals( 70, removed.getKey().intValue() );
1339 assertEquals( "v70", removed.getValue() );
1340 checkNull( btree, 70 );
1341
1342
1343 removed = btree.delete( 71 );
1344 assertEquals( 71, removed.getKey().intValue() );
1345 assertEquals( "v71", removed.getValue() );
1346 checkNull( btree, 71 );
1347
1348
1349 removed = btree.delete( 51 );
1350 assertEquals( 51, removed.getKey().intValue() );
1351 assertEquals( "v51", removed.getValue() );
1352 checkNull( btree, 51 );
1353
1354
1355 removed = btree.delete( 50 );
1356 assertEquals( 50, removed.getKey().intValue() );
1357 assertEquals( "v50", removed.getValue() );
1358 checkNull( btree, 50 );
1359
1360 btree.close();
1361 }
1362
1363
1364
1365
1366
1367
1368 @Test
1369 public void testDelete2LevelsTreeWithHalfFullLeaves() throws Exception
1370 {
1371
1372 BTree<Integer, String> btree = createTwoLevelBTreeHalfFullLeaves();
1373
1374
1375
1376 btree.delete( 10 );
1377 checkNull( btree, 10 );
1378
1379
1380 btree.delete( 9 );
1381 checkNull( btree, 9 );
1382
1383
1384 btree.delete( 13 );
1385 checkNull( btree, 13 );
1386
1387
1388 btree.delete( 14 );
1389 checkNull( btree, 14 );
1390
1391
1392 btree.delete( 18 );
1393 checkNull( btree, 18 );
1394
1395
1396 btree.delete( 5 );
1397 checkNull( btree, 5 );
1398
1399
1400 btree.delete( 6 );
1401 checkNull( btree, 6 );
1402
1403 btree.close();
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413 @Test
1414 public void testDeleteMultiLevelsLeadingToNodeBorrowRight1() throws Exception
1415 {
1416 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1417
1418
1419 delete( btree, EXPECTED1, 2, 3, 6, 7 );
1420
1421
1422 checkRemoval( btree, 10, EXPECTED1 );
1423
1424 btree.close();
1425 }
1426
1427
1428
1429
1430
1431
1432
1433
1434 @Test
1435 public void testDeleteMultiLevelsLeadingToNodeBorrowRight2() throws Exception
1436 {
1437 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1438
1439
1440 delete( btree, EXPECTED1, 2, 3, 6, 7 );
1441
1442
1443 checkRemoval( btree, 11, EXPECTED1 );
1444
1445 btree.close();
1446 }
1447
1448
1449
1450
1451
1452
1453
1454
1455 @Test
1456 public void testDeleteMultiLevelsLeadingToNodeBorrowRight3() throws Exception
1457 {
1458 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1459
1460
1461 delete( btree, EXPECTED1, 2, 3, 6, 7 );
1462
1463
1464 checkRemoval( btree, 19, EXPECTED1 );
1465
1466 btree.close();
1467 }
1468
1469
1470
1471
1472
1473
1474
1475
1476 @Test
1477 public void testDeleteMultiLevelsLeadingToNodeBorrowRight4() throws Exception
1478 {
1479 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1480
1481
1482 delete( btree, EXPECTED1, 2, 3, 6, 7 );
1483
1484
1485 checkRemoval( btree, 14, EXPECTED1 );
1486
1487 btree.close();
1488 }
1489
1490
1491
1492
1493
1494
1495
1496
1497 @Test
1498 public void testDeleteMultiLevelsLeadingToNodeBorrowRight5() throws Exception
1499 {
1500 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1501
1502
1503 delete( btree, EXPECTED1, 2, 3, 6, 7 );
1504
1505
1506 checkRemoval( btree, 15, EXPECTED1 );
1507
1508 btree.close();
1509 }
1510
1511
1512
1513
1514
1515
1516
1517
1518 @Test
1519 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft1() throws Exception
1520 {
1521 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1522
1523
1524 delete( btree, EXPECTED1, 94, 95, 98, 99 );
1525
1526
1527 checkRemoval( btree, 91, EXPECTED1 );
1528
1529 btree.close();
1530 }
1531
1532
1533
1534
1535
1536
1537
1538
1539 @Test
1540 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft2() throws Exception
1541 {
1542 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1543
1544
1545 delete( btree, EXPECTED1, 94, 95, 98, 99 );
1546
1547
1548 checkRemoval( btree, 90, EXPECTED1 );
1549
1550 btree.close();
1551 }
1552
1553
1554
1555
1556
1557
1558
1559
1560 @Test
1561 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft3() throws Exception
1562 {
1563 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1564
1565
1566 delete( btree, EXPECTED1, 94, 95, 98, 99 );
1567
1568
1569 checkRemoval( btree, 82, EXPECTED1 );
1570
1571 btree.close();
1572 }
1573
1574
1575
1576
1577
1578
1579
1580
1581 @Test
1582 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft4() throws Exception
1583 {
1584 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1585
1586
1587 delete( btree, EXPECTED1, 94, 95, 98, 99 );
1588
1589
1590 checkRemoval( btree, 83, EXPECTED1 );
1591
1592 btree.close();
1593 }
1594
1595
1596
1597
1598
1599
1600
1601
1602 @Test
1603 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft6() throws Exception
1604 {
1605 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1606
1607
1608 delete( btree, EXPECTED1, 42, 43, 46, 47 );
1609
1610
1611 checkRemoval( btree, 50, EXPECTED1 );
1612
1613 btree.close();
1614 }
1615
1616
1617
1618
1619
1620
1621
1622
1623 @Test
1624 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft7() throws Exception
1625 {
1626 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1627
1628
1629 delete( btree, EXPECTED1, 42, 43, 46, 47 );
1630
1631
1632 checkRemoval( btree, 51, EXPECTED1 );
1633
1634 btree.close();
1635 }
1636
1637
1638
1639
1640
1641
1642
1643
1644 @Test
1645 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft8() throws Exception
1646 {
1647 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1648
1649
1650 delete( btree, EXPECTED1, 42, 43, 46, 47 );
1651
1652
1653 checkRemoval( btree, 59, EXPECTED1 );
1654
1655 btree.close();
1656 }
1657
1658
1659
1660
1661
1662
1663
1664
1665 @Test
1666 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft9() throws Exception
1667 {
1668 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1669
1670
1671 delete( btree, EXPECTED1, 42, 43, 46, 47 );
1672
1673
1674 checkRemoval( btree, 58, EXPECTED1 );
1675
1676 btree.close();
1677 }
1678
1679
1680
1681
1682
1683
1684
1685
1686 @Test
1687 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft10() throws Exception
1688 {
1689 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1690
1691
1692 delete( btree, EXPECTED1, 42, 43, 46, 47 );
1693
1694
1695 checkRemoval( btree, 54, EXPECTED1 );
1696
1697 btree.close();
1698 }
1699
1700
1701
1702
1703
1704
1705
1706
1707 @Test
1708 public void testDeleteMultiLevelsLeadingToNodeBorrowLeft11() throws Exception
1709 {
1710 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1711
1712
1713 delete( btree, EXPECTED1, 42, 43, 46, 47 );
1714
1715
1716 checkRemoval( btree, 55, EXPECTED1 );
1717
1718 btree.close();
1719 }
1720
1721
1722
1723
1724
1725 @Test
1726 public void testAdditionNullValues() throws IOException, KeyNotFoundException
1727 {
1728 BTree<Integer, String> btree = createMultiLevelBTreeLeavesHalfFull();
1729
1730
1731 btree.insert( 100, null );
1732
1733 assertTrue( btree.hasKey( 100 ) );
1734
1735 try
1736 {
1737 assertNull( btree.get( 100 ) );
1738 }
1739 catch ( KeyNotFoundException knfe )
1740 {
1741 fail();
1742 }
1743
1744 Tuple<Integer, String> deleted = btree.delete( 100 );
1745
1746 assertNotNull( deleted );
1747 assertNull( deleted.getValue() );
1748
1749 btree.close();
1750 }
1751
1752
1753
1754
1755
1756
1757 @Test
1758 public void testBrowse500K() throws Exception
1759 {
1760 Random random = new Random( System.nanoTime() );
1761
1762 int nbError = 0;
1763
1764 int n = 0;
1765 int nbElems = 500000;
1766 long delta = System.currentTimeMillis();
1767
1768
1769 BTree<Long, String> btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE,
1770 StringSerializer.INSTANCE );
1771 btree.setPageSize( 32 );
1772
1773 for ( int i = 0; i < nbElems; i++ )
1774 {
1775 Long key = ( long ) random.nextLong();
1776 String value = Long.toString( key );
1777
1778 try
1779 {
1780 btree.insert( key, value );
1781 }
1782 catch ( Exception e )
1783 {
1784 e.printStackTrace();
1785 System.out.println( btree );
1786 System.out.println( "Error while adding " + value );
1787 nbError++;
1788 btree.close();
1789
1790 return;
1791 }
1792
1793 if ( i % 100000 == 0 )
1794 {
1795 if ( n > 0 )
1796 {
1797 long t0 = System.currentTimeMillis();
1798 System.out.println( "Delta" + n + ": " + ( t0 - delta ) );
1799 delta = t0;
1800 }
1801
1802 n++;
1803 }
1804 }
1805
1806
1807 long l1 = System.currentTimeMillis();
1808
1809 TupleCursor<Long, String> cursor = btree.browse();
1810
1811 int nb = 0;
1812 long elem = Long.MIN_VALUE;
1813
1814 while ( cursor.hasNext() )
1815 {
1816 Tuple<Long, String> res = cursor.next();
1817
1818 if ( res.getKey() > elem )
1819 {
1820 elem = res.getKey();
1821 nb++;
1822 }
1823 }
1824
1825 System.out.println( "Nb elements read : " + nb );
1826
1827 cursor.close();
1828 btree.close();
1829
1830 long l2 = System.currentTimeMillis();
1831
1832 System.out.println( "Delta : " + ( l2 - l1 ) + ", nbError = " + nbError
1833 + ", Nb searches per second : " + ( ( nbElems * 1000 ) / ( l2 - l1 ) ) );
1834 }
1835
1836
1837 private void checkNull( BTree<Long, String> btree, long key ) throws IOException
1838 {
1839 try
1840 {
1841 btree.get( key );
1842 fail();
1843 }
1844 catch ( KeyNotFoundException knfe )
1845 {
1846
1847 }
1848 }
1849
1850
1851 private void checkNull( BTree<Integer, String> btree, int key ) throws IOException
1852 {
1853 try
1854 {
1855 btree.get( key );
1856 fail();
1857 }
1858 catch ( KeyNotFoundException knfe )
1859 {
1860
1861 }
1862 }
1863
1864
1865
1866
1867
1868 @Test
1869 public void testBrowseForwardBackwardExtremes() throws Exception
1870 {
1871
1872 BTree<Integer, String> btree = BTreeFactory.createInMemoryBTree( "test", IntSerializer.INSTANCE,
1873 StringSerializer.INSTANCE );
1874 btree.setPageSize( 4 );
1875
1876 for ( int i = 8; i < 13; i++ )
1877 {
1878 String strValue = "V" + i;
1879 btree.insert( i, strValue );
1880 }
1881
1882
1883 TupleCursor<Integer, String> cursor = btree.browseFrom( 8 );
1884
1885 assertTrue( cursor.hasNext() );
1886
1887
1888 assertEquals( 8, cursor.next().getKey().intValue() );
1889
1890
1891 assertEquals( 9, cursor.next().getKey().intValue() );
1892
1893
1894 assertEquals( 10, cursor.next().getKey().intValue() );
1895
1896
1897 assertEquals( 11, cursor.next().getKey().intValue() );
1898
1899
1900 assertEquals( 12, cursor.next().getKey().intValue() );
1901
1902 assertFalse( cursor.hasNext() );
1903 assertTrue( cursor.hasPrev() );
1904
1905
1906 assertEquals( 11, cursor.prev().getKey().intValue() );
1907
1908
1909 assertEquals( 10, cursor.prev().getKey().intValue() );
1910
1911
1912 assertEquals( 9, cursor.prev().getKey().intValue() );
1913
1914
1915 assertEquals( 8, cursor.prev().getKey().intValue() );
1916
1917 assertFalse( cursor.hasPrev() );
1918 assertTrue( cursor.hasNext() );
1919
1920 cursor.close();
1921 btree.close();
1922 }
1923
1924
1925 @Test
1926 public void testNextAfterPrev() throws Exception
1927 {
1928 IntSerializer serializer = IntSerializer.INSTANCE;
1929
1930 InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
1931 config.setName( "master" );
1932 config.setPageSize( 4 );
1933 config.setSerializers( serializer, serializer );
1934 BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
1935
1936 int i = 7;
1937 for ( int k = 0; k < i; k++ )
1938 {
1939 btree.insert( k, k );
1940 }
1941
1942
1943 TupleCursor<Integer, Integer> cursor = btree.browseFrom( 4 );
1944
1945 assertTrue( cursor.hasNext() );
1946 Tuple<Integer, Integer> tuple = cursor.next();
1947 assertEquals( Integer.valueOf( 4 ), tuple.getKey() );
1948 assertEquals( Integer.valueOf( 4 ), tuple.getValue() );
1949
1950 assertTrue( cursor.hasPrev() );
1951 tuple = cursor.prev();
1952 assertEquals( Integer.valueOf( 3 ), tuple.getKey() );
1953 assertEquals( Integer.valueOf( 3 ), tuple.getValue() );
1954
1955 assertTrue( cursor.hasNext() );
1956 tuple = cursor.next();
1957 assertEquals( Integer.valueOf( 4 ), tuple.getKey() );
1958 assertEquals( Integer.valueOf( 4 ), tuple.getValue() );
1959
1960 cursor.close();
1961 btree.close();
1962 }
1963
1964
1965 @Test
1966 public void testCheckRootPageContents() throws Exception
1967 {
1968 IntSerializer ser = IntSerializer.INSTANCE;
1969 BTree<Integer, Integer> btree = BTreeFactory.createInMemoryBTree( "master1", ser, ser, 4 );
1970
1971 for ( int i = 1; i < 8; i++ )
1972 {
1973 btree.insert( i, i );
1974 }
1975
1976 System.out.println( btree.getRootPage() );
1977 assertEquals( 2, btree.getRootPage().getNbElems() );
1978
1979 assertEquals( 7, btree.getRootPage().findRightMost().getKey().intValue() );
1980
1981 assertEquals( 1, btree.getRootPage().findLeftMost().getKey().intValue() );
1982
1983 btree.close();
1984 }
1985 }