in mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java [982:1080]
private InsertResult<K, V> addAndSplit( List<Page<K, V>> copiedPages, long revision, K pivot, Page<K, V> leftPage,
Page<K, V> rightPage, int pos ) throws IOException
{
int middle = btree.getPageSize() >> 1;
// Create two new pages
PersistedNode<K, V> newLeftPage = new PersistedNode<K, V>( btree, revision, middle );
PersistedNode<K, V> newRightPage = new PersistedNode<K, V>( btree, revision, middle );
// Determinate where to store the new value
// If it's before the middle, insert the value on the left,
// the key in the middle will become the new pivot
if ( pos < middle )
{
// Copy the keys and the children up to the insertion position
System.arraycopy( keys, 0, newLeftPage.keys, 0, pos );
System.arraycopy( children, 0, newLeftPage.children, 0, pos );
// Add the new element
newLeftPage.keys[pos] = new PersistedKeyHolder<K>( btree.getKeySerializer(), pivot );
newLeftPage.children[pos] = createHolder( leftPage );
newLeftPage.children[pos + 1] = createHolder( rightPage );
// And copy the remaining elements minus the new pivot
System.arraycopy( keys, pos, newLeftPage.keys, pos + 1, middle - pos - 1 );
System.arraycopy( children, pos + 1, newLeftPage.children, pos + 2, middle - pos - 1 );
// Copy the keys and the children in the right page
System.arraycopy( keys, middle, newRightPage.keys, 0, middle );
System.arraycopy( children, middle, newRightPage.children, 0, middle + 1 );
// Create the result
pivot = keys[middle - 1].getKey();
if ( pivot == null )
{
pivot = keys[middle - 1].getKey();
}
InsertResult<K, V> result = new SplitResult<K, V>( copiedPages, pivot, newLeftPage,
newRightPage );
result.addCopiedPage( this );
return result;
}
else if ( pos == middle )
{
// A special case : the pivot will be propagated up in the tree
// The left and right pages will be spread on the two new pages
// Copy the keys and the children up to the insertion position (here, middle)
System.arraycopy( keys, 0, newLeftPage.keys, 0, middle );
System.arraycopy( children, 0, newLeftPage.children, 0, middle );
newLeftPage.children[middle] = createHolder( leftPage );
// And process the right page now
System.arraycopy( keys, middle, newRightPage.keys, 0, middle );
System.arraycopy( children, middle + 1, newRightPage.children, 1, middle );
newRightPage.children[0] = createHolder( rightPage );
// Create the result
InsertResult<K, V> result = new SplitResult<K, V>( copiedPages, pivot, newLeftPage, newRightPage );
result.addCopiedPage( this );
return result;
}
else
{
// Copy the keys and the children up to the middle
System.arraycopy( keys, 0, newLeftPage.keys, 0, middle );
System.arraycopy( children, 0, newLeftPage.children, 0, middle + 1 );
// Copy the keys and the children in the right page up to the pos
System.arraycopy( keys, middle + 1, newRightPage.keys, 0, pos - middle - 1 );
System.arraycopy( children, middle + 1, newRightPage.children, 0, pos - middle - 1 );
// Add the new element
newRightPage.keys[pos - middle - 1] = new PersistedKeyHolder<K>( btree.getKeySerializer(), pivot );
newRightPage.children[pos - middle - 1] = createHolder( leftPage );
newRightPage.children[pos - middle] = createHolder( rightPage );
// And copy the remaining elements minus the new pivot
System.arraycopy( keys, pos, newRightPage.keys, pos - middle, nbElems - pos );
System.arraycopy( children, pos + 1, newRightPage.children, pos + 1 - middle, nbElems - pos );
// Create the result
pivot = keys[middle].getKey();
if ( pivot == null )
{
pivot = keys[middle].getKey();
}
InsertResult<K, V> result = new SplitResult<K, V>( copiedPages, pivot, newLeftPage,
newRightPage );
result.addCopiedPage( this );
return result;
}
}