directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1566659 [3/6] - in /directory/mavibot/branches/with-txns/mavibot: img/ src/main/java/org/apache/directory/mavibot/btree/ src/main/java/org/apache/directory/mavibot/btree/comparator/ src/main/java/org/apache/directory/mavibot/btree/exceptio...
Date Mon, 10 Feb 2014 15:35:20 GMT
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
Mon Feb 10 15:35:18 2014
@@ -24,8 +24,8 @@ import java.io.Closeable;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
-import java.util.Map;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
 
 import net.sf.ehcache.Cache;
@@ -45,15 +45,15 @@ import org.slf4j.LoggerFactory;
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class PersistedBTree<K, V> extends AbstractBTree<K, V> implements Closeable
+public class PersistedBTree<K, V> extends AbstractBTree<K, V> implements TransactionManager,
Closeable
 {
     /** The LoggerFactory used by this class */
     protected static final Logger LOG = LoggerFactory.getLogger( PersistedBTree.class );
 
-    /** The RecordManager if the BTree is managed */
+    /** The RecordManager if the B-tree is managed */
     private RecordManager recordManager;
 
-    /** The cache associated with this BTree */
+    /** The cache associated with this B-tree */
     protected Cache cache;
 
     /** The default number of pages to keep in memory */
@@ -62,35 +62,33 @@ public class PersistedBTree<K, V> extend
     /** The cache size, default to 1000 elements */
     protected int cacheSize = DEFAULT_CACHE_SIZE;
 
-    /** A flag indicating if this BTree is a Sub BTree */
-    private boolean isSubBtree = false;
-
-    /** The number of stored Values before we switch to a BTree */
+    /** The number of stored Values before we switch to a B-tree */
     private static final int DEFAULT_VALUE_THRESHOLD_UP = 8;
 
     /** The number of stored Values before we switch back to an array */
     private static final int DEFAULT_VALUE_THRESHOLD_LOW = 1;
 
-    /** The configuration for the array <-> BTree switch */
+    /** The configuration for the array <-> B-tree switch */
     /*No qualifier*/static int valueThresholdUp = DEFAULT_VALUE_THRESHOLD_UP;
     /*No qualifier*/static int valueThresholdLow = DEFAULT_VALUE_THRESHOLD_LOW;
 
     /** A lock to protect the creation of the transaction */
-    protected ReentrantLock createTransaction = new ReentrantLock();
+    private ReentrantLock createTransaction = new ReentrantLock();
 
+    /** A flag set when we initiate an automatic transaction */
+    private AtomicBoolean automaticTransaction = new AtomicBoolean( true );
 
     /**
      * Creates a new BTree, with no initialization.
      */
     /* no qualifier */PersistedBTree()
     {
-        btreeHeader = new BTreeHeader();
         setType( BTreeTypeEnum.PERSISTED );
     }
 
 
     /**
-     * Creates a new persisted BTree using the BTreeConfiguration to initialize the
+     * Creates a new persisted B-tree using the BTreeConfiguration to initialize the
      * BTree
      *
      * @param configuration The configuration to use
@@ -105,22 +103,17 @@ public class PersistedBTree<K, V> extend
             throw new IllegalArgumentException( "BTree name cannot be null" );
         }
 
-        btreeHeader = new BTreeHeader();
-        btreeHeader.setName( name );
-        btreeHeader.setPageSize( configuration.getPageSize() );
-        isSubBtree = configuration.isSubBtree();
-
-        keySerializer = configuration.getKeySerializer();
-        btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
-
-        valueSerializer = configuration.getValueSerializer();
-        btreeHeader.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+        BTreeHeader<K, V> btreeHeader = getBtreeHeader();
+        setName( name );
+        setPageSize( configuration.getPageSize() );
+        setKeySerializer( configuration.getKeySerializer() );
+        setValueSerializer( configuration.getValueSerializer() );
+        setAllowDuplicates( configuration.isAllowDuplicates() );
+        setType( configuration.getBtreeType() );
 
         readTimeOut = configuration.getReadTimeOut();
         writeBufferSize = configuration.getWriteBufferSize();
-        btreeHeader.setAllowDuplicates( configuration.isAllowDuplicates() );
         cacheSize = configuration.getCacheSize();
-        setType( BTreeTypeEnum.PERSISTED );
 
         if ( keySerializer.getComparator() == null )
         {
@@ -129,13 +122,14 @@ public class PersistedBTree<K, V> extend
 
         // Create the first root page, with revision 0L. It will be empty
         // and increment the revision at the same time
-        rootPage = new PersistedLeaf<K, V>( this );
+        // Create the first root page, with revision 0L. It will be empty
+        // and increment the revision at the same time
+        btreeHeader.setRootPage( new PersistedLeaf<K, V>( this ) );
 
-        if ( isSubBtree )
+        if ( btreeType == BTreeTypeEnum.PERSISTED_SUB )
         {
             // The subBTree inherit its cache from its parent BTree
             this.cache = ( ( PersistedBTree<K, V> ) configuration.getParentBTree()
).getCache();
-            this.writeLock = ( ( PersistedBTree<K, V> ) configuration.getParentBTree()
).getWriteLock();
             readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
         }
 
@@ -151,15 +145,13 @@ public class PersistedBTree<K, V> extend
      */
     public void init()
     {
-        if ( !isSubBtree )
+        if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
         {
             // This is not a subBtree, we have to initialize the cache
 
             // Create the queue containing the pending read transactions
             readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
 
-            writeLock = new ReentrantLock();
-
             // Initialize the caches
             CacheConfiguration cacheConfiguration = new CacheConfiguration();
             cacheConfiguration.setName( "pages" );
@@ -191,15 +183,6 @@ public class PersistedBTree<K, V> extend
     /**
      * Return the cache we use in this BTree
      */
-    /* No qualifier */ReentrantLock getWriteLock()
-    {
-        return writeLock;
-    }
-
-
-    /**
-     * Return the cache we use in this BTree
-     */
     /* No qualifier */ConcurrentLinkedQueue<ReadTransaction<K, V>> getReadTransactions()
     {
         return readTransactions;
@@ -222,8 +205,6 @@ public class PersistedBTree<K, V> extend
         }
 
         cache.dispose();
-
-        rootPage = null;
     }
 
 
@@ -232,7 +213,7 @@ public class PersistedBTree<K, V> extend
      */
     /* No qualifier*/long getBtreeOffset()
     {
-        return btreeHeader.getBTreeOffset();
+        return getBtreeHeader().getBTreeOffset();
     }
 
 
@@ -241,7 +222,7 @@ public class PersistedBTree<K, V> extend
      */
     /* No qualifier*/void setBtreeOffset( long btreeOffset )
     {
-        btreeHeader.setBTreeOffset( btreeOffset );
+        getBtreeHeader().setBTreeOffset( btreeOffset );
     }
 
 
@@ -250,7 +231,7 @@ public class PersistedBTree<K, V> extend
      */
     /* No qualifier*/long getRootPageOffset()
     {
-        return btreeHeader.getRootPageOffset();
+        return getBtreeHeader().getRootPageOffset();
     }
 
 
@@ -259,32 +240,14 @@ public class PersistedBTree<K, V> extend
      */
     /* No qualifier*/void setRootPageOffset( long rootPageOffset )
     {
-        btreeHeader.setRootPageOffset( rootPageOffset );
-    }
-
-
-    /**
-     * @return the nextBTreeOffset
-     */
-    /* No qualifier*/long getNextBTreeOffset()
-    {
-        return btreeHeader.getNextBTreeOffset();
-    }
-
-
-    /**
-     * @param nextBTreeOffset the nextBTreeOffset to set
-     */
-    /* No qualifier*/void setNextBTreeOffset( long nextBTreeOffset )
-    {
-        btreeHeader.setNextBTreeOffset( nextBTreeOffset );
+        getBtreeHeader().setRootPageOffset( rootPageOffset );
     }
 
 
     /**
      * Gets the RecordManager for a managed BTree
      *
-     * @return The recordManager if the BTree is managed
+     * @return The recordManager if the B-tree is managed
      */
     /* No qualifier */RecordManager getRecordManager()
     {
@@ -315,81 +278,119 @@ public class PersistedBTree<K, V> extend
      * @return
      * @throws IOException
      */
-    protected Tuple<K, V> delete( K key, V value, long revision ) throws IOException
+    /* no qualifier */ Tuple<K, V> delete( K key, V value, long revision ) throws IOException
     {
-        writeLock.lock();
+        boolean inTransaction = recordManager.isTransactionStarted();
 
-        try
+        if ( !inTransaction )
         {
-            // If the key exists, the existing value will be replaced. We store it
-            // to return it to the caller.
-            Tuple<K, V> tuple = null;
+            recordManager.beginTransaction();
+        }
 
-            // Try to delete the entry starting from the root page. Here, the root
-            // page may be either a Node or a Leaf
-            DeleteResult<K, V> result = rootPage.delete( revision, key, value, null,
-1 );
+        // Try to delete the entry starting from the root page. Here, the root
+        // page may be either a Node or a Leaf
+        DeleteResult<K, V> result = processDelete( key, value, revision );
 
-            if ( result instanceof NotPresentResult )
+        // Check that we have found the element to delete
+        if ( result instanceof NotPresentResult )
+        {
+            // We haven't found the element in the B-tree, just get out
+            if ( !inTransaction )
             {
-                // Key not found.
-                return null;
+                recordManager.commit();
             }
 
-            // Keep the oldRootPage so that we can later access it
-            Page<K, V> oldRootPage = rootPage;
+            return null;
+        }
 
-            if ( result instanceof RemoveResult )
-            {
-                // The element was found, and removed
-                RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
+        // The element was found, and removed
+        AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V>
) result;
 
-                Page<K, V> modifiedPage = removeResult.getModifiedPage();
+        Tuple<K, V> tuple = deleteResult.getRemovedElement();
 
-                // Write the modified page on disk
-                // Note that we don't use the holder, the new root page will
-                // remain in memory.
-                PageHolder<K, V> holder = writePage( modifiedPage, revision );
-
-                // Store the offset on disk in the page in memory
-                ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( ( PersistedPageHolder<K,
V> ) holder )
-                    .getOffset() );
-
-                // Store the last offset on disk in the page in memory
-                ( ( AbstractPage<K, V> ) modifiedPage )
-                    .setLastOffset( ( ( PersistedPageHolder<K, V> ) holder )
-                        .getLastOffset() );
-
-                // This is a new root
-                rootPage = modifiedPage;
-                tuple = removeResult.getRemovedElement();
-            }
+        // Update the B-tree header, creating a new BtreeHeader page now
+        long newBtreeHeaderOffset = recordManager.updateBtreeHeader( this, ( ( AbstractPage<K,
V> ) getRootPage() ).getOffset() );
 
-            // Decrease the number of elements in the current tree if the deletion is successful
-            if ( tuple != null )
-            {
-                btreeHeader.decrementNbElems();
+        // 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
);
+                break;
 
-                // We have to update the rootPage on disk
-                // Update the BTree header now
-                recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) rootPage
).getOffset() );
-            }
+            case PERSISTED_MANAGEMENT :
+                // The B-tree of B-trees or the copiedPages B-tree has been updated, update
the RMheader parameters
+                getBtreeHeader().setBTreeOffset( newBtreeHeaderOffset );
 
