private static BTree bulkLoad()

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;
    }