You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2017/10/09 20:33:00 UTC

svn commit: r1811602 [1/6] - in /directory/mavibot/branches/single-value/mavibot: ./ src/main/java/org/apache/directory/mavibot/btree/ src/main/java/org/apache/directory/mavibot/btree/exception/ src/test/java/org/apache/directory/mavibot/btree/

Author: elecharny
Date: Mon Oct  9 20:32:59 2017
New Revision: 1811602

URL: http://svn.apache.org/viewvc?rev=1811602&view=rev
Log:
Vast refactoring to add transaction support to Mavibot.

This is a temporary commit, as there are still many compilation errors, and failing tests. More to come !

Added:
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java
      - copied, changed from r1811601, directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/BTreeNotFoundException.java
Removed:
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageHolder.java
Modified:
    directory/mavibot/branches/single-value/mavibot/pom.xml
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeInfo.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/DeleteResult.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/KeyCursor.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Leaf.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/ModifyResult.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Node.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/NotPresentResult.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageReclaimer.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManagerHeader.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RemoveResult.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionOffsets.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Transaction.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/TupleCursor.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/ValueHolder.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/WALObject.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/BTreeBrowseTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/BTreeBuilderTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/PageReclaimerTest.java

Modified: directory/mavibot/branches/single-value/mavibot/pom.xml
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/pom.xml?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/pom.xml (original)
+++ directory/mavibot/branches/single-value/mavibot/pom.xml Mon Oct  9 20:32:59 2017
@@ -52,6 +52,12 @@
       <scope>test</scope>
     </dependency>
 