-            recordManager.addFreePages( this, result.getCopiedPages() );
+                break;
 
-            // Update the RecordManager header
-            recordManager.updateRecordManagerHeader();
+            default:
+                // Nothing to do for sub-btrees
+                break;
+        }
 
-            // Store the created rootPage into the revision BTree, this will be stored in
RecordManager only if revisions are set to keep
-            recordManager.storeRootPage( this, rootPage );
+        // We can safely free the copied pages
+        recordManager.freePages( this, revision, result.getCopiedPages() );
 
-            // Return the value we have found if it was modified
-            return tuple;
+        // If the B-tree is managed, we have to update the rootPage on disk
+        // Update the RecordManager header
+        if ( !inTransaction )
+        {
+            recordManager.commit();
         }
-        finally
+
+        // Return the value we have found if it was modified
+        return tuple;
+    }
+
+
+    /**
+     * Insert the tuple into the B-tree rootPage, get back the new rootPage
+     */
+    private DeleteResult<K, V> processDelete( K key, V value, long revision ) throws
IOException
+    {
+        // Try to delete the entry starting from the root page. Here, the root
+        // page may be either a Node or a Leaf
+        DeleteResult<K, V> result = getRootPage().delete( key, value, revision);
+
+        if ( result instanceof NotPresentResult )
         {
-            // See above
-            writeLock.unlock();
+            // Key not found.
+            return result;
         }
+
+        // The element was found, and removed
+        AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V>
) result;
+
+        Page<K, V> modifiedPage = removeResult.getModifiedPage();
+
+        // Write the modified page on disk
+        // Note that we don't use the holder, the new root page will
+        // remain in memory.
+        PageHolder<K, V> holder = writePage( modifiedPage, revision );
+
+        // Store the offset on disk in the page in memory
+        ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( ( PersistedPageHolder<K,
V> ) holder )
+            .getOffset() );
+
+        // Store the last offset on disk in the page in memory
+        ( ( AbstractPage<K, V> ) modifiedPage )
+            .setLastOffset( ( ( PersistedPageHolder<K, V> ) holder )
+                .getLastOffset() );
+
+        // This is a new root
+        rootPage = modifiedPage;
+
+        // Decrease the number of elements in the current tree
+        getBtreeHeader().decrementNbElems();
+
+        // We have to update the rootPage on disk
+        // Update the B-tree header now
+        recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) getBtreeHeader().getRootPage()
).getOffset() );
+
+        // Return the value we have found if it was modified
+        return result;
     }
 
 
