in mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java [850:975]
private static <K, V> BTree<K, V> bulkLoad( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator, int nbElems )
throws IOException
{
int pageSize = btree.getPageSize();
// Special case : we can store all the element sin a single page
if ( nbElems <= pageSize )
{
return bulkLoadSinglePage( btree, dataIterator, nbElems );
}
// Ok, we will need more than one page to store the elements, which
// means we also will need more than one level.
// First, compute the needed number of levels.
List<LevelInfo<K, V>> levels = computeLevels( btree, nbElems );
// Now, let's fill the levels
LevelInfo<K, V> leafLevel = levels.get( 0 );
while ( dataIterator.hasNext() )
{
// let's fill page up to the point all the complete pages have been filled
if ( leafLevel.getNbAddedElems() < leafLevel.getNbElemsLimit() )
{
// grab a tuple
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
leafLevel.incNbAddedElems();
// The page is completed, update the parent's node and create a new current page
if ( leafLevel.getCurrentPos() == pageSize )
{
injectInNode( btree, leafLevel.getCurrentPage(), levels, 1 );
// The page is full, we have to create a new one
leafLevel.setCurrentPage( BTreeFactory
.createLeaf( btree, 0L, computeNbElemsLeaf( btree, leafLevel ) ) );
leafLevel.setCurrentPos( 0 );
}
}
else
{
// We have to deal with uncompleted pages now (if we have any)
if ( leafLevel.getNbAddedElems() == nbElems )
{
// First use case : we have injected all the elements in the btree : get out
break;
}
if ( nbElems - leafLevel.getNbElemsLimit() > pageSize )
{
// Second use case : the number of elements after the limit does not
// fit in a page, that means we have to split it into
// two pages
// First page will contain nbElems - leafLevel.nbElemsLimit - PageSize/2 elements
int nbToAdd = nbElems - leafLevel.getNbElemsLimit() - pageSize / 2;
while ( nbToAdd > 0 )
{
// grab a tuple
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
leafLevel.incNbAddedElems();
nbToAdd--;
}
// Now inject the page into the node
Page<K, V> currentPage = leafLevel.getCurrentPage();
injectInNode( btree, currentPage, levels, 1 );
// Create a new page for the remaining elements
nbToAdd = pageSize / 2;
leafLevel.setCurrentPage( BTreeFactory.createLeaf( btree, 0L, nbToAdd ) );
leafLevel.setCurrentPos( 0 );
while ( nbToAdd > 0 )
{
// grab a tuple
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
leafLevel.incNbAddedElems();
nbToAdd--;
}
// And update the parent node
Page<K, V> levelCurrentPage = leafLevel.getCurrentPage();
injectInNode( btree, levelCurrentPage, levels, 1 );
// We are done
break;
}
else
{
// Third use case : we can push all the elements in the last page.
// Let's do it
int nbToAdd = nbElems - leafLevel.getNbElemsLimit();
while ( nbToAdd > 0 )
{
// grab a tuple
Tuple<K, Set<V>> tuple = dataIterator.next();
injectInLeaf( btree, tuple, leafLevel );
leafLevel.incNbAddedElems();
nbToAdd--;
}
// Now inject the page into the node
injectInNode( btree, leafLevel.getCurrentPage(), levels, 1 );
// and we are done
break;
}
}
}
// Update the btree with the nb of added elements, and write it$
BTreeHeader<K, V> btreeHeader = ( ( AbstractBTree<K, V> ) btree ).getBtreeHeader();
btreeHeader.setNbElems( nbElems );
return btree;
}