directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1527458 [11/14] - in /directory/mavibot/trunk/mavibot: img/ src/main/java/org/apache/directory/mavibot/btree/ src/main/java/org/apache/directory/mavibot/btree/managed/ src/main/java/org/apache/directory/mavibot/btree/memory/ src/main/java/...
Date Mon, 30 Sep 2013 06:32:28 GMT
Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/ReadTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/ReadTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/ReadTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/ReadTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,355 @@
+/*
+ *  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.managed;
+
+
+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.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * Test the RecordManager.readXXX() methods using reflection
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ReadTest
+{
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+
+    /**
+     * Test the readInt method
+     */
+    @Test
+    public void testReadInt() throws Exception
+    {
+        File tempFile = tempFolder.newFile( "mavibot.db" );
+        String tempFileName = tempFile.getAbsolutePath();
+
+        // 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 = tempFolder.newFile( "mavibot.db" );
+        String tempFileName = tempFile.getAbsolutePath();
+
+        // 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 = tempFolder.newFile( "mavibot.db" );
+        String tempFileName = tempFile.getAbsolutePath();
+
+        // 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
+        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
+        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 );
+        }
+
+        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
+        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 );
+        }
+
+        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/managed/RecordManagerFreePageTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerFreePageTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerFreePageTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerFreePageTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,184 @@
+/*
+ *  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.managed;
+
+
+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.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:dev@directory.apache.org">Apache Directory 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() );
+
+        CursorImpl<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/managed/RecordManagerPrivateMethodTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerPrivateMethodTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerPrivateMethodTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerPrivateMethodTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,143 @@
+/*
+ *  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.managed;
+
+
+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.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:dev@directory.apache.org">Apache Directory 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 = 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 = ( PageIO[] ) getFreePageIOsMethod.invoke( recordManager, 0 );
+
+        assertEquals( 0, pages.length );
+
+        for ( int i = 1; i < 20; i++ )
+        {
+            pages = ( PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
+            assertEquals( 1, pages.length );
+        }
+
+        for ( int i = 21; i < 44; i++ )
+        {
+            pages = ( PageIO[] ) getFreePageIOsMethod.invoke( recordManager, i );
+            assertEquals( 2, pages.length );
+        }
+
+        for ( int i = 45; i < 68; i++ )
+        {
+            pages = ( 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/managed/RecordManagerTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,873 @@
+/*
+ *  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.managed;
+
+
+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.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:dev@directory.apache.org">Apache Directory Project</a>
+ */
+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<Long, String> btree1 = recordManager1.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        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.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.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.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<Long, String> btree, long revision, long... values )
+        throws IOException,
+        KeyNotFoundException
+    {
+        CursorImpl<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<Long, String> btree, long revision, long from, long... values )
+        throws IOException,
+        KeyNotFoundException
+    {
+        CursorImpl<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.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.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.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.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.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<Long, String>( 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++ )
+        {
+            DuplicateKeyVal<String> dupVal = dupsTree.getValues( i );
+            //            Cursor<String, String> cursor = values.browse();
+            //            while( cursor.hasNext() )
+            //            {
+            //                System.out.println( cursor.next() );
+            //            }
+            //            cursor.close();
+
+            BTree<String, String> values = dupVal.getSubTree();
+
+            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/managed/RecordManagerWithDuplicatesTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerWithDuplicatesTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerWithDuplicatesTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/RecordManagerWithDuplicatesTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,189 @@
+/*
+ *  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.managed;
+
+
+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.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:dev@directory.apache.org">Apache Directory Project</a>
+ */
+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<Long, String> btree1 = recordManager.getManagedTree( "test" );
+
+        assertNotNull( btree1 );
+        assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
+        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 ) );
+
+        }
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/StoreTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/StoreTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/StoreTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/managed/StoreTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,460 @@
+/*
+ *  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.managed;
+
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+
+/**
+ * Test the RecordManager.store() method using reflection
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class StoreTest
+{
+    @Rule
+    public TemporaryFolder tempFolder = new TemporaryFolder();
+
+    /**
+     * Test the store( int ) method
+     */
+    @Test
+    public void testInjectInt() throws Exception
+    {
+        File tempFile = tempFolder.newFile( "mavibot.db" );
+        String tempFileName = tempFile.getAbsolutePath();
+
+        RecordManager recordManager = new RecordManager( tempFileName, 4 * 1024 );
+        Method method = RecordManager.class.getDeclaredMethod( "store", long.class, int.class, PageIO[].class );
+        method.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
+        long position = ( Long ) method.invoke( recordManager, 0, 0x12345678, pageIos );
+
+        assertEquals( 4, position );
+        int pos = 12;
+        assertEquals( 0x12, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x34, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x56, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x78, pageIos[0].getData().get( pos++ ) );
+
+        // Set the int at the end of the first page
+        position = ( Long ) method.invoke( recordManager, 4080, 0x12345678, pageIos );
+
+        assertEquals( 4084, position );
+        pos = 4092;
+        assertEquals( 0x12, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x34, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x56, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x78, pageIos[0].getData().get( pos++ ) );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 1 byte overlapping
+        position = ( Long ) method.invoke( recordManager, 4081, 0x12345678, pageIos );
+
+        assertEquals( 4085, position );
+        pos = 4093;
+        assertEquals( 0x12, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x34, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x56, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( 0x78, pageIos[1].getData().get( pos++ ) );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 2 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4082, 0x12345678, pageIos );
+
+        assertEquals( 4086, position );
+        pos = 4094;
+        assertEquals( 0x12, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x34, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( 0x56, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x78, pageIos[1].getData().get( pos++ ) );
+
+        // Set the int at the end of the first page and overlapping on the second page
+        // 3 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4083, 0x12345678, pageIos );
+
+        assertEquals( 4087, position );
+        pos = 4095;
+        assertEquals( 0x12, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( 0x34, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x56, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x78, pageIos[1].getData().get( pos++ ) );
+
+        // Set the int at the beginning of the second page
+        position = ( Long ) method.invoke( recordManager, 4084, 0x12345678, pageIos );
+
+        assertEquals( 4088, position );
+        pos = 8;
+        assertEquals( 0x12, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x34, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x56, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x78, pageIos[1].getData().get( pos++ ) );
+    }
+
+
+    /**
+     * Test the store( long ) method
+     */
+    @Test
+    public void testInjectLong() throws Exception
+    {
+        File tempFile = tempFolder.newFile( "mavibot.db" );
+        String tempFileName = tempFile.getAbsolutePath();
+
+        RecordManager recordManager = new RecordManager( tempFileName, 4 * 1024 );
+        Method method = RecordManager.class.getDeclaredMethod( "store", long.class, long.class, PageIO[].class );
+        method.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 long at the beginning
+        long position = ( Long ) method.invoke( recordManager, 0, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 8, position );
+        int pos = 12;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[0].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page
+        position = ( Long ) method.invoke( recordManager, 4076, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4084, position );
+        pos = 4088;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[0].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 1 byte overlapping
+        position = ( Long ) method.invoke( recordManager, 4077, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4085, position );
+        pos = 4089;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 2 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4078, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4086, position );
+        pos = 4090;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 3 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4079, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4087, position );
+        pos = 4091;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( ( byte ) 0xAB, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 4 byte overlapping
+        position = ( Long ) method.invoke( recordManager, 4080, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4088, position );
+        pos = 4092;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( ( byte ) 0x89, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 5 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4081, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4089, position );
+        pos = 4093;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( 0x67, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 6 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4082, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4090, position );
+        pos = 4094;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( 0x45, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the end of the first page and overlapping on the second page
+        // 7 bytes overlapping
+        position = ( Long ) method.invoke( recordManager, 4083, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4091, position );
+        pos = 4095;
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        pos = 8;
+        assertEquals( 0x23, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+
+        // Set the long at the beginning of the second page
+        position = ( Long ) method.invoke( recordManager, 4084, 0x0123456789ABCDEFL, pageIos );
+
+        assertEquals( 4092, position );
+        pos = 8;
+        assertEquals( 0x01, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[1].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0x89, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xAB, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xCD, pageIos[1].getData().get( pos++ ) );
+        assertEquals( ( byte ) 0xEF, pageIos[1].getData().get( pos++ ) );
+    }
+
+
+    /**
+     * Test the store( bytes ) method
+     */
+    @Test
+    public void testInjectBytes() throws Exception
+    {
+        File tempFile = tempFolder.newFile( "mavibot.db" );
+        String tempFileName = tempFile.getAbsolutePath();
+
+        // We use smaller pages
+        RecordManager recordManager = new RecordManager( tempFileName, 32 );
+        Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, byte[].class, PageIO[].class );
+        storeMethod.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 );
+
+        assertEquals( 8, position );
+        int pos = 12;
+        // The byte length
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x04, pageIos[0].getData().get( pos++ ) );
+        // The data
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( pos++ ) );
+
+        // Set the bytes at the end of the first page
+        position = ( Long ) storeMethod.invoke( recordManager, 12L, bytes, pageIos );
+
+        assertEquals( 20, position );
+        pos = 24;
+        // The byte length
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x04, pageIos[0].getData().get( pos++ ) );
+        // The data
+        assertEquals( 0x01, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x23, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x45, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x67, pageIos[0].getData().get( 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 );
+
+        assertEquals( 20, position );
+        pos = 12;
+        // The byte length
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x10, pageIos[0].getData().get( pos++ ) );
+
+        // The data
+        for ( int i = 0; i < 16; i++ )
+        {
+            assertEquals( ( byte ) ( i + 1 ), pageIos[0].getData().get( pos++ ) );
+        }
+
+        // Write the bytes over 2 pages
+        position = ( Long ) storeMethod.invoke( recordManager, 15L, bytes, pageIos );
+
+        assertEquals( 35, position );
+        pos = 27;
+        // The byte length
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x10, pageIos[0].getData().get( pos++ ) );
+
+        // The data in the first page
+        assertEquals( 1, pageIos[0].getData().get( pos++ ) );
+
+        // and in the second page
+        pos = 8;
+
+        for ( int i = 0; i < 15; i++ )
+        {
+            assertEquals( ( byte ) ( i + 2 ), pageIos[1].getData().get( 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 );
+
+        assertEquals( 86, position );
+        pos = 14;
+        // The byte length
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x00, pageIos[0].getData().get( pos++ ) );
+        assertEquals( 0x50, pageIos[0].getData().get( pos++ ) );
+
+        // The data in the first page
+        for ( int i = 0; i < 14; i++ )
+        {
+            assertEquals( ( byte ) ( i + 1 ), pageIos[0].getData().get( pos++ ) );
+        }
+
+        // The data in the second page
+        pos = 8;
+        for ( int i = 14; i < 38; i++ )
+        {
+            assertEquals( ( byte ) ( i + 1 ), pageIos[1].getData().get( pos++ ) );
+        }
+
+        // The data in the third page
+        pos = 8;
+        for ( int i = 38; i < 62; i++ )
+        {
+            assertEquals( ( byte ) ( i + 1 ), pageIos[2].getData().get( pos++ ) );
+        }
+
+        // The data in the forth page
+        pos = 8;
+        for ( int i = 62; i < 80; i++ )
+        {
+            assertEquals( ( byte ) ( i + 1 ), pageIos[3].getData().get( pos++ ) );
+        }
+    }
+}