@@ -413,31 +414,87 @@ public class PersistedBTree<K, V> extend
             throw new IllegalArgumentException( "Key must not be null" );
         }
 
-        // If the key exists, the existing value will be replaced. We store it
-        // to return it to the caller.
-        V modifiedValue = null;
+        // We have to start a new transaction, which will be committed or rollbacked
+        // locally. This will duplicate the current BtreeHeader during this phase.
+        boolean inTransaction = beginTransaction( revision );
+
+        if ( revision == -1L )
+        {
+            revision = currentRevision.get() + 1;
+        }
+
+
+        if ( !inTransaction )
+        {
+            recordManager.beginTransaction();
+        }
 
         // Try to insert the new value in the tree at the right place,
         // starting from the root page. Here, the root page may be either
         // a Node or a Leaf
-        InsertResult<K, V> result = rootPage.insert( revision, key, value );
+        InsertResult<K, V> result = processInsert( key, value, revision );
+
+        // Update the B-tree header, creating a new BtreeHeader page now
+        long newBtreeHeaderOffset = recordManager.updateBtreeHeader( this, ( ( AbstractPage<K,
V> ) getBtreeHeader().getRootPage() ).getOffset() );
+
+        // 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
);
+                break;
+
+            case PERSISTED_MANAGEMENT :
+                // The B-tree of B-trees or the copiedPages B-tree has been updated, update
the RMheader parameters
+                getBtreeHeader().setBTreeOffset( newBtreeHeaderOffset );
+
+                break;
+
+            default:
+                // Nothing to do for sub-btrees
+                break;
+        }
+
+        // We can safely free the copied pages
+        recordManager.freePages( this, revision, result.getCopiedPages() );
+
+        // If the B-tree is managed, we have to update the rootPage on disk
+        // Update the RecordManager header
+        if ( !inTransaction )
+        {
+            recordManager.commit();
+        }
+
+        // Return the value we have found if it was modified
+        return result;
+    }
+
+
+    /**
+     * Insert the tuple into the B-tree rootPage, get back the new rootPage
+     */
+    private InsertResult<K, V> processInsert( K key, V value, long revision ) throws
IOException
+    {
+        InsertResult<K, V> result = getBtreeHeader().getRootPage().insert( key, value,
revision );
+        Page<K, V> newRootPage;
 
         if ( result instanceof ModifyResult )
         {
             ModifyResult<K, V> modifyResult = ( ( ModifyResult<K, V> ) result
);
 
-            Page<K, V> modifiedPage = modifyResult.getModifiedPage();
+            newRootPage = modifyResult.getModifiedPage();
 
-            // Write the modified page on disk
+            // Write the new root page on disk
             // Note that we don't use the holder, the new root page will
             // remain in memory.
-            writePage( modifiedPage, revision );
-
-            // The root has just been modified, we haven't split it
-            // Get it and make it the current root page
-            rootPage = modifiedPage;
+            writePage( newRootPage, revision );
 
-            modifiedValue = modifyResult.getModifiedValue();
+            // Increment the counter if we have inserted a new value
+            if ( modifyResult.getModifiedValue() == null )
+            {
+                getBtreeHeader().incrementNbElems();
+            }
         }
         else
         {
@@ -448,9 +505,8 @@ public class PersistedBTree<K, V> extend
             K pivot = splitResult.getPivot();
             Page<K, V> leftPage = splitResult.getLeftPage();
             Page<K, V> rightPage = splitResult.getRightPage();
-            Page<K, V> newRootPage = null;
 
-            // If the BTree is managed, we have to write the two pages that were created
+            // 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 );
 
@@ -459,41 +515,20 @@ public class PersistedBTree<K, V> extend
             // Create the new rootPage
             newRootPage = new PersistedNode<K, V>( this, revision, pivot, holderLeft,
holderRight );
 
-            // If the BTree is managed, we now have to write the page on disk
+            // If the B-tree is managed, we now have to write the page on disk
             // and to add this page to the list of modified pages
-            PageHolder<K, V> holder = writePage( newRootPage, revision );
+            writePage( newRootPage, revision );
 
-            rootPage = newRootPage;
-        }
-
-        // Increase the number of element in the current tree if the insertion is successful
-        // and does not replace an element
-        if ( modifiedValue == null )
-        {
-            btreeHeader.incrementNbElems();
+            // Always increment the counter : we have added a new value
+            getBtreeHeader().incrementNbElems();
         }
 
-        // If the BTree is managed, we have to update the rootPage on disk
-        // Update the RecordManager header
-        if ( ( writeTransaction == null ) || !writeTransaction.isStarted() )
-        {
-            recordManager.updateRecordManagerHeader();
-
-            // Update the BTree header now
-            recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) rootPage
).getOffset() );
-
-            // Moved the free pages into the list of free pages
-            recordManager.addFreePages( this, result.getCopiedPages() );
+        // Get the new root page and make it the current root page
+        rootPage = newRootPage;
 
