in mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java [404:520]
private DeleteResult<K, V> mergeWithSibling( long revision, MergedWithSiblingResult<K, V> mergedResult,
InMemoryNode<K, V> sibling, boolean isLeft, int pos ) throws IOException
{
// Create the new node. It will contain N - 1 elements (the maximum number)
// as we merge two nodes that contain N/2 elements minus the one we remove
InMemoryNode<K, V> newNode = new InMemoryNode<K, V>( btree, revision, btree.getPageSize() );
Tuple<K, V> removedElement = mergedResult.getRemovedElement();
int half = btree.getPageSize() / 2;
int index = Math.abs( pos );
if ( isLeft )
{
// The sibling is on the left. Copy all of its elements in the new node first
System.arraycopy( sibling.getKeys(), 0, newNode.getKeys(), 0, half ); //1
System.arraycopy( sibling.children, 0, newNode.children, 0, half + 1 ); //2
// Then copy all the elements up to the deletion point
if ( index < 2 )
{
newNode.setKey( half, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) );
System.arraycopy( getKeys(), 1, newNode.getKeys(), half + 1, half - 1 );
Page<K, V> modifiedPage = mergedResult.getModifiedPage();
newNode.children[half + 1] = new PageHolder<K, V>( btree, modifiedPage );
System.arraycopy( children, 2, newNode.children, half + 2, half - 1 );
}
else
{
// Copy the left part of the node keys up to the deletion point
// Insert the new key
newNode.setKey( half, new KeyHolder<K>( children[0].getValue().getLeftMostKey() ) ); // 3
if ( index > 2 )
{
System.arraycopy( getKeys(), 0, newNode.getKeys(), half + 1, index - 2 ); //4
}
// Inject the new merged key
newNode.setKey( half + index - 1, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) ); //5
if ( index < half )
{
System.arraycopy( getKeys(), index, newNode.getKeys(), half + index, half - index ); //6
System.arraycopy( children, index + 1, newNode.children, half + index + 1, half - index ); //9
}
// Copy the children before the deletion point
System.arraycopy( children, 0, newNode.children, half + 1, index - 1 ); // 7
// Inject the new merged child
Page<K, V> modifiedPage = mergedResult.getModifiedPage();
newNode.children[half + index] = new PageHolder<K, V>( btree, modifiedPage ); //8
}
}
else
{
// The sibling is on the right.
if ( index < 2 )
{
// Copy the keys
System.arraycopy( getKeys(), 1, newNode.getKeys(), 0, half - 1 );
// Insert the first child
Page<K, V> modifiedPage = mergedResult.getModifiedPage();
newNode.children[0] = new PageHolder<K, V>( btree, modifiedPage );
// Copy the node children
System.arraycopy( children, 2, newNode.children, 1, half - 1 );
}
else
{
// Copy the keys and children before the deletion point
if ( index > 2 )
{
// Copy the first keys
System.arraycopy( getKeys(), 0, newNode.getKeys(), 0, index - 2 ); //1
}
// Copy the first children
System.arraycopy( children, 0, newNode.children, 0, index - 1 ); //6
// Inject the modified key
newNode.setKey( index - 2, new KeyHolder<K>( mergedResult.getModifiedPage().getLeftMostKey() ) ); //2
// Inject the modified children
Page<K, V> modifiedPage = mergedResult.getModifiedPage();
newNode.children[index - 1] = new PageHolder<K, V>( btree, modifiedPage ); // 7
// Add the remaining node's key if needed
if ( index < half )
{
System.arraycopy( getKeys(), index, newNode.getKeys(), index - 1, half - index ); //5
// Add the remining children if below half
System.arraycopy( children, index + 1, newNode.children, index, half - index ); // 8
}
}
// Inject the new key from sibling
newNode.setKey( half - 1, new KeyHolder<K>( sibling.findLeftMost().getKey() ) ); //3
// Copy the sibling keys
System.arraycopy( sibling.getKeys(), 0, newNode.getKeys(), half, half );
// Add the sibling children
System.arraycopy( sibling.children, 0, newNode.children, half, half + 1 ); // 9
}
// And create the result
DeleteResult<K, V> result = new MergedWithSiblingResult<K, V>( mergedResult.getCopiedPages(), newNode,
removedElement );
result.addCopiedPage( this );
result.addCopiedPage( sibling );
return result;
}