You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2013/08/04 11:22:58 UTC

svn commit: r1510115 [11/13] - in /directory/mavibot/trunk: ./ mavibot/ mavibot/src/main/java/org/apache/directory/ mavibot/src/main/java/org/apache/directory/mavibot/ mavibot/src/main/java/org/apache/directory/mavibot/btree/ mavibot/src/main/java/org/...

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedBtreeTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedBtreeTest.java?rev=1510115&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedBtreeTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/MultiThreadedBtreeTest.java Sun Aug  4 09:22:56 2013
@@ -0,0 +1,287 @@
+/*
+ *  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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.directory.mavibot.btree.BTree;
+import org.apache.directory.mavibot.btree.Cursor;
+import org.apache.directory.mavibot.btree.Tuple;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * A class to test multi-threaded operations on the btree
+ *  
+ * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
+ */
+public class MultiThreadedBtreeTest
+{
+    /** The btree we use */
+    private static BTree<Long, String> btree;
+
+
+    /**
+     * Create the btree once
+     * @throws IOException If the creation failed
+     */
+    @BeforeClass
+    public static void setup() throws IOException
+    {
+        btree = new BTree<Long, String>( "test", new LongSerializer(), new StringSerializer() );
+    }
+
+
+    /**
+     * Close the btree
+     */
+    @AfterClass
+    public static void shutdown() throws IOException
+    {
+        btree.close();
+    }
+
+
+    /**
+     * Create a btree with 500 000 elements in it
+     * @throws IOException If the creation failed
+     */
+    private void create500KBTree() throws IOException
+    {
+        Random random = new Random( System.nanoTime() );
+
+        int nbElems = 500000;
+
+        // Create a BTree with 500 000 entries
+        btree.setPageSize( 32 );
+
+        for ( int i = 0; i < nbElems; i++ )
+        {
+            Long key = ( long ) random.nextLong();
+            String value = Long.toString( key );
+
+            try
+            {
+                btree.insert( key, value );
+
+                if ( i % 100000 == 0 )
+                {
+                    System.out.println( "Written " + i + " elements" );
+                }
+            }
+            catch ( Exception e )
+            {
+                e.printStackTrace();
+                System.out.println( btree );
+                System.out.println( "Error while adding " + value );
+                return;
+            }
+        }
+    }
+
+
+    /**
+     * Browse the btree in its current revision, reading all of its elements
+     * @return The number of read elements 
+     * @throws IOException If the browse failed
+     */
+    private int testBrowse() throws IOException
+    {
+        Cursor<Long, String> cursor = btree.browse();
+
+        int nb = 0;
+        long elem = Long.MIN_VALUE;
+
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> res = cursor.next();
+
+            if ( res.getKey() > elem )
+            {
+                elem = res.getKey();
+                nb++;
+            }
+        }
+
+        long revision = cursor.getRevision();
+
+        cursor.close();
+
+        //System.out.println( Thread.currentThread().getName() + " Nb elements read : " + nb + " on revision : "
+        //    + revision );
+
+        return nb;
+    }
+
+
+    /**
+     * Chack that we can read the btree while it is being modified. We will start
+     * 100 readers for one writer.
+     * 
+     * @throws InterruptedException If the btree access failed.
+     */
+    @Test
+    public void testBrowseMultiThreads() throws InterruptedException
+    {
+        int nbThreads = 100;
+        final CountDownLatch latch = new CountDownLatch( nbThreads );
+
+        Thread writer = new Thread()
+        {
+            public void run()
+            {
+                try
+                {
+                    create500KBTree();
+                }
+                catch ( Exception e )
+                {
+                }
+            }
+        };
+
+        long t0 = System.currentTimeMillis();
+
+        // Start the writer
+        writer.start();
+
+        for ( int i = 0; i < nbThreads; i++ )
+        {
+            Thread test = new Thread()
+            {
+                public void run()
+                {
+                    try
+                    {
+                        int res = 0;
+                        int previous = -1;
+
+                        while ( previous < res )
+                        {
+                            previous = res;
+                            res = testBrowse();
+                            Thread.sleep( 500 );
+                        }
+
+                        latch.countDown();
+                    }
+                    catch ( Exception e )
+                    {
+                    }
+                }
+            };
+
+            // Start each reader
+            test.start();
+        }
+
+        // Wait for all the readers to be done
+        latch.await();
+
+        long t1 = System.currentTimeMillis();
+
+        System.out.println( " Time to create 500K entries and to have " + nbThreads + " threads reading them : "
+            + ( ( t1 - t0 ) / 1000 ) + " seconds" );
+    }
+
+
+    /**
+     * Test that we can use many threads inserting data in a BTree
+     * @throws InterruptedException
+     */
+    @Test
+    public void testInsertMultiThreads() throws InterruptedException, IOException
+    {
+        int nbThreads = 100;
+        final CountDownLatch latch = new CountDownLatch( nbThreads );
+
+        //Thread.sleep( 60000L );
+
+        long t0 = System.currentTimeMillis();
+
+        for ( int i = 0; i < nbThreads; i++ )
+        {
+            final long prefix = i;
+            Thread test = new Thread()
+            {
+                public void run()
+                {
+                    try
+                    {
+                        // Inject 10000 elements
+                        for ( int j = 0; j < 10000; j++ )
+                        {
+                            long value = prefix * 10000 + j;
+                            btree.insert( value, Long.toString( value ) );
+
+                            /*
+                            if ( j % 10000 == 0 )
+                            {
+                                System.out.println( "Thread " + Thread.currentThread().getName() + " flushed " + j
+                                    + " elements" );
+                            }
+                            */
+                        }
+
+                        latch.countDown();
+                    }
+                    catch ( Exception e )
+                    {
+                    }
+                }
+            };
+
+            // Start each reader
+            test.start();
+        }
+
+        // Wait for all the readers to be done
+        latch.await();
+
+        long t1 = System.currentTimeMillis();
+
+        // Check that the tree contains all the values
+        try
+        {
+            for ( long i = 0L; i < 100000L; i++ )
+            {
+                assertEquals( Long.toString( i ), btree.get( i ) );
+            }
+        }
+        catch ( KeyNotFoundException knfe )
+        {
+            fail();
+        }
+
+        System.out.println( " Time to create 1M entries : "
+            + ( ( t1 - t0 ) / 1000 ) + " seconds" );
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/ReadTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/ReadTest.java?rev=1510115&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/ReadTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/ReadTest.java Sun Aug  4 09:22:56 2013
@@ -0,0 +1,354 @@
+/*
+ *  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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.mavibot.btree.PageIO;
+import org.apache.directory.mavibot.btree.RecordManager;
+import org.junit.Test;
+
+
+/**
+ * Test the RecordManager.readXXX() methods using reflection
+ * 
+ * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
+ */
+public class ReadTest
+{
+    /**
+     * Test the readInt method
+     */
+    @Test
+    public void testReadInt() throws Exception
+    {
+        File tempFile = File.createTempFile( "mavibot", ".db" );
+        String tempFileName = tempFile.getAbsolutePath();
+        tempFile.deleteOnExit();
+
+        // Create page size of 32 only
+        RecordManager recordManager = new RecordManager( tempFileName, 32 );
+        Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, int.class, PageIO[].class );
+        Method readIntMethod = RecordManager.class.getDeclaredMethod( "readInt", PageIO[].class, long.class );
+        storeMethod.setAccessible( true );
+        readIntMethod.setAccessible( true );
+
+        // Allocate some Pages
+        PageIO[] pageIos = new PageIO[2];
+        pageIos[0] = new PageIO();
+        pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+        pageIos[1] = new PageIO();
+        pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+
+        // Set the int at the beginning
+        storeMethod.invoke( recordManager, 0, 0x12345678, pageIos );
+
+        // Read it back
+        int readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 0 );
+
+        assertEquals( 0x12345678, readValue );
+
+        // Set the int at the end of the first page
+        storeMethod.invoke( recordManager, 16, 0x12345678, pageIos );
+
+        // Read it back
+        readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 16 );
+
+        assertEquals( 0x12345678, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 1 byte overlapping
+        storeMethod.invoke( recordManager, 17, 0x12345678, pageIos );
+
+        // Read it back
+        readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 17 );
+
+        assertEquals( 0x12345678, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 2 bytes overlapping
+        storeMethod.invoke( recordManager, 18, 0x12345678, pageIos );
+
+        // Read it back
+        readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 18 );
+
+        assertEquals( 0x12345678, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 3 bytes overlapping
+        storeMethod.invoke( recordManager, 19, 0x12345678, pageIos );
+
+        // Read it back
+        readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 19 );
+
+        assertEquals( 0x12345678, readValue );
+
+        // Set the int at the beginning of the second page
+        storeMethod.invoke( recordManager, 20, 0x12345678, pageIos );
+
+        // Read it back
+        readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 20 );
+    }
+
+
+    /**
+     * Test the readLong method
+     */
+    @Test
+    public void testReadLong() throws Exception
+    {
+        File tempFile = File.createTempFile( "mavibot", ".db" );
+        String tempFileName = tempFile.getAbsolutePath();
+        tempFile.deleteOnExit();
+
+        // Create page size of 32 only
+        RecordManager recordManager = new RecordManager( tempFileName, 32 );
+        Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, long.class, PageIO[].class );
+        Method readLongMethod = RecordManager.class.getDeclaredMethod( "readLong", PageIO[].class, long.class );
+        storeMethod.setAccessible( true );
+        readLongMethod.setAccessible( true );
+
+        // Allocate some Pages
+        PageIO[] pageIos = new PageIO[2];
+        pageIos[0] = new PageIO();
+        pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+        pageIos[1] = new PageIO();
+        pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+
+        // Set the int at the beginning
+        storeMethod.invoke( recordManager, 0, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        long readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 0 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page
+        storeMethod.invoke( recordManager, 12, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 12 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 1 byte overlapping
+        storeMethod.invoke( recordManager, 13, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 13 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 2 bytes overlapping
+        storeMethod.invoke( recordManager, 14, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 14 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 3 bytes overlapping
+        storeMethod.invoke( recordManager, 15, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 15 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 4 bytes overlapping
+        storeMethod.invoke( recordManager, 16, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 16 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 5 bytes overlapping
+        storeMethod.invoke( recordManager, 17, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 17 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 6 bytes overlapping
+        storeMethod.invoke( recordManager, 18, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 18 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 7 bytes overlapping
+        storeMethod.invoke( recordManager, 19, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 19 );
+
+        assertEquals( 0x0123456789ABCDEFL, readValue );
+
+        // Set the int at the beginning of the second page
+        storeMethod.invoke( recordManager, 20, 0x0123456789ABCDEFL, pageIos );
+
+        // Read it back
+        readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 20 );
+    }
+
+
+    /**
+     * Test the readBytes() method
+     */
+    @Test
+    public void testReadBytes() throws Exception
+    {
+        File tempFile = File.createTempFile( "mavibot", ".db" );
+        String tempFileName = tempFile.getAbsolutePath();
+        tempFile.deleteOnExit();
+
+        // We use smaller pages
+        RecordManager recordManager = new RecordManager( tempFileName, 32 );
+        Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, byte[].class, PageIO[].class );
+        Method readBytesMethod = RecordManager.class.getDeclaredMethod( "readBytes", PageIO[].class, long.class );
+        storeMethod.setAccessible( true );
+        readBytesMethod.setAccessible( true );
+
+        // Allocate some Pages
+        PageIO[] pageIos = new PageIO[4];
+        pageIos[0] = new PageIO();
+        pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+        pageIos[1] = new PageIO();
+        pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+        pageIos[2] = new PageIO();
+        pageIos[2].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+        pageIos[3] = new PageIO();
+        pageIos[3].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
+
+        // We start with 4 bytes
+        byte[] bytes = new byte[]
+            { 0x01, 0x23, 0x45, 0x67 };
+
+        // Set the bytes at the beginning
+        long position = ( Long ) storeMethod.invoke( recordManager, 0L, bytes, pageIos );
+
+        // Read the bytes back
+        byte[] readBytes = ( byte[] ) readBytesMethod.invoke( recordManager, pageIos, 0L );
+
+        // The byte length
+        int pos = 0;
+        assertNotNull( readBytes );
+        assertEquals( 4, readBytes.length );
+        // The data
+        assertEquals( 0x01, readBytes[pos++] );
+        assertEquals( 0x23, readBytes[pos++] );
+        assertEquals( 0x45, readBytes[pos++] );
+        assertEquals( 0x67, readBytes[pos++] );
+
+        // Set the bytes at the end of the first page
+        position = ( Long ) storeMethod.invoke( recordManager, 12L, bytes, pageIos );
+
+        // Read the bytes back
+        readBytes = ( byte[] ) readBytesMethod.invoke( recordManager, pageIos, 12L );
+
+        // The byte length
+        pos = 0;
+        assertNotNull( readBytes );
+        assertEquals( 4, readBytes.length );
+        // The data
+        assertEquals( 0x01, readBytes[pos++] );
+        assertEquals( 0x23, readBytes[pos++] );
+        assertEquals( 0x45, readBytes[pos++] );
+        assertEquals( 0x67, readBytes[pos++] );
+
+        // Set A full page of bytes in the first page 
+        bytes = new byte[16];
+
+        for ( int i = 0; i < 16; i++ )
+        {
+            bytes[i] = ( byte ) ( i + 1 );
+        }
+
+        position = ( Long ) storeMethod.invoke( recordManager, 0L, bytes, pageIos );
+
+        // Read the bytes back
+        readBytes = ( byte[] ) readBytesMethod.invoke( recordManager, pageIos, 0L );
+
+        // The byte length
+        pos = 0;
+        assertNotNull( readBytes );
+        assertEquals( 16, readBytes.length );
+        // The data
+        for ( int i = 0; i < 16; i++ )
+        {
+            assertEquals( i + 1, readBytes[pos++] );
+        }
+
+        // Write the bytes over 2 pages
+        position = ( Long ) storeMethod.invoke( recordManager, 15L, bytes, pageIos );
+
+        // Read the bytes back
+        readBytes = ( byte[] ) readBytesMethod.invoke( recordManager, pageIos, 15L );
+
+        // The byte length
+        pos = 0;
+        assertNotNull( readBytes );
+        assertEquals( 16, readBytes.length );
+        // The data
+        for ( int i = 0; i < 16; i++ )
+        {
+            assertEquals( i + 1, readBytes[pos++] );
+        }
+
+        // Write the bytes over 4 pages
+        bytes = new byte[80];
+
+        for ( int i = 0; i < 80; i++ )
+        {
+            bytes[i] = ( byte ) ( i + 1 );
+        }
+
+        position = ( Long ) storeMethod.invoke( recordManager, 2L, bytes, pageIos );
+
+        // Read the bytes back
+        readBytes = ( byte[] ) readBytesMethod.invoke( recordManager, pageIos, 2L );
+
+        // The byte length
+        pos = 0;
+        assertNotNull( readBytes );
+        assertEquals( 80, readBytes.length );
+        // The data
+        for ( int i = 0; i < 80; i++ )
+        {
+            assertEquals( i + 1, readBytes[pos++] );
+        }
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java?rev=1510115&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerFreePageTest.java Sun Aug  4 09:22:56 2013
@@ -0,0 +1,187 @@
+/*
+ *  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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.directory.mavibot.btree.BTree;
+import org.apache.directory.mavibot.btree.Cursor;
+import org.apache.directory.mavibot.btree.RecordManager;
+import org.apache.directory.mavibot.btree.Tuple;
+import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * test the RecordManager's free page management
+ * 
+ * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
+ */
+public class RecordManagerFreePageTest
+{
+    private BTree<Long, String> btree = null;
+
+    private RecordManager recordManager1 = null;
+
+    private File dataDir = null;
+
+
+    @Before
+    public void createBTree() throws IOException
+    {
+        dataDir = new File( System.getProperty( "java.io.tmpdir" ) + "/recordman" );
+
+        if ( dataDir.exists() )
+        {
+            FileUtils.deleteDirectory( dataDir );
+        }
+
+        dataDir.mkdirs();
+
+        openRecordManagerAndBtree();
+
+        try
+        {
+            // Create a new BTree
+            btree = recordManager1.addBTree( "test", new LongSerializer(), new StringSerializer(), false );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    private void openRecordManagerAndBtree()
+    {
+        try
+        {
+            if ( recordManager1 != null )
+            {
+                recordManager1.close();
+            }
+
+            // Now, try to reload the file back
+            recordManager1 = new RecordManager( dataDir.getAbsolutePath() );
+
+            // load the last created btree
+            if ( btree != null )
+            {
+                btree = recordManager1.getManagedTree( btree.getName() );
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+    private int nbElems = 100000;
+
+
+    /**
+     * Test the creation of a RecordManager, and that we can read it back.  
+     */
+    @Test
+    public void testRecordManager() throws IOException, BTreeAlreadyManagedException
+    {
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        int nbError = 0;
+
+        long l1 = System.currentTimeMillis();
+        int n = 0;
+        long delta = l1;
+
+        for ( int i = 0; i < nbElems; i++ )
+        {
+            Long key = ( long ) i;
+            String value = Long.toString( key );
+
+            btree.insert( key, value );
+
+            if ( i % 10000 == 0 )
+            {
+                if ( n > 0 )
+                {
+                    long t0 = System.currentTimeMillis();
+                    System.out.println( "Written " + i + " elements in : " + ( t0 - delta ) + "ms" );
+                    delta = t0;
+                }
+
+                n++;
+            }
+        }
+
+        long l2 = System.currentTimeMillis();
+
+        System.out.println( "Delta : " + ( l2 - l1 ) + ", nbError = " + nbError
+            + ", Nb insertion per second : " + ( ( nbElems ) / ( l2 - l1 ) ) * 1000 );
+
+        long length = new File( dataDir, "mavibot.db" ).length();
+        String units = "MB";
+
+        long size = length / ( 1024 * 1024 );
+
+        if ( size == 0 )
+        {
+            size = length / 1024;
+            units = "KB";
+        }
+
+        System.out.println( size + units );
+
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        assertTrue( nbElems == btree.getNbElems() );
+
+        Cursor<Long, String> cursor = btree.browse();
+
+        long i = 0;
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> t = cursor.next();
+            assertEquals( ( Long ) i, t.getKey() );
+            assertEquals( String.valueOf( i ), t.getValue() );
+            i++;
+        }
+
+        cursor.close();
+
+        assertEquals( nbElems, i );
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java?rev=1510115&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerPrivateMethodTest.java Sun Aug  4 09:22:56 2013
@@ -0,0 +1,145 @@
+/*
+ *  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 static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.UUID;
+
+import org.apache.directory.mavibot.btree.BTree;
+import org.apache.directory.mavibot.btree.PageIO;
+import org.apache.directory.mavibot.btree.RecordManager;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * Test some of the RecordManager prvate methods
+ * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
+ */
+public class RecordManagerPrivateMethodTest
+{
+    
+    private BTree<Long, String> btree = null;
+
+    private RecordManager recordManager = null;
+
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+
+    private File dataDir = null;
+
+
+    @Before
+    public void createRecordManager() throws Exception
+    {
+        dataDir = tempFolder.newFolder( UUID.randomUUID().toString() );
+        
+        // Now, try to reload the file back
+        recordManager = new RecordManager( dataDir.getAbsolutePath(), 32 );
+
+        // Create a new BTree
+        btree = ( BTree<Long, String> ) recordManager.addBTree( "test", new LongSerializer(), new StringSerializer(), false );
+    }
+
+
+    @After
+    public void closeBTree() throws IOException
+    {
+        recordManager.close();
+    }
+    
+    
+    /**
+     * Test the getFreePageIOs method
+     */
+    @Test
+    public void testGetFreePageIos() throws IOException, NoSuchMethodException, InvocationTargetException,
+        IllegalAccessException
+    {
+        Method getFreePageIOsMethod = RecordManager.class.getDeclaredMethod( "getFreePageIOs", int.class );
+        getFreePageIOsMethod.setAccessible( true );
+
+        PageIO[] pages = (org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, 0 );
+
+        assertEquals( 0, pages.length );
+
+        for ( int i = 1; i < 20; i++ )
+        {
+            pages = (org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
+            assertEquals( 1, pages.length );
+        }
+
+        for ( int i = 21; i < 44; i++ )
+        {
+            pages = (org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
+            assertEquals( 2, pages.length );
+        }
+
+        for ( int i = 45; i < 68; i++ )
+        {
+            pages = (org.apache.directory.mavibot.btree.PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
+            assertEquals( 3, pages.length );
+        }
+        
+        btree.close();
+    }
+
+
+    /**
+     * Test the ComputeNbPages method
+     */
+    @Test
+    public void testComputeNbPages() throws IOException, SecurityException, NoSuchMethodException,
+        IllegalArgumentException, IllegalAccessException, InvocationTargetException
+    {
+        Method computeNbPagesMethod = RecordManager.class.getDeclaredMethod( "computeNbPages", int.class );
+        computeNbPagesMethod.setAccessible( true );
+
+        assertEquals( 0, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, 0 ) ).intValue() );
+
+        for ( int i = 1; i < 21; i++ )
+        {
+            assertEquals( 1, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, i ) ).intValue() );
+        }
+
+        for ( int i = 21; i < 45; i++ )
+        {
+            assertEquals( 2, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, i ) ).intValue() );
+        }
+
+        for ( int i = 45; i < 68; i++ )
+        {
+            assertEquals( 3, ( ( Integer ) computeNbPagesMethod.invoke( recordManager, i ) ).intValue() );
+        }
+        
+        btree.close();
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java?rev=1510115&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerTest.java Sun Aug  4 09:22:56 2013
@@ -0,0 +1,881 @@
+/*
+ *  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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.directory.mavibot.btree.BTree;
+import org.apache.directory.mavibot.btree.Cursor;
+import org.apache.directory.mavibot.btree.RecordManager;
+import org.apache.directory.mavibot.btree.Tuple;
+import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * test the RecordManager
+ * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
+ */
+//@Ignore("ignoring till RM functionality is standardized")
+public class RecordManagerTest
+{
+    private BTree<Long, String> btree = null;
+
+    private RecordManager recordManager1 = null;
+
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+
+    private File dataDir = null;
+
+
+    @Before
+    public void createBTree()
+    {
+        dataDir = tempFolder.newFolder( UUID.randomUUID().toString() );
+
+        openRecordManagerAndBtree();
+
+        try
+        {
+            // Create a new BTree
+            btree = recordManager1.addBTree( "test", new LongSerializer(), new StringSerializer(), false );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    private void openRecordManagerAndBtree()
+    {
+        try
+        {
+            if ( recordManager1 != null )
+            {
+                recordManager1.close();
+            }
+
+            // Now, try to reload the file back
+            recordManager1 = new RecordManager( dataDir.getAbsolutePath() );
+
+            // load the last created btree
+            if ( btree != null )
+            {
+                btree = recordManager1.getManagedTree( btree.getName() );
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    /**
+     * Test the creation of a RecordManager, and that we can read it back.  
+     */
+    @Test
+    public void testRecordManager() throws IOException, BTreeAlreadyManagedException
+    {
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data.
+     */
+    @Test
+    public void testRecordManagerWithBTree() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
+    {
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        btree.insert( 1L, "V1" );
+        btree.insert( 5L, "V5" );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        assertTrue( btree1.hasKey( 1L ) );
+        assertTrue( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V3", btree1.get( 3L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data, enough for some Node to be created.
+     */
+    @Test
+    public void testRecordManagerWithBTreeLeafNode() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        // Now, add some elements in the BTree
+        for ( long i = 1L; i < 32L; i++ )
+        {
+            btree.insert( i, "V" + i );
+        }
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        for ( long i = 1L; i < 32L; i++ )
+        {
+            assertTrue( btree1.hasKey( i ) );
+            assertEquals( "V" + i, btree1.get( i ) );
+        }
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing 100 000 elements
+     */
+    @Test
+    //@Ignore("This is a performance test")
+    public void testRecordManagerWithBTreeLeafNode100K() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        // Don't keep any revision
+        recordManager1.setKeepRevisions( false );
+
+        String fileName = dataDir.getAbsolutePath() + "/mavibot.db";
+        File file = new File( fileName );
+        long fileSize = file.length();
+        long nbElems = 100000L;
+        System.out.println( "----- Size before = " + fileSize );
+
+        // Now, add some elements in the BTree
+        long t0 = System.currentTimeMillis();
+        for ( Long i = 0L; i < nbElems; i++ )
+        {
+            String value = "V" + i;
+            btree.insert( i, value );
+
+            /*
+            if ( !recordManager1.check() )
+            {
+                System.out.println( "Failure while adding element " + i );
+                fail();
+            }
+            */
+
+            if ( i % 10000 == 0 )
+            {
+                fileSize = file.length();
+                System.out.println( "----- Size after insertion of " + i + " = " + fileSize );
+                System.out.println( recordManager1 );
+                //System.out.println( btree );
+            }
+        }
+        long t1 = System.currentTimeMillis();
+
+        fileSize = file.length();
+        System.out.println( "Size after insertion of 100 000 elements : " + fileSize );
+        System.out.println( "Time taken to write 100 000 elements : " + ( t1 - t0 ) );
+        System.out.println( "  Nb elem/s : " + ( ( nbElems * 1000 ) / ( t1 - t0 ) ) );
+        System.out.println( "Nb created page " + recordManager1.nbCreatedPages.get() );
+        System.out.println( "Nb allocated page " + recordManager1.nbReusedPages.get() );
+        System.out.println( "Nb page we have freed " + recordManager1.nbFreedPages.get() );
+        System.out.println( recordManager1 );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        long t2 = System.currentTimeMillis();
+        for ( long i = 0L; i < nbElems; i++ )
+        {
+            //assertTrue( btree1.exist( i ) );
+            assertEquals( "V" + i, btree1.get( i ) );
+        }
+        long t3 = System.currentTimeMillis();
+        System.out.println( "Time taken to verify 100 000 elements : " + ( t3 - t2 ) );
+
+        // Check the stored element a second time
+        long t4 = System.currentTimeMillis();
+        for ( long i = 0L; i < nbElems; i++ )
+        {
+            //assertTrue( btree1.exist( i ) );
+            assertEquals( "V" + i, btree1.get( i ) );
+        }
+        long t5 = System.currentTimeMillis();
+        System.out.println( "Time taken to verify 100 000 elements : " + ( t5 - t4 ) );
+    }
+
+
+    private void checkBTreeRevisionBrowse( BTree btree, long revision, long... values ) throws IOException,
+        KeyNotFoundException
+    {
+        Cursor<Long, String> cursor = btree.browse( revision );
+        List<Long> expected = new ArrayList<Long>( values.length );
+        Set<Long> found = new HashSet<Long>( values.length );
+
+        for ( long value : values )
+        {
+            expected.add( value );
+        }
+
+        int nb = 0;
+
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> res = cursor.next();
+
+            long key = res.getKey();
+            assertEquals( expected.get( nb ), ( Long ) key );
+            assertFalse( found.contains( key ) );
+            found.add( key );
+            assertEquals( "V" + key, res.getValue() );
+            nb++;
+        }
+
+        assertEquals( values.length, nb );
+        cursor.close();
+    }
+
+
+    private void checkBTreeRevisionBrowseFrom( BTree btree, long revision, long from, long... values )
+        throws IOException,
+        KeyNotFoundException
+    {
+        Cursor<Long, String> cursor = btree.browseFrom( revision, from );
+        List<Long> expected = new ArrayList<Long>( values.length );
+        Set<Long> found = new HashSet<Long>( values.length );
+
+        for ( long value : values )
+        {
+            expected.add( value );
+        }
+
+        int nb = 0;
+
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> res = cursor.next();
+
+            long key = res.getKey();
+            assertEquals( expected.get( nb ), ( Long ) key );
+            assertFalse( found.contains( key ) );
+            found.add( key );
+            assertEquals( "V" + key, res.getValue() );
+            nb++;
+        }
+
+        assertEquals( values.length, nb );
+        cursor.close();
+
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data, where we keep the revisions, 
+     * and browse the BTree.
+     */
+    @Test
+    public void testRecordManagerBrowseWithKeepRevisions() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        recordManager1.setKeepRevisions( true );
+
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        long rev1 = btree.getRevision();
+
+        btree.insert( 1L, "V1" );
+        long rev2 = btree.getRevision();
+
+        btree.insert( 5L, "V5" );
+        long rev3 = btree.getRevision();
+
+        // Check that we can browse each revision
+        // revision 1
+        checkBTreeRevisionBrowse( btree, rev1, 3L );
+
+        // Revision 2
+        checkBTreeRevisionBrowse( btree, rev2, 1L, 3L );
+
+        // Revision 3
+        checkBTreeRevisionBrowse( btree, rev3, 1L, 3L, 5L );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        assertTrue( btree1.hasKey( 1L ) );
+        assertTrue( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V3", btree1.get( 3L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+
+        // Check that we can read the revision again
+        // revision 1
+        checkBTreeRevisionBrowse( btree, rev1, 3L );
+
+        // Revision 2
+        checkBTreeRevisionBrowse( btree, rev2, 1L, 3L );
+
+        // Revision 3
+        checkBTreeRevisionBrowse( btree, rev3, 1L, 3L, 5L );
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data, where we keep the revision, and 
+     * we browse from a key
+     */
+    @Test
+    public void testRecordManagerBrowseFromWithRevision() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        recordManager1.setKeepRevisions( true );
+
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        long rev1 = btree.getRevision();
+
+        btree.insert( 1L, "V1" );
+        long rev2 = btree.getRevision();
+
+        btree.insert( 5L, "V5" );
+        long rev3 = btree.getRevision();
+
+        // Check that we can browse each revision
+        // revision 1
+        checkBTreeRevisionBrowseFrom( btree, rev1, 3L, 3L );
+
+        // Revision 2
+        checkBTreeRevisionBrowseFrom( btree, rev2, 3L, 3L );
+
+        // Revision 3
+        checkBTreeRevisionBrowseFrom( btree, rev3, 3L, 3L, 5L );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        assertTrue( btree1.hasKey( 1L ) );
+        assertTrue( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V3", btree1.get( 3L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+
+        // Check that we can read the revision again
+        // revision 1
+        checkBTreeRevisionBrowseFrom( btree, rev1, 3L, 3L );
+
+        // Revision 2
+        checkBTreeRevisionBrowseFrom( btree, rev2, 3L, 3L );
+
+        // Revision 3
+        checkBTreeRevisionBrowseFrom( btree, rev3, 3L, 3L, 5L );
+    }
+
+
+    /**
+     * Test a get() from a given revision
+     */
+    @Test
+    public void testGetWithRevision() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        recordManager1.setKeepRevisions( true );
+
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        long rev1 = btree.getRevision();
+
+        btree.insert( 1L, "V1" );
+        long rev2 = btree.getRevision();
+
+        btree.insert( 5L, "V5" );
+        long rev3 = btree.getRevision();
+
+        // Delete one element
+        btree.delete( 3L );
+        long rev4 = btree.getRevision();
+
+        // Check that we can get a value from each revision
+        // revision 1
+        assertEquals( "V3", btree.get( rev1, 3L ) );
+
+        // revision 2
+        assertEquals( "V1", btree.get( rev2, 1L ) );
+        assertEquals( "V3", btree.get( rev2, 3L ) );
+
+        // revision 3
+        assertEquals( "V1", btree.get( rev3, 1L ) );
+        assertEquals( "V3", btree.get( rev3, 3L ) );
+        assertEquals( "V5", btree.get( rev3, 5L ) );
+
+        // revision 4
+        assertEquals( "V1", btree.get( rev4, 1L ) );
+        assertEquals( "V5", btree.get( rev4, 5L ) );
+
+        try
+        {
+            btree.get( rev4, 3L );
+            fail();
+        }
+        catch ( KeyNotFoundException knfe )
+        {
+            // expected
+        }
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        assertTrue( btree1.hasKey( 1L ) );
+        assertFalse( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+
+        // Check that we can get a value from each revision
+        // revision 1
+        assertEquals( "V3", btree.get( rev1, 3L ) );
+
+        // revision 2
+        assertEquals( "V1", btree.get( rev2, 1L ) );
+        assertEquals( "V3", btree.get( rev2, 3L ) );
+
+        // revision 3
+        assertEquals( "V1", btree.get( rev3, 1L ) );
+        assertEquals( "V3", btree.get( rev3, 3L ) );
+        assertEquals( "V5", btree.get( rev3, 5L ) );
+
+        // revision 4
+        assertEquals( "V1", btree.get( rev4, 1L ) );
+        assertEquals( "V5", btree.get( rev4, 5L ) );
+
+        try
+        {
+            btree.get( rev4, 3L );
+            fail();
+        }
+        catch ( KeyNotFoundException knfe )
+        {
+            // expected
+        }
+    }
+
+
+    /**
+     * Test a contain() from a given revision
+     */
+    @Test
+    public void testContainWithRevision() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        recordManager1.setKeepRevisions( true );
+
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        long rev1 = btree.getRevision();
+
+        btree.insert( 1L, "V1" );
+        long rev2 = btree.getRevision();
+
+        btree.insert( 5L, "V5" );
+        long rev3 = btree.getRevision();
+
+        // Delete one element
+        btree.delete( 3L );
+        long rev4 = btree.getRevision();
+
+        // Check that we can get a value from each revision
+        // revision 1
+        assertFalse( btree.contains( rev1, 1L, "V1" ) );
+        assertTrue( btree.contains( rev1, 3L, "V3" ) );
+        assertFalse( btree.contains( rev1, 5L, "V5" ) );
+
+        // revision 2
+        assertTrue( btree.contains( rev2, 1L, "V1" ) );
+        assertTrue( btree.contains( rev2, 3L, "V3" ) );
+        assertFalse( btree.contains( rev2, 5L, "V5" ) );
+
+        // revision 3
+        assertTrue( btree.contains( rev3, 1L, "V1" ) );
+        assertTrue( btree.contains( rev3, 3L, "V3" ) );
+        assertTrue( btree.contains( rev3, 5L, "V5" ) );
+
+        // revision 4
+        assertTrue( btree.contains( rev4, 1L, "V1" ) );
+        assertFalse( btree.contains( rev4, 3L, "V3" ) );
+        assertTrue( btree.contains( rev4, 5L, "V5" ) );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        assertTrue( btree1.hasKey( 1L ) );
+        assertFalse( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+
+        // Check that we can get a value from each revision
+        // revision 1
+        assertFalse( btree.contains( rev1, 1L, "V1" ) );
+        assertTrue( btree.contains( rev1, 3L, "V3" ) );
+        assertFalse( btree.contains( rev1, 5L, "V5" ) );
+
+        // revision 2
+        assertTrue( btree.contains( rev2, 1L, "V1" ) );
+        assertTrue( btree.contains( rev2, 3L, "V3" ) );
+        assertFalse( btree.contains( rev2, 5L, "V5" ) );
+
+        // revision 3
+        assertTrue( btree.contains( rev3, 1L, "V1" ) );
+        assertTrue( btree.contains( rev3, 3L, "V3" ) );
+        assertTrue( btree.contains( rev3, 5L, "V5" ) );
+
+        // revision 4
+        assertTrue( btree.contains( rev4, 1L, "V1" ) );
+        assertFalse( btree.contains( rev4, 3L, "V3" ) );
+        assertTrue( btree.contains( rev4, 5L, "V5" ) );
+    }
+
+
+    /**
+     * Test a hasKey() from a given revision
+     */
+    @Test
+    public void testHasKeyWithRevision() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        recordManager1.setKeepRevisions( true );
+
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        long rev1 = btree.getRevision();
+
+        btree.insert( 1L, "V1" );
+        long rev2 = btree.getRevision();
+
+        btree.insert( 5L, "V5" );
+        long rev3 = btree.getRevision();
+
+        // Delete one element
+        btree.delete( 3L );
+        long rev4 = btree.getRevision();
+
+        // Check that we can get a value from each revision
+        // revision 1
+        assertFalse( btree.hasKey( rev1, 1L ) );
+        assertTrue( btree.hasKey( rev1, 3L ) );
+        assertFalse( btree.hasKey( rev1, 5L ) );
+
+        // revision 2
+        assertTrue( btree.hasKey( rev2, 1L ) );
+        assertTrue( btree.hasKey( rev2, 3L ) );
+        assertFalse( btree.hasKey( rev2, 5L ) );
+
+        // revision 3
+        assertTrue( btree.hasKey( rev3, 1L ) );
+        assertTrue( btree.hasKey( rev3, 3L ) );
+        assertTrue( btree.hasKey( rev3, 5L ) );
+
+        // revision 4
+        assertTrue( btree.hasKey( rev4, 1L ) );
+        assertFalse( btree.hasKey( rev4, 3L ) );
+        assertTrue( btree.hasKey( rev4, 5L ) );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        assertEquals( 1, recordManager1.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager1.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+
+        // Check the stored element
+        assertTrue( btree1.hasKey( 1L ) );
+        assertFalse( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+
+        // Check that we can get a value from each revision
+        // revision 1
+        assertFalse( btree.hasKey( rev1, 1L ) );
+        assertTrue( btree.hasKey( rev1, 3L ) );
+        assertFalse( btree.hasKey( rev1, 5L ) );
+
+        // revision 2
+        assertTrue( btree.hasKey( rev2, 1L ) );
+        assertTrue( btree.hasKey( rev2, 3L ) );
+        assertFalse( btree.hasKey( rev2, 5L ) );
+
+        // revision 3
+        assertTrue( btree.hasKey( rev3, 1L ) );
+        assertTrue( btree.hasKey( rev3, 3L ) );
+        assertTrue( btree.hasKey( rev3, 5L ) );
+
+        // revision 4
+        assertTrue( btree.hasKey( rev4, 1L ) );
+        assertFalse( btree.hasKey( rev4, 3L ) );
+        assertTrue( btree.hasKey( rev4, 5L ) );
+    }
+
+
+    /**
+     * Test with BTrees containing duplicate keys
+     */
+    @Test
+    public void testBTreesDuplicateKeys() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        int pageSize = 8;
+        int numKeys = 2;
+        String name = "duplicateTree";
+
+        BTree<Long, String> dupsTree = new BTree( name, null, new LongSerializer(), new StringSerializer(), pageSize,
+            true );
+
+        recordManager1.manage( dupsTree );
+
+        for ( long i = 0; i < numKeys; i++ )
+        {
+            for ( int k = 0; k < pageSize + 1; k++ )
+            {
+                dupsTree.insert( i, String.valueOf( k ) );
+            }
+        }
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+
+        dupsTree = recordManager1.getManagedTree( name );
+
+        //        Cursor<Long, String> cursor1 = dupsTree.browse();
+        //        while( cursor1.hasNext() )
+        //        {
+        //            System.out.println( cursor1.next() );
+        //        }
+        //        cursor1.close();
+
+        for ( long i = 0; i < numKeys; i++ )
+        {
+            BTree<String, String> values = dupsTree.getValues( i );
+            //            Cursor<String, String> cursor = values.browse();
+            //            while( cursor.hasNext() )
+            //            {
+            //                System.out.println( cursor.next() );
+            //            }
+            //            cursor.close();
+
+            for ( int k = 0; k < pageSize + 1; k++ )
+            {
+                assertTrue( values.hasKey( String.valueOf( k ) ) );
+            }
+        }
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java?rev=1510115&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/RecordManagerWithDuplicatesTest.java Sun Aug  4 09:22:56 2013
@@ -0,0 +1,192 @@
+/*
+ *  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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.directory.mavibot.btree.BTree;
+import org.apache.directory.mavibot.btree.RecordManager;
+import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
+import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * test the RecordManager whith duplicate values
+ * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
+ */
+//@Ignore("ignoring till RM functionality is standardized")
+public class RecordManagerWithDuplicatesTest
+{
+    private BTree<Long, String> btree = null;
+
+    private RecordManager recordManager = null;
+
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+
+    private File dataDir = null;
+
+
+    @Before
+    public void createBTree()
+    {
+        dataDir = tempFolder.newFolder( UUID.randomUUID().toString() );
+
+        openRecordManagerAndBtree();
+
+        try
+        {
+            // Create a new BTree which allows duplicate values
+            btree = recordManager.addBTree( "test", new LongSerializer(), new StringSerializer(), true );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    private void openRecordManagerAndBtree()
+    {
+        try
+        {
+            if ( recordManager != null )
+            {
+                recordManager.close();
+            }
+
+            // Now, try to reload the file back
+            recordManager = new RecordManager( dataDir.getAbsolutePath() );
+
+            // load the last created btree
+            btree = recordManager.getManagedTree( "test" );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    /**
+     * Test the creation of a RecordManager, and that we can read it back.  
+     */
+    @Test
+    public void testRecordManager() throws IOException, BTreeAlreadyManagedException
+    {
+        assertEquals( 1, recordManager.getNbManagedTrees() );
+
+        Set<String> managedBTrees = recordManager.getManagedTrees();
+
+        assertEquals( 1, managedBTrees.size() );
+        assertTrue( managedBTrees.contains( "test" ) );
+
+        BTree btree1 = recordManager.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        assertEquals( btree.getFile(), btree1.getFile() );
+        assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
+        assertEquals( btree.getName(), btree1.getName() );
+        assertEquals( btree.getNbElems(), btree1.getNbElems() );
+        assertEquals( btree.getPageSize(), btree1.getPageSize() );
+        assertEquals( btree.getRevision(), btree1.getRevision() );
+        assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
+        assertTrue( btree.isAllowDuplicates() );
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data.
+     */
+    @Test
+    public void testRecordManagerWithBTreeSameValue() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        // Now, add some elements in the BTree
+        btree.insert( 3L, "V3" );
+        btree.insert( 3L, "V5" );
+
+        assertTrue( btree.contains( 3L, "V3" ) );
+        assertTrue( btree.contains( 3L, "V5" ) );
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+        assertNotNull( btree );
+
+        assertTrue( btree.contains( 3L, "V3" ) );
+        assertTrue( btree.contains( 3L, "V5" ) );
+    }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data.
+     */
+    @Test
+    public void testRecordManagerWithBTreeVariousValues() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        // Now, add some elements in the BTree
+        for ( long i = 1; i < 128; i++ )
+        {
+            String v1 = "V" + i;
+            btree.insert( i, v1 );
+
+            String v2 = "V" + i + 1;
+            btree.insert( i, v2 );
+        }
+
+        for ( long i = 1; i < 128; i++ )
+        {
+            String v1 = "V" + i;
+            String v2 = "V" + i + 1;
+            assertTrue( btree.contains( i, v1 ) );
+            assertTrue( btree.contains( i, v2 ) );
+
+        }
+
+        // Now, try to reload the file back
+        openRecordManagerAndBtree();
+        assertNotNull( btree );
+
+        for ( long i = 1; i < 128; i++ )
+        {
+            String v1 = "V" + i;
+            String v2 = "V" + i + 1;
+            assertTrue( btree.contains( i, v1 ) );
+            assertTrue( btree.contains( i, v2 ) );
+
+        }
+    }
+}