-            // Store the created rootPage into the revision BTree, this will be stored in
RecordManager only if revisions are set to keep
-            recordManager.storeRootPage( this, rootPage );
-        }
-
-        // Return the value we have found if it was modified
         return result;
     }
 
-
     /**
      * Write the data in the ByteBuffer, and eventually on disk if needed.
      *
@@ -541,21 +576,9 @@ public class PersistedBTree<K, V> extend
      */
     private PageHolder<K, V> writePage( Page<K, V> modifiedPage, long revision
) throws IOException
     {
-        if ( ( writeTransaction != null ) && writeTransaction.isStarted() )
-        {
-            Map<Page<?, ?>, BTree<?, ?>> pendingPages = recordManager.getPendingPages();
-            pendingPages.put( modifiedPage, this );
-
-            PageHolder<K, V> pageHolder = new PageHolder<K, V>( this, modifiedPage
);
-
-            return pageHolder;
-        }
-        else
-        {
-            PageHolder<K, V> pageHolder = recordManager.writePage( this, modifiedPage,
revision );
+        PageHolder<K, V> pageHolder = recordManager.writePage( this, modifiedPage,
revision );
 
-            return pageHolder;
-        }
+        return pageHolder;
     }
 
     /**
@@ -573,59 +596,90 @@ public class PersistedBTree<K, V> extend
 
 
     /**
-     * Starts a transaction
+     * Get the current rootPage
+     *
+     * @return The rootPage
      */
