in mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java [2488:2581]
private <K, V> long updateBtreeHeader( BTree<K, V> btree, long btreeHeaderOffset, boolean onPlace )
throws EndOfFileExceededException, IOException
{
// Read the pageIOs associated with this B-tree
PageIO[] pageIos;
long newBtreeHeaderOffset = NO_PAGE;
long offset = ( ( PersistedBTree<K, V> ) btree ).getBtreeOffset();
if ( onPlace )
{
// We just have to update the existing BTreeHeader
long headerSize = LONG_SIZE + LONG_SIZE + LONG_SIZE;
pageIos = readPageIOs( offset, headerSize );
// Now, update the revision
long position = 0;
position = store( position, btree.getRevision(), pageIos );
position = store( position, btree.getNbElems(), pageIos );
position = store( position, btreeHeaderOffset, pageIos );
// Write the pages on disk
if ( LOG.isDebugEnabled() )
{
LOG.debug( "-----> Flushing the '{}' B-treeHeader", btree.getName() );
LOG.debug( " revision : " + btree.getRevision() + ", NbElems : " + btree.getNbElems()
+ ", btreeHeader offset : 0x"
+ Long.toHexString( btreeHeaderOffset ) );
}
// Get new place on disk to store the modified BTreeHeader if it's not onPlace
// Rewrite the pages at the same place
LOG.debug( "Rewriting the B-treeHeader on place for B-tree " + btree.getName() );
flushPages( pageIos );
}
else
{
// We have to read and copy the existing BTreeHeader and to create a new one
pageIos = readPageIOs( offset, Long.MAX_VALUE );
// Now, copy every read page
PageIO[] newPageIOs = new PageIO[pageIos.length];
int pos = 0;
for ( PageIO pageIo : pageIos )
{
// Fetch a free page
newPageIOs[pos] = fetchNewPage();
// keep a track of the allocated and copied pages so that we can
// free them when we do a commit or rollback, if the btree is an management one
if ( ( btree.getType() == BTreeTypeEnum.BTREE_OF_BTREES )
|| ( btree.getType() == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
{
freedPages.add( pageIo );
allocatedPages.add( newPageIOs[pos] );
}
pageIo.copy( newPageIOs[pos] );
if ( pos > 0 )
{
newPageIOs[pos - 1].setNextPage( newPageIOs[pos].getOffset() );
}
pos++;
}
// store the new btree header offset
// and update the revision
long position = 0;
position = store( position, btree.getRevision(), newPageIOs );
position = store( position, btree.getNbElems(), newPageIOs );
position = store( position, btreeHeaderOffset, newPageIOs );
// Get new place on disk to store the modified BTreeHeader if it's not onPlace
// Flush the new B-treeHeader on disk
LOG.debug( "Rewriting the B-treeHeader on place for B-tree " + btree.getName() );
flushPages( newPageIOs );
newBtreeHeaderOffset = newPageIOs[0].getOffset();
}
nbUpdateBtreeHeader.incrementAndGet();
if ( LOG_CHECK.isDebugEnabled() )
{
MavibotInspector.check( this );
}
return newBtreeHeaderOffset;
}