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 2015/11/02 00:01:01 UTC

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

Author: elecharny
Date: Sun Nov  1 23:01:00 2015
New Revision: 1711861

URL: http://svn.apache.org/viewvc?rev=1711861&view=rev
Log:
Huge modifications :
o duplicate values are not anymore supported
o inMemory btrees have been removed
o the txn context has been added
o complete review of teh way we write pages on disk (it's now done only when the txn is committed)
WARNING : This is not a functionnal branch, tests are failing, and the txn support os far from being completed. This code is committed in order to be visible to the communit, this is still a WIP

Added:
    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/TransactionContext.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/exception/CursorException.java
Removed:
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTreeBuilder.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTreeConfiguration.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryValueHolder.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeBuilderTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeConfigurationTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeDuplicateKeyTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeFlushTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBTreeTestOps.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryBulkDataSorterTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/InMemoryLeafTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedInMemoryBtreeTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeDuplicateKeyTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedSubBtreeKeyCursorTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java
Modified:
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.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/AbstractValueHolder.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.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/BTreeTypeEnum.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/EmptyTupleCursor.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/Page.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/ParentPos.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTree.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedBTreeConfiguration.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedLeaf.java
    directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PersistedValueHolder.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/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/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
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/PersistedBTreeBrowseTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java
    directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java?rev=1711861&r1=1711860&r2=1711861&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractBTree.java Sun Nov  1 23:01:00 2015
@@ -30,7 +30,7 @@ import java.util.concurrent.atomic.Atomi
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.directory.mavibot.btree.exception.BTreeCreationException;
-import org.apache.directory.mavibot.btree.exception.DuplicateValueNotAllowedException;
+import org.apache.directory.mavibot.btree.exception.CursorException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
 
@@ -64,9 +64,6 @@ import org.apache.directory.mavibot.btre
     /** The size of the buffer used to write data in disk */
     protected int writeBufferSize;
 
-    /** Flag to enable duplicate key support */
-    protected boolean allowDuplicates;
-
     /** The number of elements in a page for this B-tree */
     protected int pageSize;
 
@@ -78,6 +75,9 @@ import org.apache.directory.mavibot.btre
 
     /** The FQCN of the Value serializer */
     protected String valueSerializerFQCN;
+    
+    /** The internal recordManager */
+    protected RecordManager recordManager;
 
     /** The thread responsible for the cleanup of timed out reads */
     protected Thread readTransactionsThread;
@@ -94,9 +94,6 @@ import org.apache.directory.mavibot.btre
     /** The current revision */
     protected AtomicLong currentRevision = new AtomicLong( 0L );
 
-    /** The TransactionManager used for this BTree */
-    protected TransactionManager transactionManager;
-
     /** The size of the stack to use to manage tree searches */
     private final static int MAX_STACK_DEPTH = 32;
 
@@ -122,10 +119,10 @@ import org.apache.directory.mavibot.btre
     /**
      * {@inheritDoc}
      */
-    public TupleCursor<K, V> browse() throws IOException, KeyNotFoundException
+    public TupleCursor<K, V> browse() throws IOException, KeyNotFoundException, CursorException
     {
-        // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        // Check that we have a recordManager
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -156,7 +153,7 @@ import org.apache.directory.mavibot.btre
     public TupleCursor<K, V> browse( long revision ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -185,7 +182,7 @@ import org.apache.directory.mavibot.btre
     public TupleCursor<K, V> browseFrom( K key ) throws IOException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -213,7 +210,7 @@ import org.apache.directory.mavibot.btre
     public TupleCursor<K, V> browseFrom( long revision, K key ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -242,7 +239,7 @@ import org.apache.directory.mavibot.btre
     public boolean contains( K key, V value ) throws IOException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -277,7 +274,7 @@ import org.apache.directory.mavibot.btre
     public boolean contains( long revision, K key, V value ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -309,7 +306,7 @@ import org.apache.directory.mavibot.btre
     public Tuple<K, V> delete( K key ) throws IOException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -320,21 +317,21 @@ import org.apache.directory.mavibot.btre
         }
 
         // Take the lock if it's not already taken by another thread
-        transactionManager.beginTransaction();
+        recordManager.beginTransaction();
 
         try
         {
             Tuple<K, V> deleted = delete( key, currentRevision.get() + 1 );
 
             // Commit now
-            transactionManager.commit();
+            recordManager.commit();
 
             return deleted;
         }
         catch ( IOException ioe )
         {
             // We have had an exception, we must rollback the transaction
-            transactionManager.rollback();
+            recordManager.rollback();
 
             return null;
         }
@@ -347,7 +344,7 @@ import org.apache.directory.mavibot.btre
     public Tuple<K, V> delete( K key, V value ) throws IOException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -362,19 +359,19 @@ import org.apache.directory.mavibot.btre
             throw new IllegalArgumentException( "Value must not be null" );
         }
 
-        transactionManager.beginTransaction();
+        recordManager.beginTransaction();
 
         try
         {
             Tuple<K, V> deleted = delete( key, value, currentRevision.get() + 1 );
 
-            transactionManager.commit();
+            recordManager.commit();
 
             return deleted;
         }
         catch ( IOException ioe )
         {
-            transactionManager.rollback();
+            recordManager.rollback();
 
             throw ioe;
         }
@@ -402,12 +399,7 @@ import org.apache.directory.mavibot.btre
      */
     public V insert( K key, V value ) throws IOException
     {
-        // Check that we have a TransactionManager
-        if ( transactionManager == null )
-        {
-            throw new BTreeCreationException( "We don't have a transactionLManager" );
-        }
-
+        // First, check if we have started a transaction
         V existingValue = null;
 
         if ( key == null )
@@ -415,13 +407,6 @@ import org.apache.directory.mavibot.btre
             throw new IllegalArgumentException( "Key must not be null" );
         }
 
-        // Take the lock if it's not already taken by another thread and if we 
-        // aren't on a sub-btree
-        if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
-        {
-            transactionManager.beginTransaction();
-        }
-
         try
         {
             InsertResult<K, V> result = insert( key, value, -1L );
@@ -435,37 +420,12 @@ import org.apache.directory.mavibot.btre
                 existingValue = ( ( ModifyResult<K, V> ) result ).getModifiedValue();
             }
 
-            // Commit now if it's not a sub-btree
-            if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
-            {
-                //FIXME when result type is ExistsResult then we should avoid writing the headers
-                transactionManager.commit();
-            }
-
             return existingValue;
         }
         catch ( IOException ioe )
         {
-            // We have had an exception, we must rollback the transaction
-            // if it's not a sub-btree
-            if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
-            {
-                transactionManager.rollback();
-            }
-
             return null;
         }
-        catch ( DuplicateValueNotAllowedException e )
-        {
-            // We have had an exception, we must rollback the transaction
-            // if it's not a sub-btree
-            if ( btreeType != BTreeTypeEnum.PERSISTED_SUB )
-            {
-                transactionManager.rollback();
-            }
-
-            throw e;
-        }
     }
 
 
@@ -490,7 +450,7 @@ import org.apache.directory.mavibot.btre
     public V get( K key ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -521,7 +481,7 @@ import org.apache.directory.mavibot.btre
     public V get( long revision, K key ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -564,7 +524,7 @@ import org.apache.directory.mavibot.btre
     public ValueCursor<V> getValues( K key ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -595,7 +555,7 @@ import org.apache.directory.mavibot.btre
     public boolean hasKey( K key ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -631,7 +591,7 @@ import org.apache.directory.mavibot.btre
     public boolean hasKey( long revision, K key ) throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -723,7 +683,7 @@ import org.apache.directory.mavibot.btre
     public long getRevision()
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -753,7 +713,7 @@ import org.apache.directory.mavibot.btre
      */
     /* no qualifier */void setRevision( long revision )
     {
-        transactionManager.getBTreeHeader( getName() ).setRevision( revision );
+        recordManager.getBTreeHeader( getName() ).setRevision( revision );
     }
 
 
@@ -776,10 +736,7 @@ import org.apache.directory.mavibot.btre
         currentBtreeHeader = btreeHeader;
 
         // And update the newBTreeHeaders map
-        if ( btreeHeader.getBtree().getType() != BTreeTypeEnum.PERSISTED_SUB )
-        {
-            transactionManager.updateNewBTreeHeaders( btreeHeader );
-        }
+        recordManager.updateNewBTreeHeaders( btreeHeader );
     }
 
 
@@ -799,10 +756,7 @@ import org.apache.directory.mavibot.btre
         currentBtreeHeader = btreeHeader;
 
         // And update the newBTreeHeaders map
-        if ( btreeHeader.getBtree().getType() != BTreeTypeEnum.PERSISTED_SUB )
-        {
-            transactionManager.updateNewBTreeHeaders( btreeHeader );
-        }
+        recordManager.updateNewBTreeHeaders( btreeHeader );
     }
 
 
@@ -830,7 +784,7 @@ import org.apache.directory.mavibot.btre
     public long getNbElems()
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a transactionLManager" );
         }
@@ -860,7 +814,7 @@ import org.apache.directory.mavibot.btre
      */
     /* no qualifier */void setNbElems( long nbElems )
     {
-        transactionManager.getBTreeHeader( getName() ).setNbElems( nbElems );
+        recordManager.getBTreeHeader( getName() ).setNbElems( nbElems );
     }
 
 
@@ -946,24 +900,6 @@ import org.apache.directory.mavibot.btre
     /**
      * {@inheritDoc}
      */
-    public boolean isAllowDuplicates()
-    {
-        return allowDuplicates;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setAllowDuplicates( boolean allowDuplicates )
-    {
-        this.allowDuplicates = allowDuplicates;
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
     public BTreeTypeEnum getType()
     {
         return btreeType;
@@ -1020,7 +956,7 @@ import org.apache.directory.mavibot.btre
     public KeyCursor<K> browseKeys() throws IOException, KeyNotFoundException
     {
         // Check that we have a TransactionManager
-        if ( transactionManager == null )
+        if ( recordManager == null )
         {
             throw new BTreeCreationException( "We don't have a Transaction Manager" );
         }

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=1711861&r1=1711860&r2=1711861&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 Sun Nov  1 23:01:00 2015
@@ -36,7 +36,7 @@ import org.apache.directory.mavibot.btre
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-/* No qualifier*/abstract class AbstractPage<K, V> implements Page<K, V>
+/* No qualifier*/abstract class AbstractPage<K, V> implements Page<K, V>, WALObject
 {
     /** Parent B+Tree. */
     protected transient BTree<K, V> btree;
@@ -58,6 +58,8 @@ import org.apache.directory.mavibot.btre
 
     /** The last {@link PageIO} storing the serialized Page on disk */
     protected long lastOffset = -1L;
+    
+    private long id;
 
 
     /**
@@ -654,6 +656,27 @@ import org.apache.directory.mavibot.btre
     }
 
 
+    @Override
+    public long getId()
+    {
+        return id;
+    }
+
+
+    @Override
+    public void setId( long id )
+    {
+        this.id = id;
+    }
+
+
+    @Override
+    public PageIO[] serialize() throws IOException
+    {
+        return null;
+    }
+
+
     /**
      * {@inheritDoc}
      */

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java?rev=1711861&r1=1711860&r2=1711861&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractValueHolder.java Sun Nov  1 23:01:00 2015
@@ -20,47 +20,25 @@
 package org.apache.directory.mavibot.btree;
 
 
-import java.io.IOException;
-import java.lang.reflect.Array;
 import java.util.Comparator;
-import java.util.Iterator;
 
-import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
 
 
 /**
- * A holder to store the Values
+ * A holder to store the Value
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @param <V> The value type
  */
 /* No qualifier*/abstract class AbstractValueHolder<V> implements ValueHolder<V>
 {
-    /** The BTree storing multiple value, if we have more than one value */
-    protected BTree<V, V> valueBtree;
-
     /** The array storing from 1 to N values */
-    protected V[] valueArray;
+    protected V value;
 
     /** The Value serializer */
     protected ElementSerializer<V> valueSerializer;
 
-    /** The configuration for the array <-> BTree switch. Default to 1 */
-    protected int valueThresholdUp = 1;
-    protected int valueThresholdLow = 1;
-
-    protected int nbArrayElems;
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isSubBtree()
-    {
-        return valueBtree != null;
-    }
-
 
     /**
      * Create a clone of this instance
@@ -74,368 +52,23 @@ import org.apache.directory.mavibot.btre
 
 
     /**
-     * @return a cursor on top of the values
-     */
-    public ValueCursor<V> getCursor()
-    {
-        if ( valueBtree != null )
-        {
-            return new ValueBTreeCursor<V>( valueBtree );
-        }
-        else
-        {
-            return new ValueArrayCursor<V>( valueArray );
-        }
-    }
-
-
-    /**
-     * Find the position of a given value in the array, or the position where we
-     * would insert the element (in this case, the position will be negative).
-     * As we use a 0-based array, the negative position for 0 is -1.
-     * -1 means the element can be added in position 0
-     * -2 means the element can be added in position 1
-     * ... 
-     */
-    private int findPos( V value )
-    {
-        if ( valueArray.length == 0 )
-        {
-            return -1;
-        }
-
-        // Do a search using dichotomy
-        int pivot = valueArray.length / 2;
-        int low = 0;
-        int high = valueArray.length - 1;
-        Comparator<V> comparator = valueSerializer.getComparator();
-
-        while ( high > low )
-        {
-            switch ( high - low )
-            {
-                case 1:
-                    // We have 2 elements
-                    int result = comparator.compare( value, valueArray[pivot] );
-
-                    if ( result == 0 )
-                    {
-                        return pivot;
-                    }
-
-                    if ( result < 0 )
-                    {
-                        if ( pivot == low )
-                        {
-                            return -( low + 1 );
-                        }
-                        else
-                        {
-                            result = comparator.compare( value, valueArray[low] );
-
-                            if ( result == 0 )
-                            {
-                                return low;
-                            }
-
-                            if ( result < 0 )
-                            {
-                                return -( low + 1 );
-                            }
-                            else
-                            {
-                                return -( low + 2 );
-                            }
-                        }
-                    }
-                    else
-                    {
-                        if ( pivot == high )
-                        {
-                            return -( high + 2 );
-                        }
-                        else
-                        {
-                            result = comparator.compare( value, valueArray[high] );
-
-                            if ( result == 0 )
-                            {
-                                return high;
-                            }
-
-                            if ( result < 0 )
-                            {
-                                return -( high + 1 );
-                            }
-                            else
-                            {
-                                return -( high + 2 );
-                            }
-                        }
-                    }
-
-                default:
-                    // We have 3 elements
-                    result = comparator.compare( value, valueArray[pivot] );
-
-                    if ( result == 0 )
-                    {
-                        return pivot;
-                    }
-
-                    if ( result < 0 )
-                    {
-                        high = pivot - 1;
-                    }
-                    else
-                    {
-                        low = pivot + 1;
-                    }
-
-                    pivot = ( high + low ) / 2;
-
-                    continue;
-            }
-        }
-
-        int result = comparator.compare( value, valueArray[pivot] );
-
-        if ( result == 0 )
-        {
-            return pivot;
-        }
-
-        if ( result < 0 )
-        {
-            return -( pivot + 1 );
-        }
-        else
-        {
-            return -( pivot + 2 );
-        }
-    }
-
-
-    /**
-     * Check if the array of values contains a given value
-     */
-    private boolean arrayContains( V value )
-    {
-        if ( valueArray.length == 0 )
-        {
-            return false;
-        }
-
-        // Do a search using dichotomy
-        return findPos( value ) >= 0;
-    }
-
-
-    /**
-     * Check if the subBtree contains a given value
-     */
-    protected boolean btreeContains( V value )
-    {
-        try
-        {
-            return valueBtree.hasKey( value );
-        }
-        catch ( IOException e )
-        {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-            return false;
-        }
-        catch ( KeyNotFoundException knfe )
-        {
-            knfe.printStackTrace();
-            return false;
-        }
-    }
-
-
-    /**
      * {@inheritDoc}
      */
     public boolean contains( V checkedValue )
     {
-        if ( valueArray == null )
-        {
-            return btreeContains( checkedValue );
-        }
-        else
-        {
-            return arrayContains( checkedValue );
-        }
-    }
-
-
-    /**
-     * Create a new Sub-BTree to store the values.
-     */
-    protected abstract void createSubTree();
-
-
-    /**
-     * Manage a new Sub-BTree .
-     */
-    protected abstract void manageSubTree();
-
-
-    /**
-     * Add the value in an array
-     */
-    private void addInArray( final V value )
-    {
-        // We have to check that we have reached the threshold or not
-        if ( size() >= valueThresholdUp )
-        {
-            // Ok, transform the array into a btree
-            createSubTree();
-
-            Iterator<Tuple<V, V>> valueIterator = new Iterator<Tuple<V, V>>()
-            {
-                int pos = 0;
-
-
-                @Override
-                public Tuple<V, V> next()
-                {
-                    // We can now return the found value
-                    if ( pos == valueArray.length )
-                    {
-                        // Special case : deal with the added value
-                        pos++;
-
-                        return new Tuple<V, V>( value, value );
-                    }
-                    else
-                    {
-                        V oldValue = valueArray[pos];
-                        pos++;
-
-                        return new Tuple<V, V>( oldValue, oldValue );
-                    }
-                }
-
-
-                @Override
-                public boolean hasNext()
-                {
-                    // Check that we have at least one element to read
-                    return pos < valueArray.length + 1;
-                }
-
-
-                @Override
-                public void remove()
-                {
-                }
-
-            };
-
-            try
-            {
-                BulkLoader.load( valueBtree, valueIterator, valueArray.length );
-            }
-            catch ( IOException e )
-            {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-
-            manageSubTree();
-
-            // And make the valueArray to be null now
-            valueArray = null;
-        }
-        else
-        {
-            // Create the array if it's null
-            if ( valueArray == null )
-            {
-                valueArray = ( V[] ) Array.newInstance( valueSerializer.getType(), 1 );
-                nbArrayElems = 1;
-                valueArray[0] = value;
-            }
-            else
-            {
-                // check that the value is not already present in the ValueHolder
-                int pos = findPos( value );
-
-                if ( pos >= 0 )
-                {
-                    // The value exists : nothing to do
-                    return;
-                }
-
-                // Ok, we just have to insert the new element at the right position
-                // We transform the position to a positive value 
-                pos = -( pos + 1 );
-                // First, copy the array
-                V[] newValueArray = ( V[] ) Array.newInstance( valueSerializer.getType(), valueArray.length + 1 );
-
-                System.arraycopy( valueArray, 0, newValueArray, 0, pos );
-                newValueArray[pos] = value;
-                System.arraycopy( valueArray, pos, newValueArray, pos + 1, valueArray.length - pos );
-
-                // And switch the arrays
-                valueArray = newValueArray;
-            }
-        }
-    }
-
+        Comparator<V> comparator = valueSerializer.getComparator();
 
-    /**
-     * Add the value in the subBTree
-     */
-    private void addInBtree( V value )
-    {
-        try
-        {
-            valueBtree.insert( value, null );
-        }
-        catch ( IOException e )
-        {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
+        int result = comparator.compare( value,  checkedValue );
+        
+        return result == 0;
     }
 
 
     /**
      * {@inheritDoc}
      */
-    public void add( V value )
+    public void set( V value )
     {
-        if ( valueBtree == null )
-        {
-            addInArray( value );
-        }
-        else
-        {
-            addInBtree( value );
-        }
+        this.value = value;
     }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public V replaceValueArray( V newValue )
-    {
-        if ( isSubBtree() )
-        {
-            throw new IllegalStateException( "method is not applicable for the duplicate B-Trees" );
-        }
-
-        V tmp = valueArray[0];
-
-        nbArrayElems = 1;
-        valueArray[0] = newValue;
-
-        return tmp;
-    }
-
 }

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java?rev=1711861&r1=1711860&r2=1711861&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java Sun Nov  1 23:01:00 2015
@@ -23,6 +23,7 @@ package org.apache.directory.mavibot.btr
 import java.io.IOException;
 import java.util.Comparator;
 
+import org.apache.directory.mavibot.btree.exception.CursorException;
 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
 
@@ -218,7 +219,7 @@ public interface BTree<K, V>
      * @return A cursor on the B-tree
      * @throws IOException
      */
-    TupleCursor<K, V> browse() throws IOException, KeyNotFoundException;
+    TupleCursor<K, V> browse() throws IOException, KeyNotFoundException, CursorException;
 
 
     /**
@@ -369,19 +370,13 @@ public interface BTree<K, V>
 
 
     /**
-     * @return true if this B-tree allow duplicate values
-     */
-    boolean isAllowDuplicates();
-
-
-    /**
-     * @param allowDuplicates True if the B-tree will allow duplicate values
-     */
-    void setAllowDuplicates( boolean allowDuplicates );
-
-
-    /**
      * @return the type
      */
     BTreeTypeEnum getType();
+    
+    
+    /**
+     * @return The recordManager reference
+     */
+    RecordManager getRecordManager();
 }

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=1711861&r1=1711860&r2=1711861&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 Sun Nov  1 23:01:00 2015
@@ -113,7 +113,6 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageSize( BTree.DEFAULT_PAGE_SIZE );
-        configuration.setAllowDuplicates( BTree.FORBID_DUPLICATES );
         configuration.setCacheSize( PersistedBTree.DEFAULT_CACHE_SIZE );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
@@ -142,7 +141,6 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageSize( BTree.DEFAULT_PAGE_SIZE );
-        configuration.setAllowDuplicates( allowDuplicates );
         configuration.setCacheSize( PersistedBTree.DEFAULT_CACHE_SIZE );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
@@ -172,7 +170,6 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageSize( BTree.DEFAULT_PAGE_SIZE );
-        configuration.setAllowDuplicates( allowDuplicates );
         configuration.setCacheSize( cacheSize );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
@@ -201,7 +198,6 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageSize( pageSize );
-        configuration.setAllowDuplicates( BTree.FORBID_DUPLICATES );
         configuration.setCacheSize( PersistedBTree.DEFAULT_CACHE_SIZE );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
@@ -231,7 +227,6 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageSize( pageSize );
-        configuration.setAllowDuplicates( allowDuplicates );
         configuration.setCacheSize( PersistedBTree.DEFAULT_CACHE_SIZE );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
@@ -262,7 +257,6 @@ public class BTreeFactory<K, V>
         configuration.setKeySerializer( keySerializer );
         configuration.setValueSerializer( valueSerializer );
         configuration.setPageSize( pageSize );
-        configuration.setAllowDuplicates( allowDuplicates );
         configuration.setCacheSize( cacheSize );
         configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
 
@@ -273,212 +267,6 @@ public class BTreeFactory<K, V>
 
 
     //--------------------------------------------------------------------------------------------
-    // Create in-memory B-trees
-    //--------------------------------------------------------------------------------------------
-    /**
-     * Creates a new in-memory B-tree, with no initialization.
-     *
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree()
-    {
-        BTree<K, V> btree = new InMemoryBTree<K, V>();
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the BTreeConfiguration to initialize the
-     * B-tree
-     *
-     * @param configuration The configuration to use
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( InMemoryBTreeConfiguration<K, V> configuration )
-    {
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the parameters to initialize the
-     * B-tree
-     *
-     * @param name The B-tree's name
-     * @param keySerializer Key serializer
-     * @param valueSerializer Value serializer
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer )
-    {
-        InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
-
-        configuration.setName( name );
-        configuration.setKeySerializer( keySerializer );
-        configuration.setValueSerializer( valueSerializer );
-        configuration.setPageSize( BTree.DEFAULT_PAGE_SIZE );
-        configuration.setAllowDuplicates( BTree.FORBID_DUPLICATES );
-        configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
-
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the parameters to initialize the
-     * B-tree
-     *
-     * @param name The B-tree's name
-     * @param keySerializer Key serializer
-     * @param valueSerializer Value serializer
-     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer, boolean allowDuplicates )
-    {
-        InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
-
-        configuration.setName( name );
-        configuration.setKeySerializer( keySerializer );
-        configuration.setValueSerializer( valueSerializer );
-        configuration.setPageSize( BTree.DEFAULT_PAGE_SIZE );
-        configuration.setAllowDuplicates( allowDuplicates );
-        configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
-
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the parameters to initialize the
-     * B-tree
-     *
-     * @param name The B-tree's name
-     * @param keySerializer Key serializer
-     * @param valueSerializer Value serializer
-     * @param pageSize Size of the page
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer, int pageSize )
-    {
-        InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
-
-        configuration.setName( name );
-        configuration.setKeySerializer( keySerializer );
-        configuration.setValueSerializer( valueSerializer );
-        configuration.setPageSize( pageSize );
-        configuration.setAllowDuplicates( BTree.FORBID_DUPLICATES );
-        configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
-
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the parameters to initialize the
-     * B-tree
-     *
-     * @param name The B-tree's name
-     * @param filePath The name of the data directory with absolute path
-     * @param keySerializer Key serializer
-     * @param valueSerializer Value serializer
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
-        ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer )
-    {
-        InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
-
-        configuration.setName( name );
-        configuration.setFilePath( filePath );
-        configuration.setKeySerializer( keySerializer );
-        configuration.setValueSerializer( valueSerializer );
-        configuration.setPageSize( BTree.DEFAULT_PAGE_SIZE );
-        configuration.setAllowDuplicates( BTree.FORBID_DUPLICATES );
-        configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
-
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the parameters to initialize the
-     * B-tree
-     *
-     * @param name The B-tree's name
-     * @param filePath The name of the data directory with absolute path
-     * @param keySerializer Key serializer
-     * @param valueSerializer Value serializer
-     * @param pageSize Size of the page
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
-        ElementSerializer<K> keySerializer, ElementSerializer<V> valueSerializer, int pageSize )
-    {
-        InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
-
-        configuration.setName( name );
-        configuration.setFilePath( filePath );
-        configuration.setKeySerializer( keySerializer );
-        configuration.setValueSerializer( valueSerializer );
-        configuration.setPageSize( pageSize );
-        configuration.setAllowDuplicates( BTree.FORBID_DUPLICATES );
-        configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
-
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    /**
-     * Creates a new in-memory B-tree using the parameters to initialize the
-     * B-tree
-     *
-     * @param name The B-tree's name
-     * @param filePath The name of the data directory with absolute path
-     * @param keySerializer Key serializer
-     * @param valueSerializer Value serializer
-     * @param pageSize Size of the page
-     * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
-     * @return a new B-tree instance
-     */
-    public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
-        ElementSerializer<K> keySerializer,
-        ElementSerializer<V> valueSerializer, int pageSize, boolean allowDuplicates )
-    {
-        InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
-
-        configuration.setName( name );
-        configuration.setFilePath( filePath );
-        configuration.setKeySerializer( keySerializer );
-        configuration.setValueSerializer( valueSerializer );
-        configuration.setPageSize( pageSize );
-        configuration.setAllowDuplicates( allowDuplicates );
-        configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
-
-        BTree<K, V> btree = new InMemoryBTree<K, V>( configuration );
-
-        return btree;
-    }
-
-
-    //--------------------------------------------------------------------------------------------
     // Create Pages
     //--------------------------------------------------------------------------------------------
     /**
@@ -492,14 +280,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> Page<K, V> createLeaf( BTree<K, V> btree, long revision, int nbElems )
     {
-        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
-        {
-            return new PersistedLeaf<K, V>( btree, revision, nbElems );
-        }
-        else
-        {
-            return new InMemoryLeaf<K, V>( btree, revision, nbElems );
-        }
+        return new PersistedLeaf<K, V>( btree, revision, nbElems );
     }
 
 
@@ -513,15 +294,8 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> Page<K, V> createNode( BTree<K, V> btree, long revision, int nbElems )
     {
-        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
-        {
-            //System.out.println( "Creating a node with nbElems : " + nbElems );
-            return new PersistedNode<K, V>( btree, revision, nbElems );
-        }
-        else
-        {
-            return new InMemoryNode<K, V>( btree, revision, nbElems );
-        }
+        //System.out.println( "Creating a node with nbElems : " + nbElems );
+        return new PersistedNode<K, V>( btree, revision, nbElems );
     }
 
 
@@ -538,16 +312,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setKey( BTree<K, V> btree, Page<K, V> page, int pos, K key )
     {
-        KeyHolder<K> keyHolder;
-
-        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
-        {
-            keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), key );
-        }
-        else
-        {
-            keyHolder = new KeyHolder<K>( key );
-        }
+        KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), key );
 
         ( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
     }
@@ -563,14 +328,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setValue( BTree<K, V> btree, Page<K, V> page, int pos, ValueHolder<V> value )
     {
-        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
-        {
-            ( ( PersistedLeaf<K, V> ) page ).setValue( pos, value );
-        }
-        else
-        {
-            ( ( InMemoryLeaf<K, V> ) page ).setValue( pos, value );
-        }
+        ( ( PersistedLeaf<K, V> ) page ).setValue( pos, value );
     }
 
 
@@ -584,14 +342,7 @@ public class BTreeFactory<K, V>
      */
     /* no qualifier*/static <K, V> void setPage( BTree<K, V> btree, Page<K, V> page, int pos, Page<K, V> child )
     {
-        if ( btree.getType() != BTreeTypeEnum.IN_MEMORY )
-        {
-            ( ( PersistedNode<K, V> ) page ).setValue( pos, new PersistedPageHolder<K, V>( btree, child ) );
-        }
-        else
-        {
-            ( ( InMemoryNode<K, V> ) page ).setPageHolder( pos, new PageHolder<K, V>( btree, child ) );
-        }
+        ( ( PersistedNode<K, V> ) page ).setValue( pos, new PersistedPageHolder<K, V>( btree, child ) );
     }
 
 
@@ -765,7 +516,6 @@ public class BTreeFactory<K, V>
         {
             Page<K, V> leaf = btree.getRootPage();
             ValueHolder<V> valueHolder = ( ( AbstractPage<K, V> ) leaf ).getValue( last.pos );
-            last.valueCursor = valueHolder.getCursor();
         }
         else
         {
@@ -782,7 +532,6 @@ public class BTreeFactory<K, V>
                 {
                     Page<K, V> leaf = last.page;
                     ValueHolder<V> valueHolder = ( ( AbstractPage<K, V> ) leaf ).getValue( last.pos );
-                    last.valueCursor = valueHolder.getCursor();
                     break;
                 }
             }
@@ -870,29 +619,18 @@ public class BTreeFactory<K, V>
             ParentPos<K, V> first = new ParentPos<K, V>( btree.getRootPage(), 0 );
             stack.push( first );
 
-            if ( btree.getRootPage().isLeaf() )
-            {
-                Page<K, V> leaf = btree.getRootPage();
-                ValueHolder<V> valueHolder = ( ( AbstractPage<K, V> ) leaf ).getValue( first.pos );
-                first.valueCursor = valueHolder.getCursor();
-            }
-            else
-            {
-                Page<K, V> node = btree.getRootPage();
+            Page<K, V> node = btree.getRootPage();
 
-                while ( true )
-                {
-                    Page<K, V> page = ( ( AbstractPage<K, V> ) node ).getPage( 0 );
+            while ( true )
+            {
+                Page<K, V> page = ( ( AbstractPage<K, V> ) node ).getPage( 0 );
 
-                    first = new ParentPos<K, V>( page, 0 );
-                    stack.push( first );
+                first = new ParentPos<K, V>( page, 0 );
+                stack.push( first );
 
-                    if ( page.isLeaf() )
-                    {
-                        ValueHolder<V> valueHolder = ( ( AbstractPage<K, V> ) page ).getValue( first.pos );
-                        first.valueCursor = valueHolder.getCursor();
-                        break;
-                    }
+                if ( page.isLeaf() )
+                {
+                    break;
                 }
             }
 

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=1711861&r1=1711860&r2=1711861&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 Sun Nov  1 23:01:00 2015
@@ -20,6 +20,7 @@
 package org.apache.directory.mavibot.btree;
 
 
+import java.io.IOException;
 import java.util.concurrent.atomic.AtomicInteger;
 
 
@@ -47,7 +48,7 @@ import java.util.concurrent.atomic.Atomi
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-/* No qualifier*/class BTreeHeader<K, V> implements Cloneable
+/* No qualifier*/class BTreeHeader<K, V> implements Cloneable, WALObject
 {
     /** The current revision */
     private long revision = 0L;
@@ -312,4 +313,86 @@ import java.util.concurrent.atomic.Atomi
 
         return sb.toString();
     }
+
+
+    @Override
+    public long getId()
+    {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+
+    @Override
+    public void setId( long id )
+    {
+        // TODO Auto-generated method stub
+        
+    }
+
+
+    @Override
+    public PageIO[] serialize() throws IOException
+    {
+        int bufferSize =
+            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
+        
+        RecordManager recordManager = btree.getRecordManager();
+
+        // Get the pageIOs we need to store the data. We may need more than one.
+        PageIO[] btreeHeaderPageIos = recordManager.getFreePageIOs( bufferSize );
+
+        // Store the B-tree header Offset into the B-tree
+        long btreeHeaderOffset = btreeHeaderPageIos[0].getOffset();
+
+        // Now store the B-tree data in the pages :
+        // - the B-tree revision
+        // - the B-tree number of elements
+        // - the B-tree root page offset
+        // - the B-tree info page offset
+        // Starts at 0
+        long position = 0L;
+
+        // The B-tree current revision
+        position = recordManager.store( position, getRevision(), btreeHeaderPageIos );
+
+        // The nb elems in the tree
+        position = recordManager.store( position, getNbElems(), btreeHeaderPageIos );
+
+        // Now, we can inject the B-tree rootPage offset into the B-tree header
+        position = recordManager.store( position, getRootPageOffset(), btreeHeaderPageIos );
+
+        // The B-tree info page offset
+        position = recordManager.store( position, ( ( PersistedBTree<K, V> ) btree ).getBtreeInfoOffset(), btreeHeaderPageIos );
+
+        // And flush the pages to disk now
+        /*
+        LOG.debug( "Flushing the newly managed '{}' 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" );
+
+            LOG_PAGES.debug( "Btree Header[{}]\n{}", btreeHeader.getRevision(), sb.toString() );
+        }
+        */
+
+        recordManager.storePages( btreeHeaderPageIos );
+
+        setBTreeHeaderOffset( btreeHeaderOffset );
+
+        return btreeHeaderPageIos;
+    }
 }

Added: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeInfo.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeInfo.java?rev=1711861&view=auto
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeInfo.java (added)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeInfo.java Sun Nov  1 23:01:00 2015
@@ -0,0 +1,280 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+import java.io.IOException;
+
+import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
+import org.apache.directory.mavibot.btree.util.Strings;
+
+/**
+ * This class stores the informations contained in the BTree info header :
+ * - the B-tree page size
+ * - the B-tree name
+ * - the keySerializer FQCN
+ * - the valueSerializer FQCN
+ * - the flags that tell if the dups are allowed
+ *  
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class BTreeInfo<K, V> implements WALObject
+{
+    /** The BTree reference */
+    private BTree<K,V> btree;
+    
+    /** the B-tree page size */
+    private int pageSize;
+    
+    /** the B-tree name */
+    private String btreeName;
+    
+    /** the keySerializer FQCN */
+    private String keySerializerFQCN;
+    
+    /** The key serializer instance */
+    private ElementSerializer<K> keySerializer;
+
+    /** the valueSerializer FQCN */
+    private String valueSerializerFQCN;
+    
+    /** The value serializer instance */
+    private ElementSerializer<V> valueSerializer;
+    
+    /** The unique ID for this object */
+    private long id;
+    
+    /**
+     * Serialize the structure :
+     * 
+     * <pre>
+     * +------------+
+     * | pageSize   | The B-tree page size (ie, the number of elements per page max)
+     * +------------+
+     * | nameSize   | The B-tree name size
+     * +------------+
+     * | name       | The B-tree name
+     * +------------+
+     * | keySerSize | The keySerializer FQCN size
+     * +------------+
+     * | keySerFQCN | The keySerializer FQCN
+     * +------------+
+     * | valSerSize | The Value serializer FQCN size
+     * +------------+
+     * | valSerKQCN | The valueSerializer FQCN
+     * +------------+
+     * </pre>
+     * 
+     * {@inheritDoc}
+     * @throws IOException 
+     */
+    @Override
+    public PageIO[] serialize() throws IOException
+    {
+        // We will add the newly managed B-tree at the end of the header.
+        byte[] btreeNameBytes = Strings.getBytesUtf8( btree.getName() );
+        byte[] keySerializerBytes = Strings.getBytesUtf8( btree.getKeySerializerFQCN() );
+        byte[] valueSerializerBytes = Strings.getBytesUtf8( btree.getValueSerializerFQCN() );
+
+        int bufferSize =
+            RecordManager.INT_SIZE + // The page size
+                RecordManager.INT_SIZE + // The name size
+                btreeNameBytes.length + // The name
+                RecordManager.INT_SIZE + // The keySerializerBytes size
+                keySerializerBytes.length + // The keySerializerBytes
+                RecordManager.INT_SIZE + // The valueSerializerBytes size
+                valueSerializerBytes.length; // The valueSerializerBytes
+        
+        RecordManager recordManager = btree.getRecordManager();
+
+        // Get the pageIOs we need to store the data. We may need more than one.
+        PageIO[] btreeHeaderPageIos = recordManager.getFreePageIOs( bufferSize );
+
+        // Now store the B-tree information data in the pages :
+        // - the B-tree page size
+        // - the B-tree name
+        // - the keySerializer FQCN
+        // - the valueSerializer FQCN
+        // Starts at 0
+        long position = 0L;
+
+        // The B-tree page size
+        position = recordManager.store( position, btree.getPageSize(), btreeHeaderPageIos );
+
+        // The tree name
+        position = recordManager.store( position, btreeNameBytes, btreeHeaderPageIos );
+
+        // The keySerializer FQCN
+        position = recordManager.store( position, keySerializerBytes, btreeHeaderPageIos );
+
+        // The valueSerialier FQCN
+        position = recordManager.store( position, valueSerializerBytes, btreeHeaderPageIos );
+
+        // And flush the pages to disk now
+        recordManager.storePages( btreeHeaderPageIos );
+
+        return btreeHeaderPageIos;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public long getId()
+    {
+        return id;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setId( long id )
+    {
+        this.id = id;
+    }
+
+
+    /**
+     * @return the btree
+     */
+    public BTree<K, V> getBtree()
+    {
+        return btree;
+    }
+
+
+    /**
+     * @param btree the btree to set
+     */
+    public void setBtree( BTree<K, V> btree )
+    {
+        this.btree = btree;
+    }
+
+
+    /**
+     * @return the pageSize
+     */
+    public int getPageSize()
+    {
+        return pageSize;
+    }
+
+
+    /**
+     * @param pageSize the pageSize to set
+     */
+    public void setPageSize( int pageSize )
+    {
+        this.pageSize = pageSize;
+    }
+
+
+    /**
+     * @return the btreeName
+     */
+    public String getBtreeName()
+    {
+        return btreeName;
+    }
+
+
+    /**
+     * @param btreeName the btreeName to set
+     */
+    public void setBtreeName( String btreeName )
+    {
+        this.btreeName = btreeName;
+    }
+
+
+    /**
+     * @return the keySerializer FQCN
+     */
+    public String getKeySerializerFQCN()
+    {
+        return keySerializerFQCN;
+    }
+
+
+    /**
+     * @param keySerializerFQCN the keySerializer FQCN to set
+     */
+    public void setKeySerializerFQCN( String keySerializerFQCN )
+    {
+        this.keySerializerFQCN = keySerializerFQCN;
+    }
+    
+    
+    /**
+     * @return the keySerializer
+     */
+    public ElementSerializer<K> getKeySerializer()
+    {
+        return keySerializer;
+    }
+
+
+    /**
+     * @param keySerializer the keySerializer to set
+     */
+    public void setKeySerializer( ElementSerializer<K> keySerializer )
+    {
+        this.keySerializer = keySerializer;
+    }
+
+
+    /**
+     * @return the valueSerializer FQCN
+     */
+    public String getValueSerializerFQCN()
+    {
+        return valueSerializerFQCN;
+    }
+
+
+    /**
+     * @param valueSerializerFQCN the valueSerializer FQCN to set
+     */
+    public void setValueSerializerFQCN( String valueSerializerFQCN )
+    {
+        this.valueSerializerFQCN = valueSerializerFQCN;
+    }
+
+
+    /**
+     * @return the valueSerializer
+     */
+    public ElementSerializer<V> getValueSerializer()
+    {
+        return valueSerializer;
+    }
+
+
+    /**
+     * @param valueSerializer the valueSerializer to set
+     */
+    public void setValueSerializer( ElementSerializer<V> valueSerializer )
+    {
+        this.valueSerializer = valueSerializer;
+    }
+}

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java?rev=1711861&r1=1711860&r2=1711861&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java Sun Nov  1 23:01:00 2015
@@ -35,15 +35,9 @@ package org.apache.directory.mavibot.btr
  */
 public enum BTreeTypeEnum
 {
-    /** Pure in-memory B-tree, not persisted on disk */
-    IN_MEMORY,
-
     /** Persisted B-tree */
     PERSISTED,
 
-    /** Persisted sub B-tree */
-    PERSISTED_SUB,
-
     /** Persisted Management B-tree */
     BTREE_OF_BTREES,
 

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java?rev=1711861&r1=1711860&r2=1711861&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java Sun Nov  1 23:01:00 2015
@@ -184,8 +184,8 @@ public class BulkLoader<K, V>
      * sorted and merged elements.
      * @throws IOException 
      */
-    private static <K, V> Tuple<Iterator<Tuple<K, Set<V>>>, SortedFile> processFiles( BTree<K, V> btree,
-        Iterator<Tuple<K, Set<V>>> dataIterator ) throws IOException
+    private static <K, V> Tuple<Iterator<Tuple<K, V>>, SortedFile> processFiles( BTree<K, V> btree,
+        Iterator<Tuple<K, V>> dataIterator ) throws IOException
     {
         File file = File.createTempFile( "sortedUnique", "data" );
         file.deleteOnExit();
@@ -200,36 +200,31 @@ public class BulkLoader<K, V>
             nbReads++;
 
             // grab a tuple
-            Tuple<K, Set<V>> tuple = dataIterator.next();
+            Tuple<K, V> tuple = dataIterator.next();
 
             // Serialize the key
             byte[] bytesKey = btree.getKeySerializer().serialize( tuple.key );
             fos.write( IntSerializer.serialize( bytesKey.length ) );
             fos.write( bytesKey );
 
-            // Serialize the number of values
-            int nbValues = tuple.getValue().size();
-            fos.write( IntSerializer.serialize( nbValues ) );
-
             // Serialize the values
-            for ( V value : tuple.getValue() )
-            {
-                byte[] bytesValue = btree.getValueSerializer().serialize( value );
+            V value = tuple.getValue();
 
-                // Serialize the value
-                fos.write( IntSerializer.serialize( bytesValue.length ) );
-                fos.write( bytesValue );
-            }
+            byte[] bytesValue = btree.getValueSerializer().serialize( value );
+
+            // Serialize the value
+            fos.write( IntSerializer.serialize( bytesValue.length ) );
+            fos.write( bytesValue );
         }
 
         fos.flush();
         fos.close();
 
         FileInputStream fis = new FileInputStream( file );
-        Iterator<Tuple<K, Set<V>>> uniqueIterator = createUniqueFileIterator( btree, fis );
+        Iterator<Tuple<K, V>> uniqueIterator = createUniqueFileIterator( btree, fis );
         SortedFile sortedFile = new SortedFile( file, nbReads );
 
-        Tuple<Iterator<Tuple<K, Set<V>>>, SortedFile> result = new Tuple<Iterator<Tuple<K, Set<V>>>, SortedFile>(
+        Tuple<Iterator<Tuple<K, V>>, SortedFile> result = new Tuple<Iterator<Tuple<K, V>>, SortedFile>(
             uniqueIterator, sortedFile );
 
         return result;
@@ -278,7 +273,7 @@ public class BulkLoader<K, V>
         }
 
         // Now that we have processed all the data, we can start storing them in the btree
-        Iterator<Tuple<K, Set<V>>> dataIterator = null;
+        Iterator<Tuple<K, V>> dataIterator = null;
         FileInputStream[] streams = null;
         BTree<K, V> resultBTree = null;
 
@@ -303,7 +298,7 @@ public class BulkLoader<K, V>
             dataIterator = createIterator( btree, streams );
 
             // Process the files, and construct one single file with an iterator
-            Tuple<Iterator<Tuple<K, Set<V>>>, SortedFile> result = processFiles( btree, dataIterator );
+            Tuple<Iterator<Tuple<K, V>>, SortedFile> result = processFiles( btree, dataIterator );
             resultBTree = bulkLoad( btree, result.key, result.value.nbValues );
             result.value.file.delete();
         }
@@ -467,19 +462,13 @@ public class BulkLoader<K, V>
     /**
      * Inject a tuple into a leaf
      */
-    private static <K, V> void injectInLeaf( BTree<K, V> btree, Tuple<K, Set<V>> tuple, LevelInfo<K, V> leafLevel )
+    private static <K, V> void injectInLeaf( BTree<K, V> btree, Tuple<K, V> tuple, LevelInfo<K, V> leafLevel )
     {
         PersistedLeaf<K, V> leaf = ( PersistedLeaf<K, V> ) leafLevel.getCurrentPage();
 
         KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), tuple.getKey() );
         leaf.setKey( leafLevel.getCurrentPos(), keyHolder );
 
-        if ( btree.getType() != BTreeTypeEnum.PERSISTED_SUB )
-        {
-            ValueHolder<V> valueHolder = new PersistedValueHolder<V>( btree, ( V[] ) tuple.getValue().toArray() );
-            leaf.setValue( leafLevel.getCurrentPos(), valueHolder );
-        }
-
         leafLevel.incCurrentPos();
     }
 
@@ -783,7 +772,7 @@ public class BulkLoader<K, V>
     }
 
 
-    private static <K, V> BTree<K, V> bulkLoadSinglePage( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator,
+    private static <K, V> BTree<K, V> bulkLoadSinglePage( BTree<K, V> btree, Iterator<Tuple<K, V>> dataIterator,
         int nbElems ) throws IOException
     {
         // Use the root page
@@ -796,10 +785,6 @@ public class BulkLoader<K, V>
 
         switch ( btree.getType() )
         {
-            case IN_MEMORY:
-                ( ( InMemoryLeaf<K, V> ) rootPage ).values = values;
-                break;
-
             default:
                 ( ( PersistedLeaf<K, V> ) rootPage ).values = values;
         }
@@ -809,25 +794,14 @@ public class BulkLoader<K, V>
 
         while ( dataIterator.hasNext() )
         {
-            Tuple<K, Set<V>> tuple = dataIterator.next();
+            Tuple<K, V> tuple = dataIterator.next();
 
             // Store the current element in the rootPage
             KeyHolder<K> keyHolder = new PersistedKeyHolder<K>( btree.getKeySerializer(), tuple.getKey() );
             keys[pos] = keyHolder;
 
-            switch ( btree.getType() )
-            {
-                case IN_MEMORY:
-                    ValueHolder<V> valueHolder = new InMemoryValueHolder<V>( btree, ( V[] ) tuple.getValue()
-                        .toArray() );
-                    ( ( InMemoryLeaf<K, V> ) rootPage ).values[pos] = valueHolder;
-                    break;
-
-                default:
-                    valueHolder = new PersistedValueHolder<V>( btree, ( V[] ) tuple.getValue()
-                        .toArray() );
-                    ( ( PersistedLeaf<K, V> ) rootPage ).values[pos] = valueHolder;
-            }
+            ValueHolder<V>valueHolder = new PersistedValueHolder<V>( btree, ( V )tuple.getValue() );
+            ( ( PersistedLeaf<K, V> ) rootPage ).values[pos] = valueHolder;
 
             pos++;
         }
@@ -847,7 +821,7 @@ public class BulkLoader<K, V>
      * Construct the target BTree from the sorted data. We will use the nb of elements
      * to determinate the structure of the BTree, as it must be balanced
      */
-    private static <K, V> BTree<K, V> bulkLoad( BTree<K, V> btree, Iterator<Tuple<K, Set<V>>> dataIterator, int nbElems )
+    private static <K, V> BTree<K, V> bulkLoad( BTree<K, V> btree, Iterator<Tuple<K, V>> dataIterator, int nbElems )
         throws IOException
     {
         int pageSize = btree.getPageSize();
@@ -872,7 +846,7 @@ public class BulkLoader<K, V>
             if ( leafLevel.getNbAddedElems() < leafLevel.getNbElemsLimit() )
             {
                 // grab a tuple
-                Tuple<K, Set<V>> tuple = dataIterator.next();
+                Tuple<K, V> tuple = dataIterator.next();
 
                 injectInLeaf( btree, tuple, leafLevel );
                 leafLevel.incNbAddedElems();
@@ -909,7 +883,7 @@ public class BulkLoader<K, V>
                     while ( nbToAdd > 0 )
                     {
                         // grab a tuple
-                        Tuple<K, Set<V>> tuple = dataIterator.next();
+                        Tuple<K, V> tuple = dataIterator.next();
 
                         injectInLeaf( btree, tuple, leafLevel );
                         leafLevel.incNbAddedElems();
@@ -928,7 +902,7 @@ public class BulkLoader<K, V>
                     while ( nbToAdd > 0 )
                     {
                         // grab a tuple
-                        Tuple<K, Set<V>> tuple = dataIterator.next();
+                        Tuple<K, V> tuple = dataIterator.next();
 
                         injectInLeaf( btree, tuple, leafLevel );
                         leafLevel.incNbAddedElems();
@@ -951,7 +925,7 @@ public class BulkLoader<K, V>
                     while ( nbToAdd > 0 )
                     {
                         // grab a tuple
-                        Tuple<K, Set<V>> tuple = dataIterator.next();
+                        Tuple<K, V> tuple = dataIterator.next();
 
                         injectInLeaf( btree, tuple, leafLevel );
                         leafLevel.incNbAddedElems();
@@ -984,33 +958,27 @@ public class BulkLoader<K, V>
         throws IOException
     {
         // Sort the tuples. 
-        Tuple<K, Set<V>>[] sortedTuples = sort( btree, tuples );
+        Tuple<K, V>[] sortedTuples = sort( btree, tuples );
 
         File file = File.createTempFile( "sorted", Integer.toString( fileNb ) );
         file.deleteOnExit();
         FileOutputStream fos = new FileOutputStream( file );
 
         // Flush the tuples on disk
-        for ( Tuple<K, Set<V>> tuple : sortedTuples )
+        for ( Tuple<K, V> tuple : sortedTuples )
         {
             // Serialize the key
             byte[] bytesKey = btree.getKeySerializer().serialize( tuple.key );
             fos.write( IntSerializer.serialize( bytesKey.length ) );
             fos.write( bytesKey );
 
-            // Serialize the number of values
-            int nbValues = tuple.getValue().size();
-            fos.write( IntSerializer.serialize( nbValues ) );
-
             // Serialize the values
-            for ( V value : tuple.getValue() )
-            {
-                byte[] bytesValue = btree.getValueSerializer().serialize( value );
+            V value = tuple.getValue();
+            byte[] bytesValue = btree.getValueSerializer().serialize( value );
 
-                // Serialize the value
-                fos.write( IntSerializer.serialize( bytesValue.length ) );
-                fos.write( bytesValue );
-            }
+            // Serialize the value
+            fos.write( IntSerializer.serialize( bytesValue.length ) );
+            fos.write( bytesValue );
         }
 
         fos.flush();
@@ -1024,9 +992,9 @@ public class BulkLoader<K, V>
      * Sort a list of tuples, eliminating the duplicate keys and storing the values in a set when we 
      * have a duplicate key
      */
-    private static <K, V> Tuple<K, Set<V>>[] sort( BTree<K, V> btree, List<Tuple<K, V>> tuples )
+    private static <K, V> Tuple<K, V>[] sort( BTree<K, V> btree, List<Tuple<K, V>> tuples )
     {
-        Comparator<Tuple<K, Set<V>>> tupleComparator = new TupleComparator( btree.getKeyComparator(), btree
+        Comparator<Tuple<K, V>> tupleComparator = new TupleComparator( btree.getKeyComparator(), btree
             .getValueComparator() );
 
         // Sort the list
@@ -1034,12 +1002,12 @@ public class BulkLoader<K, V>
             {} );
 
         // First, eliminate the equals keys. We use a map for that
-        Map<K, Set<V>> mapTuples = new HashMap<K, Set<V>>();
+        Map<K, V> mapTuples = new HashMap<K, V>();
 
         for ( Tuple<K, V> tuple : tuplesArray )
         {
             // Is the key present in the map ?
-            Set<V> foundSet = mapTuples.get( tuple.key );
+            V foundSet = mapTuples.get( tuple.key );
 
             if ( foundSet != null )
             {
@@ -1050,7 +1018,7 @@ public class BulkLoader<K, V>
             {
                 // No such key present in the map : create a new set to store the values,
                 // and add it in the map associated with the new key
-                Set<V> set = new TreeSet<V>();
+                V set = new TreeV();
                 set.add( tuple.value );
                 mapTuples.put( tuple.key, set );
             }
@@ -1058,13 +1026,13 @@ public class BulkLoader<K, V>
 
         // Now, sort the map, by extracting all the key/values from the map
         int size = mapTuples.size();
-        Tuple<K, Set<V>>[] sortedTuples = new Tuple[size];
+        Tuple<K, V>[] sortedTuples = new Tuple[size];
         int pos = 0;
 
         // We create an array containing all the elements
-        for ( Map.Entry<K, Set<V>> entry : mapTuples.entrySet() )
+        for ( Map.Entry<K, V> entry : mapTuples.entrySet() )
         {
-            sortedTuples[pos] = new Tuple<K, Set<V>>();
+            sortedTuples[pos] = new Tuple<K, V>();
             sortedTuples[pos].key = entry.getKey();
             sortedTuples[pos].value = entry.getValue();
             pos++;
@@ -1080,22 +1048,22 @@ public class BulkLoader<K, V>
     /**
      * Build an iterator over an array of sorted tuples, in memory
      */
-    private static <K, V> Iterator<Tuple<K, Set<V>>> createTupleIterator( BTree<K, V> btree, List<Tuple<K, V>> tuples )
+    private static <K, V> Iterator<Tuple<K, V>> createTupleIterator( BTree<K, V> btree, List<Tuple<K, V>> tuples )
     {
-        final Tuple<K, Set<V>>[] sortedTuples = sort( btree, tuples );
+        final Tuple<K, V>[] sortedTuples = sort( btree, tuples );
 
-        Iterator<Tuple<K, Set<V>>> tupleIterator = new Iterator<Tuple<K, Set<V>>>()
+        Iterator<Tuple<K, V>> tupleIterator = new Iterator<Tuple<K, V>>()
         {
             private int pos = 0;
 
 
             @Override
-            public Tuple<K, Set<V>> next()
+            public Tuple<K, V> next()
             {
                 // Return the current tuple, if any
                 if ( pos < sortedTuples.length )
                 {
-                    Tuple<K, Set<V>> tuple = sortedTuples[pos];
+                    Tuple<K, V> tuple = sortedTuples[pos];
                     pos++;
 
                     return tuple;
@@ -1122,7 +1090,7 @@ public class BulkLoader<K, V>
     }
 
 
-    private static <K, V> Tuple<K, Set<V>> fetchTuple( BTree<K, V> btree, FileInputStream fis )
+    private static <K, V> Tuple<K, V> fetchTuple( BTree<K, V> btree, FileInputStream fis )
     {
         try
         {
@@ -1131,8 +1099,8 @@ public class BulkLoader<K, V>
                 return null;
             }
 
-            Tuple<K, Set<V>> tuple = new Tuple<K, Set<V>>();
-            tuple.value = new TreeSet<V>();
+            Tuple<K, V> tuple = new Tuple<K, V>();
+            tuple.value = new TreeV();
 
             byte[] intBytes = new byte[4];
 
@@ -1177,7 +1145,7 @@ public class BulkLoader<K, V>
      * Build an iterator over an array of sorted tuples, from files on the disk
      * @throws FileNotFoundException 
      */
-    private static <K, V> Iterator<Tuple<K, Set<V>>> createIterator( final BTree<K, V> btree,
+    private static <K, V> Iterator<Tuple<K, V>> createIterator( final BTree<K, V> btree,
         final FileInputStream[] streams )
         throws FileNotFoundException
     {
@@ -1185,9 +1153,9 @@ public class BulkLoader<K, V>
         final int nbFiles = streams.length;
 
         // We will read only one element at a time from each file
-        final Tuple<K, Set<V>>[] readTuples = new Tuple[nbFiles];
-        final TreeMap<Tuple<K, Integer>, Set<V>> candidates =
-            new TreeMap<Tuple<K, Integer>, Set<V>>(
+        final Tuple<K, V>[] readTuples = new Tuple[nbFiles];
+        final TreeMap<Tuple<K, Integer>, V> candidates =
+            new TreeMap<Tuple<K, Integer>, V>(
                 new TupleComparator<K, Integer>( btree.getKeyComparator(), IntComparator.INSTANCE ) );
 
         // Read the tuple from each files
@@ -1210,7 +1178,7 @@ public class BulkLoader<K, V>
                     else
                     {
                         // We have to merge the pulled tuple with the existing one, and read one more tuple
-                        Set<V> oldValues = candidates.get( candidate );
+                        V oldValues = candidates.get( candidate );
                         oldValues.addAll( readTuples[i].getValue() );
                     }
                 }
@@ -1221,10 +1189,10 @@ public class BulkLoader<K, V>
             }
         }
 
-        Iterator<Tuple<K, Set<V>>> tupleIterator = new Iterator<Tuple<K, Set<V>>>()
+        Iterator<Tuple<K, V>> tupleIterator = new Iterator<Tuple<K, V>>()
         {
             @Override
-            public Tuple<K, Set<V>> next()
+            public Tuple<K, V> next()
             {
                 // Get the first candidate
                 Tuple<K, Integer> tupleCandidate = candidates.firstKey();
@@ -1233,7 +1201,7 @@ public class BulkLoader<K, V>
                 candidates.remove( tupleCandidate );
 
                 // Get the the next tuple from the stream we just got the tuple from
-                Tuple<K, Set<V>> tuple = readTuples[tupleCandidate.value];
+                Tuple<K, V> tuple = readTuples[tupleCandidate.value];
 
                 // fetch the next tuple from the file we just read teh candidate from 
                 while ( true )
@@ -1250,7 +1218,7 @@ public class BulkLoader<K, V>
                     if ( readTuples[tupleCandidate.value] != null )
                     {
                         // And store it into the candidate set
-                        Set<V> oldValues = candidates.get( readTuples[tupleCandidate.value] );
+                        V oldValues = candidates.get( readTuples[tupleCandidate.value] );
 
                         if ( oldValues != null )
                         {
@@ -1297,20 +1265,20 @@ public class BulkLoader<K, V>
      * Build an iterator over an array of sorted tuples, from files on the disk
      * @throws FileNotFoundException 
      */
-    private static <K, V> Iterator<Tuple<K, Set<V>>> createUniqueFileIterator( final BTree<K, V> btree,
+    private static <K, V> Iterator<Tuple<K, V>> createUniqueFileIterator( final BTree<K, V> btree,
         final FileInputStream stream )
         throws FileNotFoundException
     {
-        Iterator<Tuple<K, Set<V>>> tupleIterator = new Iterator<Tuple<K, Set<V>>>()
+        Iterator<Tuple<K, V>> tupleIterator = new Iterator<Tuple<K, V>>()
         {
             boolean hasNext = true;
 
 
             @Override
-            public Tuple<K, Set<V>> next()
+            public Tuple<K, V> next()
             {
                 // Get the tuple from the stream
-                Tuple<K, Set<V>> tuple = fetchTuple( btree, stream );
+                Tuple<K, V> tuple = fetchTuple( btree, stream );
 
                 // We can now return the found value
                 return tuple;

Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java?rev=1711861&r1=1711860&r2=1711861&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/EmptyTupleCursor.java Sun Nov  1 23:01:00 2015
@@ -53,22 +53,6 @@ public class EmptyTupleCursor<K, V> exte
 
 
     /**
-     * Change the position in the current cursor to set it after the last key
-     */
-    public void afterLast() throws IOException
-    {
-    }
-
-
-    /**
-     * Change the position in the current cursor before the first key
-     */
-    public void beforeFirst() throws IOException
-    {
-    }
-
-
-    /**
      * Always return false.
      *
      * @return Always false