-    public void beginTransaction()
+    public Page<K, V> getRootPage()
     {
-        createTransaction.lock();
+        return getBtreeHeader().getRootPage();
+    }
 
-        if ( writeTransaction == null )
-        {
-            writeTransaction = new WriteTransaction( recordManager );
-        }
 
-        createTransaction.unlock();
+    /* no qualifier */void setRootPage( Page<K, V> root )
+    {
+        getBtreeHeader().setRootPage( root );
+    }
 
-        writeTransaction.start();
+
+    /**
+     * Starts a transaction
+     */
+    public void beginTransaction()
+    {
+        automaticTransaction.set( false );
+        beginTransaction( getRevision() + 1 );
     }
 
 
     /**
-     * Commits a transaction
+     * Starts a transaction
      */
-    public void commit()
+    private boolean beginTransaction( long revision )
     {
         createTransaction.lock();
 
         if ( writeTransaction == null )
         {
-            writeTransaction = new WriteTransaction( recordManager );
+            writeTransaction = new WriteTransaction();
+        }
+
+        if ( isTransactionStarted() && !automaticTransaction.get() )
+        {
+            createTransaction.unlock();
+
+            return true;
         }
 
         createTransaction.unlock();
 
-        writeTransaction.commit();
+        writeTransaction.start();
+
+        return false;
     }
 
 
     /**
-     * Rollback a transaction
+     * Tells if a transaction has been started or not
      */
