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 java.io.IOException;
24 import java.lang.reflect.Array;
25 import java.util.List;
26
27
28
29
30
31
32
33
34
35
36
37 class InMemoryNode<K, V> extends AbstractPage<K, V>
38 {
39
40
41
42
43
44
45
46
47
48 @SuppressWarnings("unchecked")
49 InMemoryNode( BTree<K, V> btree, long revision, int nbElems )
50 {
51 super( btree, revision, nbElems );
52
53
54 children = ( PageHolder<K, V>[] ) Array.newInstance( PageHolder.class, nbElems + 1 );
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69 @SuppressWarnings("unchecked")
70 InMemoryNode( BTree<K, V> btree, long revision, K key, Page<K, V> leftPage, Page<K, V> rightPage )
71 {
72 super( btree, revision, 1 );
73
74
75 children = ( PageHolder[] ) Array.newInstance( PageHolder.class, btree.getPageSize() + 1 );
76
77 children[0] = new PageHolder<K, V>( btree, leftPage );
78 children[1] = new PageHolder<K, V>( btree, rightPage );
79
80
81
82
83 setKeys( ( KeyHolder<K>[] ) Array.newInstance( KeyHolder.class, btree.getPageSize() ) );
84
85 setKey( 0, new KeyHolder<K>( key ) );
86 }
87
88
89
90
91
92 public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
93 {
94
95 int pos = findPos( key );
96
97 if ( pos < 0 )
98 {
99
100
101 pos = -( pos++ );
102 }
103
104
105 Page<K, V> child = children[pos].getValue();
106
107
108 InsertResult<K, V> result = child.insert( key, value, revision );
109
110
111
112 if ( result instanceof ModifyResult )
113 {
114
115 return replaceChild( revision, ( ModifyResult<K, V> ) result, pos );
116 }
117 else
118 {
119
120
121 SplitResult<K, V> splitResult = ( SplitResult<K, V> ) result;
122 K pivot = splitResult.getPivot();
123 Page<K, V> leftPage = splitResult.getLeftPage();
124 Page<K, V> rightPage = splitResult.getRightPage();
125
126
127
128
129 if ( nbElems == btree.getPageSize() )
130 {
131
132 result = addAndSplit( splitResult.getCopiedPages(), revision, pivot, leftPage, rightPage, pos );
133 }
134 else
135 {
136
137 result = insertChild( splitResult.getCopiedPages(), revision, pivot, leftPage, rightPage, pos );
138 }
139
140 return result;
141 }
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155
156 private RemoveResult<K, V> handleRemoveResult( RemoveResult<K, V> removeResult, int index, int pos, boolean found )
157 throws IOException
158 {
159
160
161
162 InMemoryNode<K, V> newPage = copy( revision );
163
164 Page<K, V> modifiedPage = removeResult.getModifiedPage();
165
166 if ( found )
167 {
168 newPage.children[index + 1] = new PageHolder<K, V>( btree, modifiedPage );
169 }
170 else
171 {
172 newPage.children[index] = new PageHolder<K, V>( btree, modifiedPage );
173 }
174
175 if ( pos < 0 )
176 {
177 newPage.setKey( index, new KeyHolder<K>( removeResult.getModifiedPage().getLeftMostKey() ) );
178 }
179
180
181 removeResult.setModifiedPage( newPage );
182 removeResult.addCopiedPage( this );
183
184 return removeResult;
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198 private RemoveResult<K, V> handleRootRemove( MergedWithSiblingResult<K, V> mergedResult, int pos, boolean found )
199 throws IOException
200 {
201 RemoveResult<K, V> removeResult = null;
202
203
204
205 if ( nbElems == 1 )
206 {
207 removeResult = new RemoveResult<K, V>( mergedResult.getCopiedPages(), mergedResult.getModifiedPage(),
208 mergedResult.getRemovedElement() );
209
210 removeResult.addCopiedPage( this );
211 }
212 else
213 {
214
215 removeResult = removeKey( mergedResult, revision, pos );
216 }
217
218 return removeResult;
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232
233 private DeleteResult<K, V> borrowFromRight( long revision, MergedWithSiblingResult<K, V> mergedResult,
234 InMemoryNode<K, V> sibling, int pos ) throws IOException
235 {
236
237 InMemoryNode<K, V> newSibling = new InMemoryNode<K, V>( btree, revision, sibling.getNbElems() - 1 );
238
239 K siblingKey = sibling.children[0].getValue().getLeftMostKey();
240
241
242 System.arraycopy( sibling.getKeys(), 1, newSibling.getKeys(), 0, newSibling.getNbElems() );
243 System.arraycopy( sibling.children, 1, newSibling.children, 0, newSibling.getNbElems() + 1 );
244
245
246
247 InMemoryNode<K, V> newNode = new InMemoryNode<K, V>( btree, revision, nbElems );
248
249
250 int index = Math.abs( pos );
251
252
253 newNode.setKey( nbElems - 1, new KeyHolder<K>( siblingKey ) );
254 newNode.children[nbElems] = sibling.children[0];
255
256 if ( index < 2 )
257 {
258
259 System.arraycopy( getKeys(), 1, newNode.getKeys(), 0, nbElems - 1 );
260
261
262 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
263 newNode.children[0] = new PageHolder<K, V>( btree, modifiedPage );
264
265
266 System.arraycopy( children, 2, newNode.children, 1, nbElems - 1 );
267 }
268 else
269 {
270 if ( index > 2 )
271 {
272
273 System.arraycopy( getKeys(), 0, newNode.getKeys(), 0, index - 2 );
274 }
275
276
277 newNode.setKey( index - 2, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
278
279 if ( index < nbElems )
280 {
281
282 System.arraycopy( getKeys(), index, newNode.getKeys(), index - 1, nbElems - index );
283
284
285 System.arraycopy( children, index + 1, newNode.children, index, nbElems - index );
286 }
287
288
289 System.arraycopy( children, 0, newNode.children, 0, index - 1 );
290
291
292 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
293 newNode.children[index - 1] = new PageHolder<K, V>( btree, modifiedPage );
294 }
295
296
297 DeleteResult<K, V> result = new BorrowedFromRightResult<K, V>( mergedResult.getCopiedPages(), newNode,
298 newSibling, mergedResult.getRemovedElement() );
299
300 result.addCopiedPage( this );
301 result.addCopiedPage( sibling );
302
303 return result;
304 }
305
306
307
308
309
310
311
312
313
314
315
316
317
318 private DeleteResult<K, V> borrowFromLeft( long revision, MergedWithSiblingResult<K, V> mergedResult,
319 InMemoryNode<K, V> sibling, int pos ) throws IOException
320 {
321
322 Page<K, V> siblingChild = sibling.children[sibling.nbElems].getValue();
323
324
325 InMemoryNode<K, V> newSibling = new InMemoryNode<K, V>( btree, revision, sibling.getNbElems() - 1 );
326
327
328 System.arraycopy( sibling.getKeys(), 0, newSibling.getKeys(), 0, newSibling.getNbElems() );
329 System.arraycopy( sibling.children, 0, newSibling.children, 0, newSibling.getNbElems() + 1 );
330
331
332
333 InMemoryNode<K, V> newNode = new InMemoryNode<K, V>( btree, revision, nbElems );
334
335
336 newNode.children[0] = new PageHolder<K, V>( btree, siblingChild );
337
338 int index = Math.abs( pos );
339
340 if ( index < 2 )
341 {
342 newNode.setKey( 0, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
343 System.arraycopy( getKeys(), 1, newNode.getKeys(), 1, nbElems - 1 );
344
345 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
346 newNode.children[1] = new PageHolder<K, V>( btree, modifiedPage );
347 System.arraycopy( children, 2, newNode.children, 2, nbElems - 1 );
348 }
349 else
350 {
351
352 newNode.setKey( 0, new KeyHolder<K>( children[0].getValue().getLeftMostKey() ) );
353
354 if ( index > 2 )
355 {
356
357 System.arraycopy( getKeys(), 0, newNode.getKeys(), 1, index - 2 );
358 }
359
360
361 newNode.setKey( index - 1, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
362
363 if ( index < nbElems )
364 {
365
366 System.arraycopy( getKeys(), index, newNode.getKeys(), index, nbElems - index );
367
368
369 System.arraycopy( children, index + 1, newNode.children, index + 1, nbElems - index );
370 }
371
372
373 System.arraycopy( children, 0, newNode.children, 1, index - 1 );
374
375
376 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
377 newNode.children[index] = new PageHolder<K, V>( btree, modifiedPage );
378 }
379
380
381 DeleteResult<K, V> result = new BorrowedFromLeftResult<K, V>( mergedResult.getCopiedPages(), newNode,
382 newSibling,
383 mergedResult.getRemovedElement() );
384
385 result.addCopiedPage( this );
386 result.addCopiedPage( sibling );
387
388 return result;
389 }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 private DeleteResult<K, V> mergeWithSibling( long revision, MergedWithSiblingResult<K, V> mergedResult,
405 InMemoryNode<K, V> sibling, boolean isLeft, int pos ) throws IOException
406 {
407
408
409 InMemoryNode<K, V> newNode = new InMemoryNode<K, V>( btree, revision, btree.getPageSize() );
410 Tuple<K, V> removedElement = mergedResult.getRemovedElement();
411 int half = btree.getPageSize() / 2;
412 int index = Math.abs( pos );
413
414 if ( isLeft )
415 {
416
417 System.arraycopy( sibling.getKeys(), 0, newNode.getKeys(), 0, half );
418 System.arraycopy( sibling.children, 0, newNode.children, 0, half + 1 );
419
420
421 if ( index < 2 )
422 {
423 newNode.setKey( half, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
424 System.arraycopy( getKeys(), 1, newNode.getKeys(), half + 1, half - 1 );
425
426 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
427 newNode.children[half + 1] = new PageHolder<K, V>( btree, modifiedPage );
428 System.arraycopy( children, 2, newNode.children, half + 2, half - 1 );
429 }
430 else
431 {
432
433
434 newNode.setKey( half, new KeyHolder<K>( children[0].getValue().getLeftMostKey() ) );
435
436 if ( index > 2 )
437 {
438 System.arraycopy( getKeys(), 0, newNode.getKeys(), half + 1, index - 2 );
439 }
440
441
442 newNode.setKey( half + index - 1, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
443
444 if ( index < half )
445 {
446 System.arraycopy( getKeys(), index, newNode.getKeys(), half + index, half - index );
447 System.arraycopy( children, index + 1, newNode.children, half + index + 1, half - index );
448 }
449
450
451 System.arraycopy( children, 0, newNode.children, half + 1, index - 1 );
452
453
454 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
455 newNode.children[half + index] = new PageHolder<K, V>( btree, modifiedPage );
456 }
457 }
458 else
459 {
460
461 if ( index < 2 )
462 {
463
464 System.arraycopy( getKeys(), 1, newNode.getKeys(), 0, half - 1 );
465
466
467 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
468 newNode.children[0] = new PageHolder<K, V>( btree, modifiedPage );
469
470
471 System.arraycopy( children, 2, newNode.children, 1, half - 1 );
472 }
473 else
474 {
475
476 if ( index > 2 )
477 {
478
479 System.arraycopy( getKeys(), 0, newNode.getKeys(), 0, index - 2 );
480 }
481
482
483 System.arraycopy( children, 0, newNode.children, 0, index - 1 );
484
485
486 newNode.setKey( index - 2, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
487
488
489 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
490 newNode.children[index - 1] = new PageHolder<K, V>( btree, modifiedPage );
491
492
493 if ( index < half )
494 {
495 System.arraycopy( getKeys(), index, newNode.getKeys(), index - 1, half - index );
496
497
498 System.arraycopy( children, index + 1, newNode.children, index, half - index );
499 }
500 }
501
502
503 newNode.setKey( half - 1, new KeyHolder<K>( sibling.findLeftMost().getKey() ) );
504
505
506 System.arraycopy( sibling.getKeys(), 0, newNode.getKeys(), half, half );
507
508
509 System.arraycopy( sibling.children, 0, newNode.children, half, half + 1 );
510 }
511
512
513 DeleteResult<K, V> result = new MergedWithSiblingResult<K, V>( mergedResult.getCopiedPages(), newNode,
514 removedElement );
515
516 result.addCopiedPage( this );
517 result.addCopiedPage( sibling );
518
519 return result;
520 }
521
522
523
524
525
526 DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
527 throws IOException
528 {
529
530
531 int pos = findPos( key );
532 boolean found = pos < 0;
533 int index = pos;
534 Page<K, V> child = null;
535 DeleteResult<K, V> deleteResult = null;
536
537 if ( found )
538 {
539 index = -( pos + 1 );
540 child = children[-pos].getValue();
541 deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, -pos );
542 }
543 else
544 {
545 child = children[pos].getValue();
546 deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, pos );
547 }
548
549
550 if ( deleteResult instanceof NotPresentResult )
551 {
552
553 return deleteResult;
554 }
555
556
557 if ( deleteResult instanceof RemoveResult )
558 {
559 RemoveResult<K, V> removeResult = handleRemoveResult( ( RemoveResult<K, V> ) deleteResult, index, pos,
560 found );
561
562 return removeResult;
563 }
564
565
566
567 if ( deleteResult instanceof BorrowedFromSiblingResult )
568 {
569 RemoveResult<K, V> removeResult = handleBorrowedResult( ( BorrowedFromSiblingResult<K, V> ) deleteResult,
570 pos );
571
572 return removeResult;
573 }
574
575
576
577 if ( deleteResult instanceof MergedWithSiblingResult )
578 {
579 MergedWithSiblingResult<K, V> mergedResult = ( MergedWithSiblingResult<K, V> ) deleteResult;
580
581
582 if ( parent == null )
583 {
584 RemoveResult<K, V> result = handleRootRemove( mergedResult, pos, found );
585
586 return result;
587 }
588
589
590 int halfSize = btree.getPageSize() / 2;
591
592 if ( nbElems > halfSize )
593 {
594
595
596
597
598 RemoveResult<K, V> result = removeKey( mergedResult, revision, pos );
599
600 return result;
601 }
602 else
603 {
604
605
606
607 int siblingPos = selectSibling( parent, parentPos );
608
609 InMemoryNode<K, V> sibling = ( InMemoryNode<K, V> ) ( ( ( InMemoryNode<K, V> ) parent ).children[siblingPos]
610 .getValue() );
611
612 if ( sibling.getNbElems() > halfSize )
613 {
614
615
616 if ( siblingPos < parentPos )
617 {
618 DeleteResult<K, V> result = borrowFromLeft( revision, mergedResult, sibling, pos );
619
620 return result;
621 }
622 else
623 {
624
625 DeleteResult<K, V> result = borrowFromRight( revision, mergedResult, sibling, pos );
626
627 return result;
628 }
629 }
630 else
631 {
632
633 DeleteResult<K, V> result = mergeWithSibling( revision, mergedResult, sibling,
634 ( siblingPos < parentPos ), pos );
635
636 return result;
637 }
638 }
639 }
640
641
642 return null;
643 }
644
645
646
647
648
649
650
651
652
653
654 private RemoveResult<K, V> handleBorrowedResult( BorrowedFromSiblingResult<K, V> borrowedResult, int pos )
655 throws IOException
656 {
657 Page<K, V> modifiedPage = borrowedResult.getModifiedPage();
658 Page<K, V> modifiedSibling = borrowedResult.getModifiedSibling();
659
660 InMemoryNode<K, V> newPage = copy( revision );
661
662 if ( pos < 0 )
663 {
664 pos = -( pos + 1 );
665
666 if ( borrowedResult.isFromRight() )
667 {
668
669 newPage.setKey( pos, new KeyHolder<K>( modifiedPage.findLeftMost().getKey() ) );
670 newPage.setKey( pos + 1, new KeyHolder<K>( modifiedSibling.findLeftMost().getKey() ) );
671
672
673 newPage.children[pos + 1] = new PageHolder<K, V>( btree, modifiedPage );
674 newPage.children[pos + 2] = new PageHolder<K, V>( btree, modifiedSibling );
675 }
676 else
677 {
678
679 newPage.setKey( pos, new KeyHolder<K>( modifiedPage.findLeftMost().getKey() ) );
680
681
682 newPage.children[pos] = new PageHolder<K, V>( btree, modifiedSibling );
683 newPage.children[pos + 1] = new PageHolder<K, V>( btree, modifiedPage );
684 }
685 }
686 else
687 {
688 if ( borrowedResult.isFromRight() )
689 {
690
691 newPage.setKey( pos, new KeyHolder<K>( modifiedSibling.findLeftMost().getKey() ) );
692
693
694 newPage.children[pos] = new PageHolder<K, V>( btree, modifiedPage );
695 newPage.children[pos + 1] = new PageHolder<K, V>( btree, modifiedSibling );
696 }
697 else
698 {
699
700 newPage.setKey( pos - 1, new KeyHolder<K>( modifiedPage.findLeftMost().getKey() ) );
701
702
703 newPage.children[pos - 1] = new PageHolder<K, V>( btree, modifiedSibling );
704 newPage.children[pos] = new PageHolder<K, V>( btree, modifiedPage );
705 }
706 }
707
708
709 RemoveResult<K, V> removeResult = new RemoveResult<K, V>( borrowedResult.getCopiedPages(), newPage,
710 borrowedResult.getRemovedElement() );
711
712 removeResult.addCopiedPage( this );
713
714 return removeResult;
715 }
716
717
718
719
720
721
722
723
724
725
726
727 private RemoveResult<K, V> removeKey( MergedWithSiblingResult<K, V> mergedResult, long revision, int pos )
728 throws IOException
729 {
730
731 InMemoryNode<K, V> newNode = new InMemoryNode<K, V>( btree, revision, nbElems - 1 );
732
733 int index = Math.abs( pos ) - 2;
734
735
736 if ( index < 0 )
737 {
738
739 System.arraycopy( getKeys(), 1, newNode.getKeys(), 0, newNode.nbElems );
740 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
741 newNode.children[0] = new PageHolder<K, V>( btree, modifiedPage );
742 System.arraycopy( children, 2, newNode.children, 1, nbElems - 1 );
743 }
744 else
745 {
746
747 if ( index > 0 )
748 {
749 System.arraycopy( getKeys(), 0, newNode.getKeys(), 0, index );
750 }
751
752 newNode.setKey( index, new KeyHolder<K>( mergedResult.getModifiedPage().findLeftMost().getKey() ) );
753
754 if ( index < nbElems - 2 )
755 {
756 System.arraycopy( getKeys(), index + 2, newNode.getKeys(), index + 1, nbElems - index - 2 );
757 }
758
759
760 System.arraycopy( children, 0, newNode.children, 0, index + 1 );
761
762 Page<K, V> modifiedPage = mergedResult.getModifiedPage();
763 newNode.children[index + 1] = new PageHolder<K, V>( btree, modifiedPage );
764
765 if ( index < nbElems - 2 )
766 {
767 System.arraycopy( children, index + 3, newNode.children, index + 2, nbElems - index - 2 );
768 }
769 }
770
771
772 RemoveResult<K, V> result = new RemoveResult<K, V>( mergedResult.getCopiedPages(), newNode,
773 mergedResult.getRemovedElement() );
774
775 result.addCopiedPage( this );
776
777 return result;
778 }
779
780
781
782
783
784
785
786
787 void setValue( int pos, Page<K, V> value )
788 {
789 children[pos] = new PageHolder<K, V>( btree, value );
790 }
791
792
793
794
795
796
797
798
799
800
801
802
803
804 private InsertResult<K, V> replaceChild( long revision, ModifyResult<K, V> result, int pos ) throws IOException
805 {
806
807 Page<K, V> newPage = copy( revision );
808
809
810
811 Page<K, V> modifiedPage = result.getModifiedPage();
812
813 ( ( InMemoryNode<K, V> ) newPage ).children[pos] = new PageHolder<K, V>( btree, modifiedPage );
814
815
816
817 result.setModifiedPage( newPage );
818
819 result.addCopiedPage( this );
820
821 return result;
822 }
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838 private InsertResult<K, V> insertChild( List<Page<K, V>> copiedPages, long revision, K key, Page<K, V> leftPage,
839 Page<K, V> rightPage, int pos )
840 throws IOException
841 {
842
843 InMemoryNode<K, V> newNode = new InMemoryNode<K, V>( btree, revision, nbElems + 1 );
844
845
846 if ( nbElems > 0 )
847 {
848 System.arraycopy( getKeys(), 0, newNode.getKeys(), 0, pos );
849 System.arraycopy( children, 0, newNode.children, 0, pos );
850 }
851
852
853 newNode.setKey( pos, new KeyHolder<K>( key ) );
854
855
856
857 newNode.children[pos] = new PageHolder<K, V>( btree, leftPage );
858 newNode.children[pos + 1] = new PageHolder<K, V>( btree, rightPage );
859
860
861 if ( nbElems > 0 )
862 {
863 System.arraycopy( getKeys(), pos, newNode.getKeys(), pos + 1, getKeys().length - pos );
864 System.arraycopy( children, pos + 1, newNode.children, pos + 2, children.length - pos - 1 );
865 }
866
867
868 InsertResult<K, V> result = new ModifyResult<K, V>( copiedPages, newNode, null );
869 result.addCopiedPage( this );
870
871 return result;
872 }
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893 private InsertResult<K, V> addAndSplit( List<Page<K, V>> copiedPages, long revision, K pivot, Page<K, V> leftPage,
894 Page<K, V> rightPage, int pos ) throws IOException
895 {
896 int middle = btree.getPageSize() >> 1;
897
898
899 InMemoryNode<K, V> newLeftPage = new InMemoryNode<K, V>( btree, revision, middle );
900 InMemoryNode<K, V> newRightPage = new InMemoryNode<K, V>( btree, revision, middle );
901
902
903
904
905 if ( pos < middle )
906 {
907
908 System.arraycopy( getKeys(), 0, newLeftPage.getKeys(), 0, pos );
909 System.arraycopy( children, 0, newLeftPage.children, 0, pos );
910
911
912 newLeftPage.setKey( pos, new KeyHolder<K>( pivot ) );
913 newLeftPage.children[pos] = new PageHolder<K, V>( btree, leftPage );
914 newLeftPage.children[pos + 1] = new PageHolder<K, V>( btree, rightPage );
915
916
917 System.arraycopy( getKeys(), pos, newLeftPage.getKeys(), pos + 1, middle - pos - 1 );
918 System.arraycopy( children, pos + 1, newLeftPage.children, pos + 2, middle - pos - 1 );
919
920
921 System.arraycopy( getKeys(), middle, newRightPage.getKeys(), 0, middle );
922 System.arraycopy( children, middle, newRightPage.children, 0, middle + 1 );
923
924
925 InsertResult<K, V> result = new SplitResult<K, V>( copiedPages, getKey( middle - 1 ), newLeftPage,
926 newRightPage );
927 result.addCopiedPage( this );
928
929 return result;
930 }
931 else if ( pos == middle )
932 {
933
934
935
936 System.arraycopy( getKeys(), 0, newLeftPage.getKeys(), 0, middle );
937 System.arraycopy( children, 0, newLeftPage.children, 0, middle );
938 newLeftPage.children[middle] = new PageHolder<K, V>( btree, leftPage );
939
940
941 System.arraycopy( getKeys(), middle, newRightPage.getKeys(), 0, middle );
942 System.arraycopy( children, middle + 1, newRightPage.children, 1, middle );
943 newRightPage.children[0] = new PageHolder<K, V>( btree, rightPage );
944
945
946 InsertResult<K, V> result = new SplitResult<K, V>( copiedPages, pivot, newLeftPage, newRightPage );
947 result.addCopiedPage( this );
948
949 return result;
950 }
951 else
952 {
953
954 System.arraycopy( getKeys(), 0, newLeftPage.getKeys(), 0, middle );
955 System.arraycopy( children, 0, newLeftPage.children, 0, middle + 1 );
956
957
958 System.arraycopy( getKeys(), middle + 1, newRightPage.getKeys(), 0, pos - middle - 1 );
959 System.arraycopy( children, middle + 1, newRightPage.children, 0, pos - middle - 1 );
960
961
962 newRightPage.setKey( pos - middle - 1, new KeyHolder<K>( pivot ) );
963 newRightPage.children[pos - middle - 1] = new PageHolder<K, V>( btree, leftPage );
964 newRightPage.children[pos - middle] = new PageHolder<K, V>( btree, rightPage );
965
966
967 System.arraycopy( getKeys(), pos, newRightPage.getKeys(), pos - middle, nbElems - pos );
968 System.arraycopy( children, pos + 1, newRightPage.children, pos + 1 - middle, nbElems - pos );
969
970
971 InsertResult<K, V> result = new SplitResult<K, V>( copiedPages, getKey( middle ), newLeftPage, newRightPage );
972 result.addCopiedPage( this );
973
974 return result;
975 }
976 }
977
978
979
980
981
982
983
984
985 protected InMemoryNode<K, V> copy( long revision )
986 {
987 InMemoryNode<K, V> newPage = new InMemoryNode<K, V>( btree, revision, nbElems );
988
989
990 System.arraycopy( getKeys(), 0, newPage.getKeys(), 0, nbElems );
991
992
993 System.arraycopy( children, 0, newPage.children, 0, nbElems + 1 );
994
995 return newPage;
996 }
997
998
999
1000
1001
1002 public K getLeftMostKey()
1003 {
1004 return children[0].getValue().getLeftMostKey();
1005 }
1006
1007
1008
1009
1010
1011 public K getRightMostKey()
1012 {
1013 int index = ( nbElems + 1 ) - 1;
1014
1015 if ( children[index] != null )
1016 {
1017 return children[index].getValue().getRightMostKey();
1018 }
1019
1020 return children[nbElems - 1].getValue().getRightMostKey();
1021 }
1022
1023
1024
1025
1026
1027 public boolean isLeaf()
1028 {
1029 return false;
1030 }
1031
1032
1033
1034
1035
1036 public boolean isNode()
1037 {
1038 return true;
1039 }
1040
1041
1042
1043
1044
1045 public String toString()
1046 {
1047 StringBuilder sb = new StringBuilder();
1048
1049 sb.append( "Node[" );
1050 sb.append( super.toString() );
1051 sb.append( "] -> {" );
1052
1053 if ( nbElems > 0 )
1054 {
1055
1056 if ( children[0] == null )
1057 {
1058 sb.append( "null" );
1059 }
1060 else
1061 {
1062 sb.append( 'r' ).append( children[0].getValue().getRevision() );
1063 }
1064
1065 for ( int i = 0; i < nbElems; i++ )
1066 {
1067 sb.append( "|<" ).append( getKey( i ) ).append( ">|" );
1068
1069 if ( children[i + 1] == null )
1070 {
1071 sb.append( "null" );
1072 }
1073 else
1074 {
1075 sb.append( 'r' ).append( children[i + 1].getValue().getRevision() );
1076 }
1077 }
1078 }
1079
1080 sb.append( "}" );
1081
1082 return sb.toString();
1083 }
1084 }