in mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java [506:636]
private InsertResult<K, V> processInsert( K key, V value, long revision ) throws IOException
{
// Get the current B-tree header, and insert the value into it
BTreeHeader<K, V> btreeHeader = getBTreeHeader( getName() );
InsertResult<K, V> result = btreeHeader.getRootPage().insert( key, value, revision );
if ( result instanceof ExistsResult )
{
return result;
}
// Create a new BTreeHeader
BTreeHeader<K, V> newBtreeHeader = btreeHeader.copy();
// Inject the old B-tree header into the pages to be freed
// if we are inserting an element in a management BTree
if ( ( btreeType == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btreeType == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
{
PageIO[] pageIos = recordManager.readPageIOs( btreeHeader.getBTreeHeaderOffset(), -1L );
for ( PageIO pageIo : pageIos )
{
recordManager.freedPages.add( pageIo );
}
}
Page<K, V> newRootPage;
if ( result instanceof ModifyResult )
{
ModifyResult<K, V> modifyResult = ( ( ModifyResult<K, V> ) result );
newRootPage = modifyResult.getModifiedPage();
// Increment the counter if we have inserted a new value
if ( modifyResult.getModifiedValue() == null )
{
newBtreeHeader.incrementNbElems();
}
}
else
{
// We have split the old root, create a new one containing
// only the pivotal we got back
SplitResult<K, V> splitResult = ( ( SplitResult<K, V> ) result );
K pivot = splitResult.getPivot();
Page<K, V> leftPage = splitResult.getLeftPage();
Page<K, V> rightPage = splitResult.getRightPage();
// If the B-tree is managed, we have to write the two pages that were created
// and to keep a track of the two offsets for the upper node
PageHolder<K, V> holderLeft = writePage( leftPage, revision );
PageHolder<K, V> holderRight = writePage( rightPage, revision );
// Create the new rootPage
newRootPage = new PersistedNode<K, V>( this, revision, pivot, holderLeft, holderRight );
// Always increment the counter : we have added a new value
newBtreeHeader.incrementNbElems();
}
// Write the new root page on disk
LOG_PAGES.debug( "Writing the new rootPage revision {} for {}", revision, name );
writePage( newRootPage, revision );
// Update the new B-tree header
newBtreeHeader.setRootPage( newRootPage );
newBtreeHeader.setRevision( revision );
// Write down the data on disk
long newBtreeHeaderOffset = recordManager.writeBtreeHeader( this, newBtreeHeader );
// Update the B-tree of B-trees with this new offset, if we are not already doing so
switch ( btreeType )
{
case PERSISTED:
// We have a new B-tree header to inject into the B-tree of btrees
recordManager.addInBtreeOfBtrees( getName(), revision, newBtreeHeaderOffset );
recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
// Store the new revision
storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
break;
case PERSISTED_SUB:
// Sub-B-trees are only updating the CopiedPage B-tree
recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
// Store the new revision
storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
currentRevision.set( revision );
break;
case BTREE_OF_BTREES:
// The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
recordManager.updateRecordManagerHeader( newBtreeHeaderOffset, -1L );
// We can free the copied pages
recordManager.freePages( this, revision, result.getCopiedPages() );
// Store the new revision
storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
break;
case COPIED_PAGES_BTREE:
// The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
recordManager.updateRecordManagerHeader( -1L, newBtreeHeaderOffset );
// We can free the copied pages
recordManager.freePages( this, revision, result.getCopiedPages() );
// Store the new revision
storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
break;
default:
// Nothing to do for sub-btrees
break;
}
// Get the new root page and make it the current root page
return result;
}