-    public void rollback()
+    private boolean isTransactionStarted()
     {
         createTransaction.lock();
 
-        if ( writeTransaction == null )
-        {
-            writeTransaction = new WriteTransaction( recordManager );
-        }
+        boolean started = ( writeTransaction != null ) && ( writeTransaction.isStarted()
);
 
         createTransaction.unlock();
 
-        writeTransaction.rollback();
+        return started;
     }
 
 
+    /**
+     * Commits a transaction
+     */
+    public void commit()
+    {
+        recordManager.commit();
+    }
+
+
+    /**
+     * Rollback a transaction
+     */
+    public void rollback()
+    {
+        recordManager.rollback();
+    }
 
 
     /**
@@ -636,12 +690,12 @@ public class PersistedBTree<K, V> extend
         StringBuilder sb = new StringBuilder();
 
         sb.append( "Managed BTree" );
-        sb.append( "[" ).append( btreeHeader.getName() ).append( "]" );
-        sb.append( "( pageSize:" ).append( btreeHeader.getPageSize() );
+        sb.append( "[" ).append( getName() ).append( "]" );
+        sb.append( "( pageSize:" ).append( getPageSize() );
 
-        if ( rootPage != null )
+        if ( getBtreeHeader().getRootPage() != null )
         {
-            sb.append( ", nbEntries:" ).append( btreeHeader.getNbElems() );
+            sb.append( ", nbEntries:" ).append( getBtreeHeader().getNbElems() );
         }
         else
         {
@@ -659,10 +713,10 @@ public class PersistedBTree<K, V> extend
             sb.append( keySerializer.getComparator().getClass().getSimpleName() );
         }
 
-        sb.append( ", DuplicatesAllowed: " ).append( btreeHeader.isAllowDuplicates() );
+        sb.append( ", DuplicatesAllowed: " ).append( isAllowDuplicates() );
 
         sb.append( ") : \n" );
-        sb.append( rootPage.dumpPage( "" ) );
+        sb.append( getBtreeHeader().getRootPage().dumpPage( "" ) );
 
         return sb.toString();
     }

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeBuilder.java
Mon Feb 10 15:35:18 2014
@@ -32,7 +32,7 @@ import org.apache.directory.mavibot.btre
 
 
 /**
- * A BTree builder that builds a tree from the bottom.
+ * A B-tree builder that builds a tree from the bottom.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
@@ -138,7 +138,7 @@ public class PersistedBTreeBuilder<K, V>
 
         rm.updateBtreeHeader( btree, ( ( AbstractPage<K, V> ) rootPage ).getOffset()
);
 
-        rm.addFreePages( btree, Arrays.asList( btree.getRootPage() ) );
+        rm.freePages( btree, btree.getRootPage().getRevision(), Arrays.asList( btree.getRootPage()
) );
 
         ( ( AbstractBTree<K, V> ) btree ).setRootPage( rootPage );
 

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
Mon Feb 10 15:35:18 2014
@@ -25,11 +25,11 @@ import org.apache.directory.mavibot.btre
 
 /**
  * The B+Tree Configuration. This class can be used to store all the configurable
- * parameters used by the BTree class
- * 
+ * parameters used by the B-tree class
+ *
  * @param <K> The type for the keys
  * @param <V> The type for the stored values
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class PersistedBTreeConfiguration<K, V>
@@ -40,23 +40,23 @@ public class PersistedBTreeConfiguration
     /** The size of the buffer used to write data in disk */
     private int writeBufferSize = BTree.DEFAULT_WRITE_BUFFER_SIZE;
 