Added: directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/memory/BTreeBuilderTest.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/memory/BTreeBuilderTest.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/memory/BTreeBuilderTest.java (added)
+++ directory/mavibot/trunk/mavibot/src/test/java/org/apache/directory/mavibot/btree/memory/BTreeBuilderTest.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,79 @@
+/*
+ *   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.memory;
+
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.mavibot.btree.Cursor;
+import org.apache.directory.mavibot.btree.Tuple;
+import org.apache.directory.mavibot.btree.serializer.IntSerializer;
+import org.junit.Test;
+
+
+/**
+ * Test cases for BTreeBuilder.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class BTreeBuilderTest
+{
+    @Test
+    public void testIntegerTree() throws IOException
+    {
+        List<Tuple<Integer, Integer>> sortedTuple = new ArrayList<Tuple<Integer, Integer>>();
+        for ( int i = 1; i < 8; i++ )
+        {
+            Tuple<Integer, Integer> t = new Tuple<Integer, Integer>( i, i );
+            sortedTuple.add( t );
+        }
+
+        IntSerializer ser = new IntSerializer();
+        BTreeBuilder<Integer, Integer> bb = new BTreeBuilder<Integer, Integer>( "master", 4, ser, ser );
+
+        // contains 1, 2, 3, 4, 5, 6, 7
+        BTree<Integer, Integer> btree = bb.build( sortedTuple.iterator() );
+
+        assertEquals( 1, btree.rootPage.getNbElems() );
+
+        assertEquals( 7, btree.rootPage.findRightMost().getKey().intValue() );
+
+        assertEquals( 1, btree.rootPage.findLeftMost().getKey().intValue() );
+
+        Cursor<Integer, Integer> cursor = btree.browse();
+        int i = 0;
+        while ( cursor.hasNext() )
+        {
+            Tuple<Integer, Integer> expected = sortedTuple.get( i++ );
+            Tuple<Integer, Integer> actual = cursor.next();
+            assertEquals( expected.getKey(), actual.getKey() );
+            assertEquals( expected.getValue(), actual.getValue() );
+        }
+
+        cursor.close();
+        btree.close();
+    }
+
+}



Mime
View raw message