+    <dependency>
+      <groupId>org.ehcache</groupId>
+      <artifactId>ehcache</artifactId>
+      <version>3.4.0</version>
+    </dependency>
+
     <!-- Logging dependencies -->
 
     <dependency>

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java Mon Oct  9 20:32:59 2017
@@ -31,14 +31,16 @@ import java.util.List;
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-/* No qualifier*/abstract class AbstractDeleteResult<K, V> extends AbstractResult<K, V> implements
-    DeleteResult<K, V>
+/* No qualifier*/abstract class AbstractDeleteResult<K, V> extends AbstractResult<K, V> implements DeleteResult<K, V>
 {
     /** The modified page reference */
     private Page<K, V> modifiedPage;
 
     /** The removed element if the key was found in the tree*/
     private Tuple<K, V> removedElement;
+    
+    /** The key following the deleted key (may be null) */
+    private K nextKey;
 
 
     /**
@@ -75,6 +77,25 @@ import java.util.List;
      * {@inheritDoc}
      */
     @Override
+    public K getNextKey()
+    {
+        return nextKey;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setNextKey( K nextKey )
+    {
+        this.nextKey = nextKey;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
     public Page<K, V> getModifiedPage()
     {
         return modifiedPage;
@@ -84,7 +105,6 @@ import java.util.List;
     /**
      * {@inheritDoc}
      */
-    @Override
     public Tuple<K, V> getRemovedElement()
     {
         return removedElement;

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java Mon Oct  9 20:32:59 2017
@@ -23,12 +23,13 @@ package org.apache.directory.mavibot.btr
 import java.io.IOException;
 import java.lang.reflect.Array;
 
-import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
-
-
 /**
- * A MVCC abstract Page. It stores the field and the methods shared by the Node and Leaf
- * classes (the keys and values/children).
+ * A MVCC abstract Page. It stores the keys/children and the methods shared by the {@link Node} and {@link Leaf}
+ * classes (the keys and values/children). It also hold the number of elements the page contains, and its current revision.
+ * <p>
+ * Keys are stored in {@link KeyHolder}s, values in {@link ValueHolder}.
+ * <p>
+ * The {@link Page} extends {@link AbstractWALObject} as any pae may be stored in the WAL at some point.
  *
  * @param <K> The type for the Key
  * @param <V> The type for the stored value
@@ -41,22 +42,19 @@ import org.apache.directory.mavibot.btre
     protected KeyHolder<K>[] keys;
 
     /** Children pages associated with keys. */
-    protected PageHolder<K, V>[] children;
+    protected long[] children;
 
     /** The number of current values in the Page */
-    protected int nbPageElems;
-
-    /** This Page's revision */
-    protected long revision;
+    protected int pageNbElems;
 
     /**
      * Creates a default empty AbstractPage
      *
-     * @param btree The associated BTree
+     * @param btreeInfo The associated BTree info
      */
-    protected AbstractPage( BTree<K, V> btree )
+    protected AbstractPage( BTreeInfo<K, V> btreeInfo )
     {
-        this.btree = btree;
+        super( btreeInfo );
     }
 
 
@@ -65,12 +63,12 @@ import org.apache.directory.mavibot.btre
      */
     @SuppressWarnings("unchecked")
     // Cannot create an array of generic objects
-    protected AbstractPage( BTree<K, V> btree, long revision, int nbPageElems )
+    protected AbstractPage( BTreeInfo<K, V> btreeInfo, long revision, int pageNbElems )
     {
-        this.btree = btree;
+        super( btreeInfo );
         this.revision = revision;
-        this.nbPageElems = nbPageElems;
-        this.keys = ( KeyHolder[] ) Array.newInstance( KeyHolder.class, btree.getPageNbElem() );
+        this.pageNbElems = pageNbElems;
+        this.keys = ( KeyHolder[] ) Array.newInstance( KeyHolder.class, btreeInfo.getPageNbElem() );
     }
 
 
@@ -78,29 +76,32 @@ import org.apache.directory.mavibot.btre
      * {@inheritDoc}
      */
     @Override
-    public int getNbPageElems()
+    public int getPageNbElems()
     {
-        return nbPageElems;
+        return pageNbElems;
     }
 
 
     /**
      * Sets the number of element in this page
-     * @param nbPageElems The number of elements
+     * 
+     * @param pageNbElems The number of elements
      */
-    /* no qualifier */void setNbPageElems( int nbPageElems )
+    /* no qualifier */void setPageNbElems( int pageNbElems )
     {
-        this.nbPageElems = nbPageElems;
+        this.pageNbElems = pageNbElems;
     }
 
 
     /**
-     * {@inheritDoc}
+     * Returns the key at a given position
+     *
+     * @param pos The position of the key we want to retrieve
+     * @return The key found at the given position
      */
-    @Override
-    public K getKey( int pos )
+    protected K getKey( int pos )
     {
-        if ( ( pos < nbPageElems ) && ( keys[pos] != null ) )
+        if ( ( pos < pageNbElems ) && ( keys[pos] != null ) )
         {
             return keys[pos].getKey();
         }
@@ -109,224 +110,54 @@ import org.apache.directory.mavibot.btre
             return null;
         }
     }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean hasKey( K key ) throws IOException
-    {
-        int pos = findPos( key );
-
-        if ( pos < 0 )
-        {
-            // Here, if we have found the key in the node, then we must go down into
-            // the right child, not the left one
-            return children[-pos].getValue().hasKey( key );
-        }
-        else
-        {
-            Page<K, V> page = children[pos].getValue();
-
-            return page.hasKey( key );
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    /* no qualifier */Page<K, V> getReference( int pos ) throws IOException
-    {
-        if ( pos < nbPageElems + 1 )
-        {
-            if ( children[pos] != null )
-            {
-                return children[pos].getValue();
-            }
-            else
-            {
-                return null;
-            }
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public TupleCursor<K, V> browse( Transaction transaction, K key, ParentPos<K, V>[] stack, int depth )
-        throws IOException
-    {
-        int pos = findPos( key );
-
-        if ( pos < 0 )
-        {
-            pos = -pos;
-        }
-
-        // We first stack the current page
-        stack[depth++] = new ParentPos<>( this, pos );
-
-        Page<K, V> page = children[pos].getValue();
-
-        return page.browse( transaction, key, stack, depth );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean contains( K key, V value ) throws IOException
-    {
-        int pos = findPos( key );
-
-        if ( pos < 0 )
-        {
-            // Here, if we have found the key in the node, then we must go down into
-            // the right child, not the left one
-            return children[-pos].getValue().contains( key, value );
-        }
-        else
-        {
-            return children[pos].getValue().contains( key, value );
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public DeleteResult<K, V> delete( WriteTransaction transaction, K key ) throws IOException
-    {
-        return delete( transaction, key, null, -1 );
-    }
-
-
-    /**
-     * The real delete implementation. It can be used for internal deletion in the B-tree.
-     *
-     * @param key The key to delete
-     * @param parent The parent page
-     * @param parentPos The position of this page in the parent page
-     * @return The result
-     * @throws IOException If we had an issue while processing the deletion
-     */
-    /* no qualifier */abstract DeleteResult<K, V> delete( WriteTransaction transaction, K key, Page<K, V> parent,
-        int parentPos ) throws IOException;
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public V get( K key ) throws IOException, KeyNotFoundException
-    {
-        int pos = findPos( key );
-
-        if ( pos < 0 )
-        {
-            // Here, if we have found the key in the node, then we must go down into
-            // the right child, not the left one
-            return children[-pos].getValue().get( key );
-        }
-        else
-        {
-            return children[pos].getValue().get( key );
-        }
-    }
-
-
+    
+    
     /**
-     * {@inheritDoc}
+     * Set a parent page child value, either an offset (a positive value) or an ID (a negative value) if the offset is -1.
+     * 
+     * @param parent The node to update
+     * @param pos The position in the parent node
+     * @param child The child to refer to
      */
-    /* no qualifier */Page<K, V> getPage( int pos )
+    protected void setChild( Node<K, V> parent, int pos, Page<K, V> child )
     {
-        if ( ( pos >= 0 ) && ( pos < children.length ) && ( children[pos] != null ) )
-        {
-            return children[pos].getValue();
-        }
-        else
+        parent.children[pos] = child.getOffset();
+        
+        if ( parent.children[pos] == BTreeConstants.NO_PAGE )
         {
-            return null;
+            parent.children[pos] = -child.getId();
         }
     }
-
-
+    
+    
     /**
-     * Inject a pageHolder into the node, at a given position
+     * Set the page child value, either an offset (a positive value) or an ID (a negative value) if the offset is -1.
      * 
-     * @param pos The position of the added pageHolder
-     * @param pageHolder The pageHolder to add
+     * @param children The parent's children
+     * @param pos The position in the parent node
+     * @param child The child to refer to
      */
-    /* no qualifier */void setPageHolder( int pos, PageHolder<K, V> pageHolder )
+    protected void setChild( long[] children, int pos, Page<K, V> child )
     {
-        if ( ( pos >= 0 ) && ( pos < children.length ) )
+        children[pos] = child.getOffset();
+        
+        if ( children[pos] == BTreeConstants.NO_PAGE )
         {
-            children[pos] = pageHolder;
+            children[pos] = -child.getId();
         }
     }
 
 
     /**
-     * Sets the value at a give position
-     * @param pos The position in the values array
-     * @param value the value to inject
-     */
-    /* no qualifier */void setValue( int pos, ValueHolder<V> value )
-    {
-        // Implementation in the leaves
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public TupleCursor<K, V> browse( Transaction transaction, ParentPos<K, V>[] stack, int depth )
-        throws IOException
-    {
-        stack[depth++] = new ParentPos<>( this, 0 );
-
-        Page<K, V> page = children[0].getValue();
-
-        return page.browse( transaction, stack, depth );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public KeyCursor<K> browseKeys( Transaction transaction, ParentPos<K, K>[] stack, int depth )
-        throws IOException
-    {
-        stack[depth++] = new ParentPos( this, 0 );
-
-        Page<K, V> page = children[0].getValue();
-
-        return page.browseKeys( transaction, stack, depth );
-    }
-
-
-    /**
      * Selects the sibling (the previous or next page with the same parent) which has
      * the more element assuming it's above N/2
      *
+     * @param transaction The {@link Transaction} we are running in 
      * @param parent The parent of the current page
-     * @param The position of the current page reference in its parent
+     * @param parentPos The position of the current page reference in its parent
      * @return The position of the sibling, or -1 if we have'nt found any sibling
-     * @throws IOException If we have an error while trying to access the page
      */
-    protected int selectSibling( Transaction transaction, Page<K, V> parent, int parentPos ) throws IOException
+    protected int selectSibling( Transaction transaction, Node<K, V> parent, int parentPos ) throws IOException
     {
         if ( parentPos == 0 )
         {
@@ -335,18 +166,24 @@ import org.apache.directory.mavibot.btre
             return 1;
         }
 
-        if ( parentPos == parent.getNbPageElems() )
+        if ( parentPos == parent.getPageNbElems() )
         {
             // The current page is referenced on the right of its parent's page :
             // we will not have a next page with the same parent
             return parentPos - 1;
         }
 
-        Page<K, V> prevPage = ( ( AbstractPage<K, V> ) parent ).getPage( parentPos - 1 );
-        Page<K, V> nextPage = ( ( AbstractPage<K, V> ) parent ).getPage( parentPos + 1 );
+        // Ok, in the middle of a page, select the one with the higher number of children,
+        // or the left one
+        Page<K, V> prevPage = parent.getPage( transaction, parentPos - 1 );
+        Page<K, V> nextPage = parent.getPage( transaction, parentPos + 1 );
 
-        int prevPageSize = prevPage.getNbPageElems();
-        int nextPageSize = nextPage.getNbPageElems();
+        if ( prevPage == null )
+        {
+            prevPage = parent.getPage( transaction, parentPos - 1 );
+        }
+        int prevPageSize = prevPage.getPageNbElems();
+        int nextPageSize = nextPage.getPageNbElems();
 
         if ( prevPageSize >= nextPageSize )
         {
@@ -360,29 +197,9 @@ import org.apache.directory.mavibot.btre
 
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public K getLeftMostKey()
-    {
-        return keys[0].getKey();
-    }
-
-
-    /**
-     * {@inheritDoc}
+     * @return the array containing the {@link Page}'s keys.
      */
-    @Override
-    public K getRightMostKey()
-    {
-        return keys[nbPageElems - 1].getKey();
-    }
-
-
-    /**
-     * @return the keys
-     */
-    /* no qualifier */KeyHolder<K>[] getKeys()
+    public KeyHolder<K>[] getKeys()
     {
         return keys;
     }
@@ -392,7 +209,7 @@ import org.apache.directory.mavibot.btre
      * Sets the key at a give position
      *
      * @param pos The position in the keys array
-     * @param key the key to inject
+     * @param key The key to inject
      */
     /* no qualifier */void setKey( int pos, KeyHolder<K> key )
     {
@@ -401,7 +218,7 @@ import org.apache.directory.mavibot.btre
 
 
     /**
-     * @param revision the keys to set
+     * @param keys The keys to set
      */
     /* no qualifier */void setKeys( KeyHolder<K>[] keys )
     {
@@ -410,25 +227,6 @@ import org.apache.directory.mavibot.btre
 
 
     /**
-     * @return the revision
-     */
-    @Override
-    public long getRevision()
-    {
-        return revision;
-    }
-
-
-    /**
-     * @param revision the revision to set
-     */
-    /* no qualifier */void setRevision( long revision )
-    {
-        this.revision = revision;
-    }
-
-
-    /**
      * Compares two keys
      *
      * @param key1 The first key
@@ -453,7 +251,7 @@ import org.apache.directory.mavibot.btre
             return -1;
         }
 
-        return btree.getKeyComparator().compare( key1, key2 );
+        return btreeInfo.getKeySerializer().getComparator().compare( key1, key2 );
     }
 
 
@@ -493,17 +291,16 @@ import org.apache.directory.mavibot.btre
      * @param key The key to find
      * @return The position in the page.
      */
-    @Override
-    public int findPos( K key )
+    protected int findPos( K key )
     {
         // Deal with the special key where we have an empty page
-        if ( nbPageElems == 0 )
+        if ( pageNbElems == 0 )
         {
             return 0;
         }
 
         int min = 0;
-        int max = nbPageElems - 1;
+        int max = pageNbElems - 1;
 
         // binary search
         while ( min < max )
@@ -551,62 +348,6 @@ import org.apache.directory.mavibot.btre
 
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Tuple<K, V> findLeftMost() throws IOException
-    {
-        return children[0].getValue().findLeftMost();
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Tuple<K, V> findRightMost() throws IOException
-    {
-        return children[nbPageElems].getValue().findRightMost();
-    }
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getName()
-    {
-        return btree.getName();
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String dumpPage( String tabs )
-    {
-        StringBuilder sb = new StringBuilder();
-
-        if ( nbPageElems > 0 )
-        {
-            // Start with the first child
-            sb.append( children[0].getValue().dumpPage( tabs + "    " ) );
-
-            for ( int i = 0; i < nbPageElems; i++ )
-            {
-                sb.append( tabs );
-                sb.append( "<" );
-                sb.append( getKey( i ) ).append( ">\n" );
-                sb.append( children[i + 1].getValue().dumpPage( tabs + "    " ) );
-            }
-        }
-
-        return sb.toString();
-    }
-
-
-    /**
      * @see Object#toString()
      */
     @Override
@@ -615,7 +356,8 @@ import org.apache.directory.mavibot.btre
         StringBuilder sb = new StringBuilder();
 
         sb.append( "r" ).append( revision );
-        sb.append( ", nbPageElems:" ).append( nbPageElems );
+        sb.append( ", B-tree:" ).append(  getName() );
+        sb.append( ", pageNbElems:" ).append( pageNbElems );
         sb.append( ", id:" ).append( id );
 
         if ( offset > 0 )

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java Mon Oct  9 20:32:59 2017
@@ -23,6 +23,8 @@ package org.apache.directory.mavibot.btr
 import java.io.IOException;
 import java.util.Date;
 
+import org.apache.directory.mavibot.btree.exception.BTreeNotFoundException;
+
 
 /**
  * A read transaction is used to insure that reads are always done against 
@@ -67,6 +69,7 @@ public abstract class AbstractTransactio
         this( recordManager, DEFAULT_TIMEOUT );
     }
     
+    
     /**
      * Creates a new read transaction, with a specific tiemout. It create a new copy of
      * the recordManager header
@@ -78,7 +81,6 @@ public abstract class AbstractTransactio
     {
         assert recordManager != null;
         this.recordManager = recordManager;
-        recordManagerHeader = recordManager.getRecordManagerHeader();
         
         this.timeout = timeout;
     }
@@ -88,6 +90,16 @@ public abstract class AbstractTransactio
      * {@inheritDoc}
      */
     @Override
+    public <K, V> Page<K, V> getPage( BTreeInfo<K, V> btreeInfo, long offset ) throws IOException
+    {
+        return ( Page<K, V> ) recordManager.getPage( btreeInfo, recordManagerHeader.pageSize, offset );
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public RecordManager getRecordManager()
     {
         return recordManager;
@@ -171,6 +183,25 @@ public abstract class AbstractTransactio
     {
         closed = true;
     }
+    
+    
+    /**
+     * {@inheritDoc}
+     * @param name The B-tree we are looking for
+     * @return The found B-tree, or a BTreeNotFoundException if teh B-tree does not exist.
+     */
+    @Override
+    public <K, V> BTree<K, V> getBTree( String name )
+    {
+        BTree<K, V> btree = recordManagerHeader.getBTree( name );
+        
+        if ( btree == null )
+        {
+            throw new BTreeNotFoundException( "Cannot find btree " + name );
+        }
+        
+        return btree;
+    }
 
 
     /**

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java Mon Oct  9 20:32:59 2017
@@ -7,17 +7,37 @@ package org.apache.directory.mavibot.btr
  */
 public abstract class AbstractWALObject<K, V> implements WALObject<K, V>
 {
-    /** The B-tree this header is associated with */
-    protected BTree<K, V> btree;
+    /** The current revision */
+    protected long revision = 0L;
+
+    /** The B-tree information this object is associated with */
+    protected BTreeInfo<K, V> btreeInfo;
     
     /** The PageIO of the serialized WALObject */
     protected PageIO[] pageIOs;
 
     /** The first {@link PageIO} storing the serialized Page on disk */
-    protected long offset = RecordManager.NO_PAGE;
+    protected long offset = BTreeConstants.NO_PAGE;
     
     /** This page ID */
     protected long id;
+    
+    /**
+     * Create a new instance of WALObject
+     */
+    public AbstractWALObject()
+    {
+    }
+
+    /**
+     * Create a new instance of WALObject
+     * @param btreeInfo The associated BTree information
+     */
+    public AbstractWALObject( BTreeInfo<K, V> btreeInfo )
+    {
+        this.btreeInfo = btreeInfo;
+    }
+    
 
     /**
      * {@inheritDoc}
@@ -44,7 +64,7 @@ public abstract class AbstractWALObject<
     @Override
     public String getName()
     {
-        return null;
+        return btreeInfo.getName();
     }
 
 
@@ -59,34 +79,42 @@ public abstract class AbstractWALObject<
 
 
     /**
-     * {@inheritDoc}
+     * @return the revision
      */
     @Override
-    public void setPageIOs( PageIO[] pageIOs )
+    public long getRevision()
     {
-        this.pageIOs = pageIOs;
-        offset = pageIOs[0].getOffset();
+        return revision;
     }
 
 
     /**
-     * @return the B-tree
+     * @param revision the revision to set
+     */
+    /* no qualifier */void setRevision( long revision )
+    {
+        this.revision = revision;
+    }
+
+
+    /**
+     * {@inheritDoc}
      */
     @Override
-    public BTree<K, V> getBtree()
+    public void setPageIOs( PageIO[] pageIOs )
     {
-        return btree;
+        this.pageIOs = pageIOs;
+        offset = pageIOs[0].getOffset();
     }
 
 
     /**
-     * Associate a B-tree with this BTreeHeader instance
-     * 
-     * @param btree the B-tree to set
+     * @return the B-tree
      */
-    /* no qualifier */void setBtree( BTree<K, V> btree )
+    @Override
+    public BTreeInfo<K, V> getBtreeInfo()
     {
-        this.btree = btree;
+        return btreeInfo;
     }
 
 
@@ -114,8 +142,18 @@ public abstract class AbstractWALObject<
      * 
      * @param recordManagerHeader the RecordManagerHeader which contains the page ID counter
      */
-    /* no qualifier*/ void initId( RecordManagerHeader recordManagerHeader )
+    protected void initId( RecordManagerHeader recordManagerHeader )
     {
         this.id = recordManagerHeader.idCounter++;
     }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isBTreeUser()
+    {
+        return btreeInfo.getType() != BTreeTypeEnum.BTREE_OF_BTREES && btreeInfo.getType() != BTreeTypeEnum.COPIED_PAGES_BTREE;
+    }
 }

Copied: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java (from r1811601, directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java)
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java?p2=directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java&p1=directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java&r1=1811601&r2=1811602&rev=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java Mon Oct  9 20:32:59 2017
@@ -26,7 +26,6 @@ import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.Comparator;
-import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.apache.commons.collections.map.LRUMap;
 import org.apache.directory.mavibot.btree.exception.BTreeCreationException;
@@ -45,65 +44,40 @@ import org.slf4j.LoggerFactory;
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class BTreeImpl<K, V> implements BTree<K, V>, Closeable
+public class BTree<K, V> implements Closeable
 {
     /** The LoggerFactory used by this class */
-    protected static final Logger LOG = LoggerFactory.getLogger( BTreeImpl.class );
+    protected static final Logger LOG = LoggerFactory.getLogger( BTree.class );
 
     protected static final Logger LOG_PAGES = LoggerFactory.getLogger( "org.apache.directory.mavibot.LOG_PAGES" );
 
-    /** The default number of pages to keep in memory */
-    public static final int DEFAULT_CACHE_SIZE = 1000;
+    /** Default page size (number of entries per node) */
+    public static final int DEFAULT_PAGE_NBELEM = 16;
+
+    /** Default size of the buffer used to write data on disk. Around 1Mb */
+    public static final int DEFAULT_WRITE_BUFFER_SIZE = 4096 * 250;
+
+    /** Define a default delay for a read transaction. This is 10 seconds */
+    public static final long DEFAULT_READ_TIMEOUT = 10 * 1000L;
 
     /** The size of the stack to use to manage tree searches */
     private static final int MAX_STACK_DEPTH = 32;
 
     /** The BtreeInfo */
     private BTreeInfo<K, V> btreeInfo = null;
-
-    /** The cache size, default to 1000 elements */
-    private int cacheSize = DEFAULT_CACHE_SIZE;
     
-    /** The current Header for a managed BTree */
+    /** The B-tree Header */
     private BTreeHeader<K, V> currentBtreeHeader;
-
-    /** The BTree type : either in-memory, disk backed or persisted */
-    private BTreeTypeEnum btreeType;
-
-    /** The cache associated with this B-tree */
-    private LRUMap cache;
-
-    /** The Key serializer used for this tree.*/
-    private ElementSerializer<K> keySerializer;
-
-    /** The FQCN of the Key serializer */
-    private String keySerializerFQCN;
-
-    /** The Value serializer used for this tree. */
-    private ElementSerializer<V> valueSerializer;
-
-    /** The FQCN of the Value serializer */
-    private String valueSerializerFQCN;
-
-    /** The BTree name */
-    private String name;
-
-    /** The number of elements in a page for this B-tree */
-    private int pageNbElem;
     
     /** The RecordManager */
     private RecordManager recordManager;
-    
-    /** The RecordManagerHeader */
-    private RecordManagerHeader recordManagerHeader;
 
 
     /**
      * Creates a new BTree, with no initialization.
      */
-    /* No qualifier */BTreeImpl()
+    BTree()
     {
-        setType( BTreeTypeEnum.PERSISTED );
     }
 
 
@@ -113,36 +87,49 @@ public class BTreeImpl<K, V> implements
      *
      * @param configuration The configuration to use
      */
-    BTreeImpl( Transaction transaction, BTreeConfiguration<K, V> configuration )
+    BTree( Transaction transaction, BTreeConfiguration<K, V> configuration )
     {
         if ( configuration.getName() == null )
         {
             throw new IllegalArgumentException( "BTree name cannot be null" );
         }
 
+        btreeInfo = new BTreeInfo<>();
+        
         setName( configuration.getName() );
         setPageNbElem( configuration.getPageNbElem() );
         setKeySerializer( configuration.getKeySerializer() );
         setValueSerializer( configuration.getValueSerializer() );
         setType( configuration.getBtreeType() );
         recordManager = transaction.getRecordManager();
-        recordManagerHeader = transaction.getRecordManagerHeader();
-
-        cacheSize = configuration.getCacheSize();
-
-        if ( keySerializer.getComparator() == null )
+        //recordManagerHeader = transaction.getRecordManagerHeader();
+        
+        if ( btreeInfo.getKeySerializer().getComparator() == null )
         {
             throw new IllegalArgumentException( "Comparator should not be null" );
         }
+    }
+    
+    
+    public BTree<K, V> copy()
+    {
+        BTree<K, V> copy = new BTree<>();
+        
+        copy.btreeInfo = btreeInfo;
+        copy.currentBtreeHeader = currentBtreeHeader;
+        copy.recordManager = recordManager;
         
-        initCache();
+        return copy;
     }
 
 
     /**
-     * {@inheritDoc}
+     * Creates a cursor starting at the beginning of the tree
+     *
+     * @param transaction The Transaction we are running in 
+     * @return A cursor on the B-tree
+     * @throws IOException
      */
-    @Override
     public TupleCursor<K, V> browse( Transaction transaction ) throws IOException, KeyNotFoundException, CursorException
     {
         if ( transaction == null )
@@ -164,9 +151,13 @@ public class BTreeImpl<K, V> implements
 
 
     /**
-     * {@inheritDoc}
+     * Creates a cursor starting on the given key
+     *
+     * @param key The key which is the starting point. If the key is not found,
+     * then the cursor will always return null.
+     * @return A cursor on the B-tree
+     * @throws IOException
      */
-    @Override
     public TupleCursor<K, V> browseFrom( Transaction transaction, K key ) throws IOException
     {
         // Check that we have a TransactionManager
@@ -187,15 +178,17 @@ public class BTreeImpl<K, V> implements
     @Override
     public void close() throws IOException
     {
-        // Clean the cache
-        //cache.clear();
+        // Nothing to do
     }
 
 
     /**
-     * {@inheritDoc}
+     * Checks if the B-tree contains the given key with the given value.
+     *
+     * @param key The key we are looking for
+     * @param value The value associated with the given key
+     * @return true if the key and value are associated with each other, false otherwise
      */
-    @Override
     public boolean contains( Transaction transaction, K key, V value ) throws IOException
     {
         if ( transaction == null )
@@ -204,18 +197,21 @@ public class BTreeImpl<K, V> implements
         }
         else
         {
-            return getRootPage().contains( key, value );
+            return getRootPage().contains( transaction, key, value );
         }
     }
 
 
     /**
-     * {@inheritDoc}
+     * Delete the entry which key is given as a parameter. If the entry exists, it will
+     * be removed from the tree, the old tuple will be returned. Otherwise, null is returned.
+     *
+     * @param key The key for the entry we try to remove
+     * @return A Tuple<K, V> containing the removed entry, or null if it's not found.
      */
-    @Override
     public Tuple<K, V> delete( WriteTransaction transaction, K key ) throws IOException
     {
-        // Check that we have a TransactionManager
+        // Check that we have a Transaction
         if ( transaction == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
@@ -226,22 +222,34 @@ public class BTreeImpl<K, V> implements
             throw new IllegalArgumentException( "Key must not be null" );
         }
 
-        try
-        {
-            return processDelete( transaction, key );
-        }
-        catch ( IOException ioe )
+        DeleteResult<K, V> result = processDelete( transaction, key );
+        
+        // Check that we have found the element to delete
+        if ( result instanceof NotPresentResult )
         {
-            // We have had an exception, we must rollback the transaction
+            // We haven't found the element in the B-tree, just get out
+            // without updating the recordManager
+
             return null;
         }
+
+        // The element was found, and removed
+        AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
+
+        return deleteResult.getRemovedElement();
     }
 
 
     /**
-     * {@inheritDoc}
+     * Find a value in the tree, given its key. If the key is not found,
+     * it will throw a KeyNotFoundException. <br/>
+     * Note that we can get a null value stored, or many values.
+     *
+     * @param key The key we are looking at
+     * @return The found value, or null if the key is not present in the tree
+     * @throws KeyNotFoundException If the key is not found in the B-tree
+     * @throws IOException TODO
      */
-    @Override
     public V get( Transaction transaction, K key ) throws IOException, KeyNotFoundException
     {
         if ( transaction == null )
@@ -250,34 +258,8 @@ public class BTreeImpl<K, V> implements
         }
         else
         {
-            return getRootPage().get( key );
-        }
-    }
-
-
-    /**
-     * Initialize the BTree.
-     *
-     * @throws IOException If we get some exception while initializing the BTree
-     */
-    public void initCache()
-    {
-        // This is not a subBtree, we have to initialize the cache
-        if ( cacheSize < 1 )
-        {
-            cacheSize = DEFAULT_CACHE_SIZE;
+            return currentBtreeHeader.getRootPage().get( transaction, key );
         }
-
-        cache = new LRUMap( cacheSize );
-    }
-
-
-    /**
-     * Return the cache we use in this BTree
-     */
-    /* No qualifier */LRUMap getCache()
-    {
-        return cache;
     }
 
 
@@ -309,67 +291,22 @@ public class BTreeImpl<K, V> implements
 
 
     /**
-     *
-     * Deletes the given <key,value> pair if both key and value match. If the given value is null
-     * and there is no null value associated with the given key then the entry with the given key
-     * will be removed.
-     *
-     * @param key The key to be removed
-     * @param value The value to be removed (can be null, and when no null value exists the key will be removed irrespective of the value)
-     * @param revision The revision to be associated with this operation
-     * @return
-     * @throws IOException
-     */
-    @Override
-    public Tuple<K, V> delete( WriteTransaction transaction, K key, V value ) throws IOException
-    {
-        try
-        {
-            // 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( transaction, key, value );
-
-            // 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
-                // without updating the recordManager
-
-                return null;
-            }
-
-            // The element was found, and removed
-            AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
-
-            Tuple<K, V> tuple = deleteResult.getRemovedElement();
-
-            // If the B-tree is managed, we have to update the rootPage on disk
-            // Update the RecordManager header
-
-            // Return the value we have found if it was modified
-            return tuple;
-        }
-        catch ( IOException ioe )
-        {
-            // if we've got an error, we have to rollback
-            throw ioe;
-        }
-    }
-
-
-    /**
      * Insert the tuple into the B-tree rootPage, get back the new rootPage
      */
     private DeleteResult<K, V> processDelete( WriteTransaction transaction, K key ) throws IOException
     {
-        RecordManager recordManager = transaction.getRecordManager();
-        RecordManagerHeader recordManagerheader = transaction.getRecordManagerHeader();
+        // Get the current B-tree header, check if it's in the transaction's pages
+        BTreeHeader<K, V> btreeHeader = currentBtreeHeader;
+
+        // Get the rootPage
+        Page<K, V> rootPage = btreeHeader.getRootPage();
+
+        
         // Get the current B-tree header, and delete the value from it
-        BTreeHeader<K, V> btreeHeader = getBTreeHeader( getName() );
 
         // 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 = btreeHeader.getRootPage().delete( transaction, key );
+        DeleteResult<K, V> result = rootPage.delete( transaction, key, null, -1 );
 
         if ( result instanceof NotPresentResult )
         {
@@ -377,93 +314,64 @@ public class BTreeImpl<K, V> implements
             return result;
         }
 
+        AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V> ) result;
+
         // Create a new BTreeHeader
-        BTreeHeader<K, V> newBtreeHeader = btreeHeader.copy();
+        BTreeHeader<K, V> newBtreeHeader;
+        long revision = transaction.getRevision();
 
-        // Inject the old B-tree header into the pages to be freed
-        // if we are deleting an element from a management BTree
-        if ( ( btreeType == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btreeType == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+        // Create a new BTreeHeader
+        // If the current b-tree header has been modified, it will be in the WalObject map.
+        // Fetch it, or create a new version of it.
+        long btreeHeaderId = btreeHeader.getId();
+        
+        WALObject<?, ?> walObject = transaction.getWALObject( btreeHeaderId );
+        
+        if ( walObject != null )
         {
-            PageIO[] pageIos = recordManager.readPageIOs( recordManagerheader, btreeHeader.getOffset(), -1L );
-
-            for ( PageIO pageIo : pageIos )
-            {
-                recordManager.freedPages.add( pageIo );
-            }
+            newBtreeHeader = (BTreeHeader<K, V>)transaction.removeWALObject( btreeHeaderId );
+            newBtreeHeader.initId( transaction.getRecordManagerHeader() );
         }
-
-        // The element was found, and removed
-        AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V> ) result;
-
-        // This is a new root
-        Page<K, V> newRootPage = removeResult.getModifiedPage();
-
-        // Write the modified page on disk
-        // Note that we don't use the holder, the new root page will
-        // remain in memory.
-        writePage( transaction, newRootPage );
-
-        // Decrease the number of elements in the current tree
-        newBtreeHeader.decrementNbElems();
-        newBtreeHeader.setRootPage( newRootPage );
+        else
+        {
+            // Create a new BTreeHeader
+            newBtreeHeader = btreeHeader.copy( transaction.getRecordManagerHeader() );
+        }
+        
+        // Update the new B-tree header
         newBtreeHeader.setRevision( revision );
+        newBtreeHeader.setRootPage( removeResult.getModifiedPage() );
+        newBtreeHeader.decrementNbElems();
 
-        // Write down the data on disk
-        PageIO[] newBtreeHeaderPageIos = recordManager.writeBtreeHeader( this, newBtreeHeader, false );
-        long newBtreeHeaderOffset = newBtreeHeaderPageIos[0].getOffset();
+        // Inject the new btreeHeader into the created pages
+        transaction.addWALObject( newBtreeHeader );
 
-        // Update the B-tree of B-trees with this new offset, if we are not already doing so
-        switch ( btreeType )
+        // Store the new B-tree header into the btreeMap
+        currentBtreeHeader = newBtreeHeader;
+        
+        // And move the old B-tree header into the CopiedPages B-tree,
+        // if we are not processing the CopiedPages B-tree itself
+        if ( btreeHeader.isBTreeUser() )
         {
-            case PERSISTED:
-                // We have a new B-tree header to inject into the B-tree of btrees
-                recordManager.addInBtreeOfBtrees( transaction, getName(), revision, newBtreeHeaderOffset );
-
-                recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
-
-                // Store the new revision
-                storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
-
-                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;
+            transaction.addCopiedWALObject( btreeHeader );
+        }
+        else
+        {
+            // transaction.addFreePage( btreeHeader );
         }
 
-        // Return the value we have found if it was modified
-        return result;
+        return removeResult;
     }
 
 
     /**
-     * {@inheritDoc}
+     * Checks if the given key exists.
+     *
+     * @param key The key we are looking at
+     * @return true if the key is present, false otherwise
+     * @throws IOException If we have an error while trying to access the page
+     * @throws KeyNotFoundException If the key is not found in the B-tree
      */
-    @Override
     public boolean hasKey( Transaction transaction, K key ) throws IOException, KeyNotFoundException
     {
         if ( key == null )
@@ -477,7 +385,7 @@ public class BTreeImpl<K, V> implements
         }
         else
         {
-            return getRootPage().hasKey( key );
+            return getRootPage().hasKey( transaction, key );
         }
     }
 
@@ -495,9 +403,19 @@ public class BTreeImpl<K, V> implements
      * @param revision The revision to use
      * @return an instance of the InsertResult.
      */
-    @Override
     public InsertResult<K, V> insert( WriteTransaction transaction, K key, V value ) throws IOException
     {
+        // Check that we have a Transaction
+        if ( transaction == null )
+        {
+            throw new BTreeCreationException( "We don't have a transactionLManager" );
+        }
+
+        if ( key == null )
+        {
+            throw new IllegalArgumentException( "Key must not be null" );
+        }
+
         try
         {
             // Try to insert the new value in the tree at the right place,
@@ -532,15 +450,14 @@ public class BTreeImpl<K, V> implements
             
             WALObject<?, ?> walObject = transaction.getWALObject( btreeHeaderId );
             
-            if ( walObject != null )
+            if ( walObject == null )
             {
-                newBtreeHeader = (BTreeHeader<K, V>)transaction.removeWALObject( btreeHeaderId );
-                newBtreeHeader.initId( transaction.getRecordManagerHeader() );
+                // Create a new BTreeHeader
+                newBtreeHeader = btreeHeader.copy( transaction.getRecordManagerHeader() );
             }
             else
             {
-                // Create a new BTreeHeader
-                newBtreeHeader = btreeHeader.copy();
+                newBtreeHeader = ( BTreeHeader<K, V> ) walObject;
             }
             
             // Second case : the B-tree has been modified, and the old rootPage has not
@@ -552,24 +469,11 @@ public class BTreeImpl<K, V> implements
 
                 newRootPage = modifyResult.getModifiedPage();
 
-                // Increment the counter if we have inserted a new value
+                // Increment the counter if we have inserted a new value, instead of replacing a value
                 if ( modifyResult.getModifiedValue() == null )
                 {
                     newBtreeHeader.incrementNbElems();
                 }
-                
-                // Add the the old rootPage in the transaction copied pages,
-                // if we are not processing the CopiedPages B-tree
-                // In this case, we have to move the copied page into
-                // the free-pages list
-                if ( getType() != BTreeTypeEnum.COPIED_PAGES_BTREE )
-                {
-                    transaction.addCopiedWALObject( rootPage );
-                }
-                else
-                {
-                    // transaction.addFreePage( rootPage );
-                }
             }
             else
             {
@@ -580,12 +484,22 @@ public class BTreeImpl<K, V> implements
 
                 K pivot = splitResult.getPivot();
 
-                PageHolder<K, V> holderLeft = new PageHolder<>( this, splitResult.getLeftPage() );
-                PageHolder<K, V> holderRight = new PageHolder<>( this, splitResult.getRightPage() );
+                long leftPage = splitResult.getLeftPage().getOffset();
+                
+                if ( leftPage == BTreeConstants.NO_PAGE )
+                {
+                    leftPage = -splitResult.getLeftPage().getId();
+                }
+                
+                long rightPage = splitResult.getRightPage().getOffset();
+
+                if ( rightPage == BTreeConstants.NO_PAGE )
+                {
+                    rightPage = -splitResult.getRightPage().getId();
+                }
 
-                // Create the new rootPage if needed
-                newRootPage = new Node<>( this, revision, pivot, holderLeft, holderRight );
-                ( ( Node<K, V> ) newRootPage ).initId( transaction.getRecordManagerHeader() );
+                // Create the new rootPage with a new ID
+                newRootPage = transaction.newNode( btreeInfo, pivot, leftPage, rightPage );
 
                 if ( rootPage.getRevision() != revision )
                 {
@@ -596,23 +510,6 @@ public class BTreeImpl<K, V> implements
                 // Add the new root page in the transaction pages map
                 transaction.addWALObject( newRootPage );
                 
-                // We now have to remove the old root page from the list of new pages
-                // and also remove the old btree-header, as we have a new rootPage
-                transaction.removeWALObject( btreeHeaderId );
-                
-                // Add the the old rootPage in the transaction copied pages,
-                // if we are not processing the CopiedPages B-tree
-                // In this case, we have to move the copied page into
-                // the free-pages list
-                if ( getType() != BTreeTypeEnum.COPIED_PAGES_BTREE )
-                {
-                    transaction.addCopiedWALObject( rootPage );
-                }
-                else
-                {
-                    // transaction.addFreePage( rootPage );
-                }
-
                 // Always increment the counter : we have added a new value
                 newBtreeHeader.incrementNbElems();
             }
@@ -621,21 +518,11 @@ public class BTreeImpl<K, V> implements
             newBtreeHeader.setRootPage( newRootPage );
             newBtreeHeader.setRevision( revision );
             
-            // Inject the new btreeHeader into the created pages
-            transaction.addWALObject( newBtreeHeader );
-            
-            // And move the old B-tree header into the CopiedPages B-tree,
-            // if we are not processing the CopiedPages B-tree itself
-            if ( getType() != BTreeTypeEnum.COPIED_PAGES_BTREE )
-            {
-                transaction.addCopiedWALObject( btreeHeader );
-            }
-            else
-            {
-                // transaction.addFreePage( btreeHeader );
-            }
+            // Inject the new btreeHeader into the created pages, and remove the previous one
+            transaction.removeWALObject( btreeHeaderId );
+            transaction.updateWAL( btreeHeaderId, btreeHeader, newBtreeHeader );
 
-            // Get the new root page and make it the current root page
+            // Store the new B-tree header into the btreeMap
             currentBtreeHeader = newBtreeHeader;
             
             // Return the value we have found if it was modified
@@ -693,11 +580,11 @@ public class BTreeImpl<K, V> implements
      * Write a page either in the pending pages if the transaction is started,
      * or directly on disk.
      */
-    private PageHolder<K, V> writePage( WriteTransaction transaction, Page<K, V> modifiedPage ) throws IOException
+    private long writePage( WriteTransaction transaction, Page<K, V> modifiedPage ) throws IOException
     {
         transaction.addWALObject( modifiedPage );
 
-        return new PageHolder<>( this, modifiedPage );
+        return modifiedPage.getOffset();
     }
 
 
@@ -722,6 +609,15 @@ public class BTreeImpl<K, V> implements
     /**
      * @return the btreeInfoOffset
      */
+    public BTreeInfo<K, V> getBtreeInfo()
+    {
+        return btreeInfo;
+    }
+
+
+    /**
+     * @return the btreeInfoOffset
+     */
     public long getBtreeInfoOffset()
     {
         return btreeInfo.getOffset();
@@ -738,73 +634,66 @@ public class BTreeImpl<K, V> implements
 
 
     /**
-     * {@inheritDoc}
+     * @return the key comparator
      */
-    @Override
     public Comparator<K> getKeyComparator()
     {
-        return keySerializer.getComparator();
+        return btreeInfo.getKeySerializer().getComparator();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return the keySerializer
      */
-    @Override
     public ElementSerializer<K> getKeySerializer()
     {
-        return keySerializer;
+        return btreeInfo.getKeySerializer();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return the keySerializer FQCN
      */
-    @Override
     public String getKeySerializerFQCN()
     {
-        return keySerializerFQCN;
+        return btreeInfo.getKeySerializerFQCN();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @param keySerializer the Key serializer to set
      */
-    @Override
     public void setKeySerializer( ElementSerializer<K> keySerializer )
     {
-        this.keySerializer = keySerializer;
-        keySerializerFQCN = keySerializer.getClass().getName();
+        btreeInfo.setKeySerializer( keySerializer );
+        btreeInfo.setKeySerializerFQCN( keySerializer.getClass().getName() );
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return the name
      */
-    @Override
     public String getName()
     {
-        return name;
+        return btreeInfo.getName();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @param name the name to set
      */
-    @Override
     public void setName( String name )
     {
-        this.name = name;
+        btreeInfo.setName( name );
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return The current number of elements in the B-tree
      */
-    @Override
-    public long getNbElems( RecordManagerHeader recordManagerHeader )
+    public long getNbElems()
     {
-        return 0L;
+        return currentBtreeHeader.getNbElems();
     }
 
 
@@ -818,28 +707,33 @@ public class BTreeImpl<K, V> implements
 
 
     /**
-     * {@inheritDoc}
+     * @return the number of elements per page
      */
-    @Override
     public int getPageNbElem()
     {
-        return pageNbElem;
+        return btreeInfo.getPageNbElem();
     }
     
     
     /**
-     * {@inheritDoc}
+     * Set the maximum number of elements we can store in a page. This must be a
+     * number greater than 1, and a power of 2. The default page size is 16.
+     * <br/>
+     * If the provided size is below 2, we will default to DEFAULT_PAGE_NB_ELEM.<br/>
+     * If the provided size is not a power of 2, we will select the closest power of 2
+     * higher than the given number<br/>
+     *
+     * @param pageNbElem The number of element per page
      */
-    @Override
     public void setPageNbElem( int pageNbElem )
     {
         if ( pageNbElem <= 2 )
         {
-            this.pageNbElem = DEFAULT_PAGE_NBELEM;
+            btreeInfo.setPageNbElem( DEFAULT_PAGE_NBELEM );
         }
         else
         {
-            this.pageNbElem = getPowerOf2( pageNbElem );
+            btreeInfo.setPageNbElem( getPowerOf2( pageNbElem ) );
         }
     }
 
@@ -871,15 +765,17 @@ public class BTreeImpl<K, V> implements
 
     
     /**
-     * {@inheritDoc}
+     * @return The RecordManager instance
      */
-    @Override
     public RecordManager getRecordManager()
     {
         return recordManager;
     }
     
     
+    /**
+     * @param recordManager The RecordManager instance to set
+     */
     /* No qualifier */ void setRecordManager( RecordManager recordManager )
     {
         this.recordManager = recordManager;
@@ -887,16 +783,15 @@ public class BTreeImpl<K, V> implements
 
     
     /**
-     * {@inheritDoc}
-     */
-    @Override
+     * @return The RecordManagerHeader instance
+     *
     public RecordManagerHeader getRecordManagerHeader()
     {
         return recordManagerHeader;
     }
     
     
-    /* No qualifier */ void setRecordManagerHeader( RecordManagerHeader recordManagerHeader )
+    /* No qualifier * void setRecordManagerHeader( RecordManagerHeader recordManagerHeader )
     {
         this.recordManagerHeader = recordManagerHeader;
     }
@@ -905,9 +800,8 @@ public class BTreeImpl<K, V> implements
     /**
      * Get the current rootPage
      *
-     * @return The rootPage
+     * @return The current rootPage
      */
-    @Override
     public Page<K, V> getRootPage()
     {
         return currentBtreeHeader.getRootPage();
@@ -926,12 +820,11 @@ public class BTreeImpl<K, V> implements
 
 
     /**
-     * {@inheritDoc}
+     * @return the type
      */
-    @Override
     public BTreeTypeEnum getType()
     {
-        return btreeType;
+        return btreeInfo.getType();
     }
 
 
@@ -940,48 +833,55 @@ public class BTreeImpl<K, V> implements
      */
     public void setType( BTreeTypeEnum type )
     {
-        this.btreeType = type;
+        btreeInfo.setType( type );
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return the value comparator
      */
-    @Override
     public Comparator<V> getValueComparator()
     {
-        return valueSerializer.getComparator();
+        return btreeInfo.getValueSerializer().getComparator();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return the valueSerializer
      */
-    @Override
     public ElementSerializer<V> getValueSerializer()
     {
-        return valueSerializer;
+        return btreeInfo.getValueSerializer();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @return the valueSerializer FQCN
      */
-    @Override
     public String getValueSerializerFQCN()
     {
-        return valueSerializerFQCN;
+        return btreeInfo.getValueSerializerFQCN();
     }
 
 
     /**
-     * {@inheritDoc}
+     * @param valueSerializer the Value serializer to set
      */
-    @Override
     public void setValueSerializer( ElementSerializer<V> valueSerializer )
     {
-        this.valueSerializer = valueSerializer;
-        valueSerializerFQCN = valueSerializer.getClass().getName();
+        btreeInfo.setValueSerializer( valueSerializer );
+        btreeInfo.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     * @see java.lang.Object#hashCode()
+     *
+    @Override
+    public int hashCode()
+    {
+        return getName().hashCode();
     }
 
 
@@ -997,18 +897,23 @@ public class BTreeImpl<K, V> implements
         sb.append( "[" ).append( getName() ).append( "]" );
         sb.append( "( pageNbElem:" ).append( getPageNbElem() );
         
-        long nbElems = getBtreeHeader().getNbElems();
+        long nbElems = 0L;
+        
+        if ( currentBtreeHeader != null )
+        {
+            nbElems = currentBtreeHeader.getNbElems();
+        }
 
         sb.append( ", nbElements:" ).append( nbElems );
         sb.append( ", comparator:" );
 
-        if ( keySerializer.getComparator() == null )
+        if ( btreeInfo.getKeySerializer().getComparator() == null )
         {
             sb.append( "null" );
         }
         else
         {
-            sb.append( keySerializer.getComparator().getClass().getSimpleName() );
+            sb.append( btreeInfo.getKeySerializer().getComparator().getClass().getSimpleName() );
         }
 
         sb.append( ") : \n" );

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java Mon Oct  9 20:32:59 2017
@@ -109,12 +109,12 @@ public class BTreeBuilder<K, V>
         // remove null keys and values from the last leaf and resize
         Leaf<K, V> lastLeaf = ( Leaf<K, V> ) lstLeaves.get( lstLeaves.size() - 1 );
         
-        for ( int i = 0; i < lastLeaf.getNbPageElems(); i++ )
+        for ( int i = 0; i < lastLeaf.getPageNbElems(); i++ )
         {
             if ( lastLeaf.getKey( i ) == null )
             {
                 int n = i;
-                lastLeaf.setNbPageElems( n );
+                lastLeaf.setPageNbElems( n );
                 KeyHolder<K>[] keys = lastLeaf.getKeys();
 
                 lastLeaf.setKeys( ( KeyHolder[] ) Array.newInstance( KeyHolder.class, n ) );
@@ -135,13 +135,13 @@ public class BTreeBuilder<K, V>
         Page<K, V> rootPage = attachNodes( transaction, lstLeaves, btree );
 
         //System.out.println("built rootpage : " + rootPage);
-        ( ( BTreeImpl<K, V> ) btree ).setNbElems( totalTupleCount );
+        ( ( BTree<K, V> ) btree ).setNbElems( totalTupleCount );
 
         //rm.updateBtreeHeader( btree, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
 
         //rm.freePages( transaction, btree, btree.getRootPage( transaction ).getRevision(), Arrays.asList( btree.getRootPage( transaction ) ) );
 
-        ( ( BTreeImpl<K, V> ) btree ).setRootPage( rootPage );
+        ( ( BTree<K, V> ) btree ).setRootPage( rootPage );
 
         return btree;
     }
@@ -190,12 +190,12 @@ public class BTreeBuilder<K, V>
         // remove null keys and values from the last node and resize
         AbstractPage<K, V> lastNode = ( AbstractPage<K, V> ) lstNodes.get( lstNodes.size() - 1 );
 
-        for ( int j = 0; j < lastNode.getNbPageElems(); j++ )
+        for ( int j = 0; j < lastNode.getPageNbElems(); j++ )
         {
             if ( lastNode.getKey( j ) == null )
             {
                 int n = j;
-                lastNode.setNbPageElems( n );
+                lastNode.setPageNbElems( n );
                 KeyHolder<K>[] keys = lastNode.getKeys();
 
                 lastNode.setKeys( ( KeyHolder[] ) Array.newInstance( KeyHolder.class, n ) );

Added: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java?rev=1811602&view=auto
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java (added)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java Mon Oct  9 20:32:59 2017
@@ -0,0 +1,49 @@
+package org.apache.directory.mavibot.btree;
+
+public class BTreeConstants
+{
+    /** A constant for an offset on a non existing page */
+    public static final long NO_PAGE = -1L;
+
+    /** A constant for a no limit page IO fetch */
+    public static final long NO_LIMIT = -1L;
+
+    /** The number of bytes used to store the size of a page */
+    /* no qualifier*/ static final int PAGE_SIZE = 4;
+
+    /** The size of the link to next page */
+    /* no qualifier*/ static final int LINK_SIZE = 8;
+
+    /** Some constants */
+    /* no qualifier*/ static final int BYTE_SIZE = 1;
+    /* no qualifier */static final int INT_SIZE = 4;
+    /* no qualifier */static final int LONG_SIZE = 8;
+
+    /** The default page size */
+    public static final int DEFAULT_PAGE_SIZE = 512;
+
+    /** The minimal page size. Can't be below 64, as we have to store many thing sin the RMHeader */
+    /* no qualifier*/ static final int MIN_PAGE_SIZE = 64;
+
+    /** The default file name */
+    /* no qualifier*/ static final String DEFAULT_FILE_NAME = "mavibot.db";
+
+    /** A flag used by internal btrees */
+    public static final boolean INTERNAL_BTREE = true;
+
+    /** A flag used by internal btrees */
+    public static final boolean NORMAL_BTREE = false;
+
+    /** The B-tree of B-trees management btree name */
+    /* no qualifier */static final String BTREE_OF_BTREES_NAME = "_btree_of_btrees_";
+
+    /** The CopiedPages management btree name */
+    /* no qualifier */static final String COPIED_PAGE_BTREE_NAME = "_copiedPageBtree_";
+
+    /** A value stored into the transaction context for rollbacked transactions */
+    /* no qualifier*/ static final int ROLLBACKED_TXN = 0;
+
+    /** Hex chars */
+    /* no qualifier*/ static final byte[] HEX_CHAR = new byte[]
+        { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+}

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java Mon Oct  9 20:32:59 2017
@@ -57,7 +57,7 @@ public class BTreeFactory<K, V>
      */
     public static <K, V> BTree<K, V> createBTree()
     {
-        return new BTreeImpl<>();
+        return new BTree<>();
     }
 
 
@@ -69,8 +69,9 @@ public class BTreeFactory<K, V>
      */
     public static <K, V> BTree<K, V> createBTree( BTreeTypeEnum type )
     {
-        BTree<K, V> btree = new BTreeImpl<>();
-        ( ( BTreeImpl<K, V> ) btree ).setType( type );
+        BTree<K, V> btree = new BTree<>( );
+        btree.setBtreeInfo( new BTreeInfo<>() );
+        btree.setType( type );
 
         return btree;
     }
@@ -85,7 +86,7 @@ public class BTreeFactory<K, V>
      */
     public static <K, V> BTree<K, V> createBTree( Transaction transaction, BTreeConfiguration<K, V> configuration )
     {
-        return new BTreeImpl<>( transaction, configuration );
+        return new BTree<>( transaction, configuration );
     }
 
 
@@ -106,10 +107,9 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageNbElem( BTree.DEFAULT_PAGE_NBELEM );
-        configuration.setCacheSize( BTreeImpl.DEFAULT_CACHE_SIZE );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
-        return new BTreeImpl<>( transaction, configuration );
+        return new BTree<>( transaction, configuration );
     }
 
 
@@ -135,7 +135,7 @@ public class BTreeFactory<K, V>
         configuration.setCacheSize( cacheSize );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
-        return new BTreeImpl<>( transaction, configuration );
+        return new BTree<>( transaction, configuration );
     }
 
 
@@ -157,10 +157,9 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageNbElem( pageNbElem );
-        configuration.setCacheSize( BTreeImpl.DEFAULT_CACHE_SIZE );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
-        return new BTreeImpl<>( transaction, configuration );
+        return new BTree<>( transaction, configuration );
     }
 
 
@@ -186,7 +185,7 @@ public class BTreeFactory<K, V>
         configuration.setCacheSize( cacheSize );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
-        return new BTreeImpl<>( transaction, configuration );
+        return new BTree<>( transaction, configuration );
     }
 
 
@@ -196,7 +195,7 @@ public class BTreeFactory<K, V>
      * @param btree The btree to update
      * @param btreeHeaderOffset The offset
      */
-    public static <K, V> void setBtreeHeaderOffset( BTreeImpl<K, V> btree, long btreeHeaderOffset )
+    public static <K, V> void setBtreeHeaderOffset( BTree<K, V> btree, long btreeHeaderOffset )
     {
         btree.setBtreeHeaderOffset( btreeHeaderOffset );
     }
@@ -214,9 +213,9 @@ public class BTreeFactory<K, V>
      *
      * @return A Leaf instance
      */
-    /* no qualifier*/static <K, V> Page<K, V> createLeaf( BTree<K, V> btree, long revision, int nbElems )
+    /* no qualifier*/static <K, V> Page<K, V> createLeaf( BTreeInfo<K, V> btreeInfo, long revision, int nbElems )
     {
-        return new Leaf<>( btree, revision, nbElems );
+        return new Leaf<>( btreeInfo, revision, nbElems );
     }
 
 
@@ -228,10 +227,10 @@ public class BTreeFactory<K, V>
      * @param nbElems The number or elements in this node
      * @return A Node instance
      */
-    /* no qualifier*/static <K, V> Page<K, V> createNode( BTree<K, V> btree, long revision, int nbElems )
+    /* no qualifier*/static <K, V> Page<K, V> createNode( BTreeInfo<K, V> btreeInfo, long revision, int nbElems )
     {
         //System.out.println( "Creating a node with nbElems : " + nbElems );
-        return new Node<>( btree, revision, nbElems );
+        return new Node<>( btreeInfo, revision, nbElems );
     }
 
 
@@ -246,9 +245,9 @@ public class BTreeFactory<K, V>
      * @param pos The position in the keys array
      * @param key The key to inject
      */
-    /* no qualifier*/static <K, V> void setKey( BTree<K, V> btree, Page<K, V> page, int pos, K key )
+    /* no qualifier*/static <K, V> void setKey( BTreeInfo<K, V> btreeInfo, Page<K, V> page, int pos, K key )
     {
-        KeyHolder<K> keyHolder = new KeyHolder<>( btree.getKeySerializer(), key );
+        KeyHolder<K> keyHolder = new KeyHolder<>( btreeInfo.getKeySerializer(), key );
 
         ( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
     }
@@ -262,7 +261,7 @@ public class BTreeFactory<K, V>
      * @param pos The position in the values array
      * @param value the value to inject
      */
-    /* no qualifier*/static <K, V> void setValue( BTree<K, V> btree, Page<K, V> page, int pos, ValueHolder<V> value )
+    /* no qualifier*/static <K, V> void setValue( Page<K, V> page, int pos, ValueHolder<V> value )
     {
         ( ( Leaf<K, V> ) page ).setValue( pos, value );
     }
@@ -276,9 +275,9 @@ public class BTreeFactory<K, V>
      * @param pos The position in the values array
      * @param child the child page to inject
      */
-    /* no qualifier*/static <K, V> void setPage( BTree<K, V> btree, Page<K, V> page, int pos, Page<K, V> child )
+    /* no qualifier*/static <K, V> void setPage( BTreeInfo<K, V> btreeInfo, Page<K, V> page, int pos, Page<K, V> child )
     {
-        ( ( Node<K, V> ) page ).setValue( pos, new PageHolder<K, V>( btree, child ) );
+        ( ( Node<K, V> ) page ).setValue( pos, child.getOffset() );
     }
 
 
@@ -368,7 +367,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setRootPage( BTree<K, V> btree, Page<K, V> root )
     {
-        ( ( BTreeImpl<K, V> ) btree ).setRootPage( root );
+        ( ( BTree<K, V> ) btree ).setRootPage( root );
     }
 
 
@@ -380,7 +379,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier */static <K, V> Page<K, V> getRootPage( BTree<K, V> btree )
     {
-        return (( BTreeImpl<K, V> ) btree ).getRootPage();
+        return (( BTree<K, V> ) btree ).getRootPage();
     }
 
 
@@ -392,7 +391,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier */static <K, V> void setNbElems( BTree<K, V> btree, long nbElems )
     {
-        ( ( BTreeImpl<K, V> ) btree ).setNbElems( nbElems );
+        ( ( BTree<K, V> ) btree ).setNbElems( nbElems );
     }
 
 
@@ -404,7 +403,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setRevision( BTree<K, V> btree, long revision )
     {
-        ( ( BTreeImpl<K, V> ) btree ).setRevision( revision );
+        ( ( BTree<K, V> ) btree ).setRevision( revision );
     }
 
 
@@ -445,7 +444,7 @@ public class BTreeFactory<K, V>
     {
         LinkedList<ParentPos<K, V>> stack = new LinkedList<ParentPos<K, V>>();
 
-        ParentPos<K, V> last = new ParentPos<K, V>( btree.getRootPage(), btree.getRootPage().getNbPageElems() );
+        ParentPos<K, V> last = new ParentPos<>( btree.getRootPage(), btree.getRootPage().getPageNbElems() );
         stack.push( last );
 
         if ( btree.getRootPage().isLeaf() )
@@ -459,9 +458,10 @@ public class BTreeFactory<K, V>
 
             while ( true )
             {
-                Page<K, V> p = ( ( AbstractPage<K, V> ) node ).getPage( node.getNbPageElems() );
+                //Page<K, V> p = transaction.getPage( btreeInfo, ( ( AbstractPage )parentPos.page ).children[parentPos.pos] );
+                Page<K, V> p = ( ( AbstractPage<K, V> ) node ).getPage( node.getPageNbElems() );
 
-                last = new ParentPos<>( p, p.getNbPageElems() );
+                last = new ParentPos<>( p, p.getPageNbElems() );
                 stack.push( last );
 
                 if ( p.isLeaf() )
@@ -488,9 +488,9 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setRootPageOffset( BTree<K, V> btree, long rootPageOffset )
     {
-        if ( btree instanceof BTreeImpl )
+        if ( btree instanceof BTree )
         {
-            ( ( BTreeImpl<K, V> ) btree ).getBtreeHeader().setRootPageOffset( rootPageOffset );
+            btree.getBtreeHeader().setRootPageOffset( rootPageOffset );
         }
         else
         {
@@ -507,9 +507,9 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setRecordManager( BTree<K, V> btree, RecordManager recordManager )
     {
-        if ( btree instanceof BTreeImpl )
+        if ( btree instanceof BTree )
         {
-            ( ( BTreeImpl<K, V> ) btree ).setRecordManager( recordManager );
+            ( ( BTree<K, V> ) btree ).setRecordManager( recordManager );
         }
         else
         {
@@ -526,17 +526,10 @@ public class BTreeFactory<K, V>
      * @param pos The position of this key in the page
      * @param buffer The byte[] containing the serialized key
      */
-    /* no qualifier*/static <K, V> void setKey( BTree<K, V> btree, Page<K, V> page, int pos, byte[] buffer )
+    /* no qualifier*/static <K, V> void setKey( BTreeInfo<K, V> btreeInfo, Page<K, V> page, int pos, byte[] buffer )
     {
-        if ( btree instanceof BTreeImpl )
-        {
-            KeyHolder<K> keyHolder = new KeyHolder<K>( btree.getKeySerializer(), buffer );
-            ( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
-        }
-        else
-        {
-            throw new IllegalArgumentException( "The b-tree must be a PersistedBTree" );
-        }
+        KeyHolder<K> keyHolder = new KeyHolder<>( btreeInfo.getKeySerializer(), buffer );
+        ( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
     }
 
 
@@ -548,7 +541,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> LinkedList<ParentPos<K, V>> getPathToLeftMostLeaf( BTree<K, V> btree )
     {
-        if ( btree instanceof BTreeImpl )
+        if ( btree instanceof BTree )
         {
             LinkedList<ParentPos<K, V>> stack = new LinkedList<ParentPos<K, V>>();
 

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java Mon Oct  9 20:32:59 2017
@@ -54,9 +54,6 @@ import java.util.concurrent.atomic.Atomi
  */
 /* No qualifier*/class BTreeHeader<K, V> extends AbstractWALObject<K, V> implements Cloneable
 {
-    /** The current revision */
-    private long revision = 0L;
-
     /** The number of elements in this B-tree */
     private long nbElems = 0L;
 
@@ -71,9 +68,9 @@ import java.util.concurrent.atomic.Atomi
     /**
      * Creates a BTreeHeader instance
      */
-    public BTreeHeader()
+    public BTreeHeader( BTreeInfo<K, V> btreeInfo )
     {
-        super();
+        super( btreeInfo );
     }
 
 
@@ -82,7 +79,7 @@ import java.util.concurrent.atomic.Atomi
      */
     public long getBTreeInfoOffset()
     {
-        return ( ( BTreeImpl<K, V> ) btree ).getBtreeInfoOffset();
+        return btreeInfo.getOffset();
     }
 
 
@@ -110,7 +107,7 @@ import java.util.concurrent.atomic.Atomi
      * Copy the current B-tree header and return the copy
      * @return The copied B-tree header
      */
-    /* no qualifier */BTreeHeader<K, V> copy()
+    /* no qualifier */BTreeHeader<K, V> copy( RecordManagerHeader recordManagerHeader )
     {
         BTreeHeader<K, V> copy = clone();
 
@@ -119,7 +116,7 @@ import java.util.concurrent.atomic.Atomi
         copy.offset = -1L;
         copy.nbUsers.set( 0 );
         copy.pageIOs = null;
-        copy.id = id;
+        copy.id = recordManagerHeader.idCounter++;
 
         return copy;
     }
@@ -136,22 +133,12 @@ import java.util.concurrent.atomic.Atomi
         }
         else
         {
-            return RecordManager.NO_PAGE;
+            return BTreeConstants.NO_PAGE;
         }
     }
 
 
     /**
-     * @return the revision
-     */
-    @Override
-    public long getRevision()
-    {
-        return revision;
-    }
-
-
-    /**
      * Set the new revision
      * 
      * @param revision the revision to set
@@ -245,30 +232,28 @@ import java.util.concurrent.atomic.Atomi
     {
         nbUsers.decrementAndGet();
     }
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getName()
-    {
-        return btree.getName();
-    }
 
 
     /**
+     * Serialize a BTreeHeader. It will contain the following data :<br/>
+     * <ul>
+     *   <li>the Page ID : a long</li>
+     *   <li>the revision : a long</li>
+     *   <li>the number of elements in the B-tree : a long</li>
+     *   <li>the root page offset : a long</li>
+     *   <li>the B-tree info page offset : a long</li>
+     * </ul>
      * {@inheritDoc}
      */
     @Override
     public PageIO[] serialize( WriteTransaction transaction ) throws IOException
     {
         int bufferSize =
-            RecordManager.LONG_SIZE + // The page ID
-                RecordManager.LONG_SIZE + // The revision
-                RecordManager.LONG_SIZE + // the number of element
-                RecordManager.LONG_SIZE + // The root page offset
-                RecordManager.LONG_SIZE; // The B-tree info page offset
+            BTreeConstants.LONG_SIZE + // The page ID
+                BTreeConstants.LONG_SIZE + // The revision
+                BTreeConstants.LONG_SIZE + // the number of element
+                BTreeConstants.LONG_SIZE + // The root page offset
+                BTreeConstants.LONG_SIZE; // The B-tree info page offset
         
         RecordManager recordManager = transaction.getRecordManager();
         RecordManagerHeader recordManagerHeader = transaction.getRecordManagerHeader();
@@ -302,33 +287,29 @@ import java.util.concurrent.atomic.Atomi
         position = recordManager.store( recordManagerHeader, position, getRootPageOffset(), pageIOs );
 
         // The B-tree info page offset
-        recordManager.store( recordManagerHeader, position, ( ( BTreeImpl<K, V> ) btree ).getBtreeInfoOffset(), pageIOs );
+        recordManager.store( recordManagerHeader, position, btreeInfo.getOffset(), pageIOs );
+
+        offset = pageIOs[0].getOffset();
 
-        // And flush the pages to disk now
         /*
-        LOG.debug( "Flushing the newly managed '{}' btree header", btree.getName() );
+        LOG.debug( "Serializing the new '{}' btree header", btree.getName() );
 
         if ( LOG_PAGES.isDebugEnabled() )
         {
             LOG_PAGES.debug( "Writing BTreeHeader revision {} for {}", btreeHeader.getRevision(), btree.getName() );
             StringBuilder sb = new StringBuilder();
 
-            sb.append( "Offset : " ).append( Long.toHexString( btreeHeaderOffset ) ).append( "\n" );
-            sb.append( "    Revision : " ).append( btreeHeader.getRevision() ).append( "\n" );
-            sb.append( "    NbElems  : " ).append( btreeHeader.getNbElems() ).append( "\n" );
-            sb.append( "    RootPage : 0x" ).append( Long.toHexString( btreeHeader.getRootPageOffset() ) )
-                .append( "\n" );
-            sb.append( "    Info     : 0x" )
-                .append( Long.toHexString( ( ( PersistedBTree<K, V> ) btree ).getBtreeInfoOffset() ) ).append( "\n" );
+            sb.append( "Offset : " ).append( Long.toHexString( btreeInfo.getOffset() ) ).append( "\n" );
+            sb.append( "    ID       : " ).append( id ).append( "\n" );
+            sb.append( "    Revision : " ).append( getRevision() ).append( "\n" );
+            sb.append( "    NbElems  : " ).append( getNbElems() ).append( "\n" );
+            sb.append( "    RootPage : 0x" ).append( Long.toHexString( getRootPageOffset() ) ).append( "\n" );
+            sb.append( "    Info     : 0x" ).append( Long.toHexString( btreeInfo.getOffset() ) ).append( "\n" );
 
-            LOG_PAGES.debug( "Btree Header[{}]\n{}", btreeHeader.getRevision(), sb.toString() );
+            LOG_PAGES.debug( "Btree Header[{}]\n{}", getRevision(), sb.toString() );
         }
         */
 
-        //recordManager.storePages( btreeHeaderPageIos );
-
-        offset = pageIOs[0].getOffset();
-
         return pageIOs;
     }
 
@@ -343,7 +324,7 @@ import java.util.concurrent.atomic.Atomi
         
         sb.append( "{Header(" ).append( id ).append( ")@" );
         
-        if ( offset == RecordManager.NO_PAGE )
+        if ( offset == BTreeConstants.NO_PAGE )
         {
             sb.append( "---" );
         }
@@ -371,13 +352,13 @@ import java.util.concurrent.atomic.Atomi
         sb.append( "B-treeHeader " );
         sb.append( ", offset[0x" ).append( Long.toHexString( offset ) ).append( "]" );
         sb.append( ", name[" );
-        sb.append( btree.getName() );
+        sb.append( getName() );
         sb.append( ':' );
         sb.append( revision );
         sb.append( "]" );
         sb.append( ", revision[" ).append( revision ).append( "]" );
         sb.append( ", btreeInfoOffset[0x" )
-            .append( Long.toHexString( ( ( BTreeImpl<K, V> ) btree ).getBtreeInfoOffset() ) ).append( "]" );
+            .append( Long.toHexString( btreeInfo.getOffset() ) ).append( "]" );
         sb.append( ", rootPageOffset[0x" ).append( Long.toHexString( getRootPageOffset() ) ).append( "]" );
         sb.append( ", nbElems[" ).append( nbElems ).append( "]" );
         sb.append( ", ID[" ).append( id ).append( "]" );