-    /** The Key and Value serializer used for this tree. If none is provided, 
-     * the BTree will deduce the serializer to use from the generic type, and
+    /** The Key and Value serializer used for this tree. If none is provided,
+     * the B-tree will deduce the serializer to use from the generic type, and
      * use the default Java serialization  */
     private ElementSerializer<K> keySerializer;
     private ElementSerializer<V> valueSerializer;
 
-    /** The BTree name */
+    /** The B-tree name */
     private String name;
 
-    /** The path where the BTree file will be stored. Default to the local 
+    /** The path where the B-tree file will be stored. Default to the local
      * temporary directory.
      */
     private String filePath;
 
-    /** 
+    /**
      * The maximum delay to wait before a revision is considered as unused.
-     * This delay is necessary so that a read that does not ends does not 
+     * This delay is necessary so that a read that does not ends does not
      * hold a revision in memory forever.
      * The default value is 10000 (10 seconds). If the value is 0 or below,
      * the delay is considered as infinite
@@ -66,13 +66,13 @@ public class PersistedBTreeConfiguration
     /** Flag to enable duplicate key support */
     private boolean allowDuplicates;
 
-    /** A flag set when the BTree is a sub btree */
-    private boolean isSubBtree = false;
+    /** The B-tree type */
+    private BTreeTypeEnum btreeType = BTreeTypeEnum.PERSISTED;
 
     /** The cache size, if it's <= 0, we don't have cache */
     private int cacheSize;
 
-    /** The inherited BTree if we create a sub BTree */
+    /** The inherited B-tree if we create a sub B-tree */
     private BTree<?, V> parentBTree;
 
 
@@ -224,10 +224,10 @@ public class PersistedBTreeConfiguration
 
     /**
      * enable duplicate key support
-     * 
+     *
      * @param allowDuplicates
-     * @throws IllegalStateException if the btree was already initialized or when tried to
turn off duplicate suport on
-     * an existing btree containing duplicate keys
+     * @throws IllegalStateException if the B-tree was already initialized or when tried
to turn off duplicate suport on
+     * an existing B-tree containing duplicate keys
      */
     public void setAllowDuplicates( boolean allowDuplicates )
     {
@@ -272,19 +272,19 @@ public class PersistedBTreeConfiguration
 
 
     /**
-     * @return True if this is a sub btree, false otherwise
+     * @return The BtreeType for this Btree
      */
-    public boolean isSubBtree()
+    public BTreeTypeEnum getBtreeType()
     {
-        return isSubBtree;
+        return btreeType;
     }
 
 
     /**
-     * @param isSubBtree True if the BTree will be a sub btree, false otherwise
+     * @param btreeType The BtreeType
      */
-    public void setSubBtree( boolean isSubBtree )
+    public void setBtreeType( BTreeTypeEnum btreeType )
     {
-        this.isSubBtree = isSubBtree;
+        this.btreeType = btreeType;
     }
 }

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
Mon Feb 10 15:35:18 2014
@@ -71,7 +71,7 @@ import org.apache.directory.mavibot.btre
     /**
      * {@inheritDoc}
      */
-    public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+    public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
         // Find the key into this leaf
         int pos = findPos( key );
@@ -116,7 +116,7 @@ import org.apache.directory.mavibot.btre
      * {@inheritDoc}
      */
     @SuppressWarnings("unchecked")
