private InsertResult processInsert()

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