-    public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V>
parent, int parentPos )
+    /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K,
V> parent, int parentPos )
         throws IOException
     {
         // Check that the leaf is not empty

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedNode.java
Mon Feb 10 15:35:18 2014
@@ -120,7 +120,7 @@ import java.util.List;
     /**
      * {@inheritDoc}
      */
-    public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+    public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
     {
         // Find the key into this leaf
         int pos = findPos( key );
@@ -136,7 +136,7 @@ import java.util.List;
         Page<K, V> child = children[pos].getValue();
 
         // and insert the <K, V> into this child
-        InsertResult<K, V> result = child.insert( revision, key, value );
+        InsertResult<K, V> result = child.insert( key, value, revision );
 
         // Ok, now, we have injected the <K, V> tuple down the tree. Let's check
         // the result to see if we have to split the current page
@@ -567,7 +567,7 @@ import java.util.List;
     /**
      * {@inheritDoc}
      */
-    public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V>
parent, int parentPos )
+    /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K,
V> parent, int parentPos )
         throws IOException
     {
         // We first try to delete the element from the child it belongs to
@@ -582,12 +582,12 @@ import java.util.List;
         {
             index = -( pos + 1 );
             child = children[-pos].getValue();
-            deleteResult = child.delete( revision, key, value, this, -pos );
+            deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision,
this, -pos );
         }
         else
         {
             child = children[pos].getValue();
-            deleteResult = child.delete( revision, key, value, this, pos );
+            deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision,
this, pos );
         }
 
         // If the key is not present in the tree, we simply return

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.java
Mon Feb 10 15:35:18 2014
@@ -248,7 +248,7 @@ import org.apache.directory.mavibot.btre
             configuration.setName( UUID.randomUUID().toString() );
             configuration.setValueSerializer( valueSerializer );
             configuration.setParentBTree( parentBtree );
-            configuration.setSubBtree( true );
+            configuration.setBtreeType( BTreeTypeEnum.PERSISTED_SUB );
 
             valueBtree = BTreeFactory.createPersistedBTree( configuration );
 
@@ -655,7 +655,7 @@ import org.apache.directory.mavibot.btre
         long offset = LongSerializer.deserialize( raw );
 
         // and reload the sub btree
-        valueBtree = parentBtree.getRecordManager().loadDupsBTree( offset );
+        valueBtree = parentBtree.getRecordManager().loadDupsBtree( offset );
     }
 
 

Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
(original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
Mon Feb 10 15:35:18 2014
@@ -35,7 +35,7 @@ import java.util.Date;
  * A Transaction can be hold for quite a long time, for instance while doing
  * a browse against a big BTree. At some point, transactions which are pending
  * for too long will be closed by the transaction manager.
- * 
+ *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  *
  * @param <K> The type for the Key
@@ -50,7 +50,10 @@ public class ReadTransaction<K, V>
     private long creationDate;
 
     /** The revision on which we are having a transaction */
-    private volatile Page<K, V> root;
+    private volatile Page<K, V> rootPage;
+
+    /** The associated B-tree header */
+    private BTreeHeader<K, V> btreeHeader;
 
     /** A flag used to tell if a transaction is closed or not */
     private volatile boolean closed;
@@ -58,16 +61,15 @@ public class ReadTransaction<K, V>
 
     /**
      * Creates a new transaction instance
-     * 
-     * @param root The associated root
-     * @param revision The revision this transaction is using
-     * @param creationDate The creation date for this transaction
-     */
-    public ReadTransaction( Page<K, V> root, long revision, long creationDate )
-    {
-        this.revision = revision;
-        this.creationDate = creationDate;
-        this.root = root;
+     *
+     * @param btreeHeader The BtreeHeader we will use for this read transaction
+     */
+    public ReadTransaction( BTreeHeader<K, V> btreeHeader )
+    {
+        this.revision = btreeHeader.getRevision();
+        this.creationDate = System.currentTimeMillis();
+        this.rootPage = btreeHeader.getRootPage();
+        this.btreeHeader = btreeHeader;
         closed = false;
     }
 
@@ -82,11 +84,11 @@ public class ReadTransaction<K, V>
 
 
     /**
-     * @return the associated root
+     * @return the associated rootPage
      */
-    public Page<K, V> getRoot()
+    public Page<K, V> getRootPage()
     {
-        return root;
+        return rootPage;
     }
 
 
@@ -100,11 +102,20 @@ public class ReadTransaction<K, V>
 
 
     /**
+     * @return the btreeHeader
+     */
+    public BTreeHeader<K, V> getBtreeHeader()
+    {
+        return btreeHeader;
+    }
+
+
+    /**
      * Close the transaction, releasing the revision it was using.
      */
     public void close()
     {
-        root = null;
+        rootPage = null;
         closed = true;
     }
 



Mime
View raw message