You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by el...@apache.org on 2013/04/04 15:59:46 UTC

svn commit: r1464552 - in /labs/mavibot/branches/mavibot-multivalue-support/mavibot/src: main/java/org/apache/mavibot/btree/ test/java/org/apache/mavibot/btree/

Author: elecharny
Date: Thu Apr  4 13:59:46 2013
New Revision: 1464552

URL: http://svn.apache.org/r1464552
Log:
o Implemented the BTree.get( revision, K ) method
o Added a test for this method
o The delete() method was not flushing the data on disk
o The Recordmanager.write() method was using a useless parameter (the old page), removed.

Modified:
    labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
    labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Node.java
    labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java
    labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RevisionNameSerializer.java
    labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/test/java/org/apache/mavibot/btree/RecordManagerTest.java

Modified: labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
URL: http://svn.apache.org/viewvc/labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java?rev=1464552&r1=1464551&r2=1464552&view=diff
==============================================================================
--- labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java (original)
+++ labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java Thu Apr  4 13:59:46 2013
@@ -802,12 +802,6 @@ public class BTree<K, V>
 
         Tuple<K, V> deleted = delete( key, revision );
 
-        // Decrease the number of element in the current tree if the delete is successful
-        if ( deleted != null )
-        {
-            btreeHeader.decrementNbElems();
-        }
-
         return deleted;
     }
 
@@ -838,12 +832,6 @@ public class BTree<K, V>
 
         Tuple<K, V> deleted = delete( key, value, revision );
 
-        // Decrease the number of element in the current tree if the delete is successful
-        if ( deleted != null )
-        {
-            btreeHeader.decrementNbElems();
-        }
-
         return deleted;
     }
 
@@ -893,15 +881,31 @@ public class BTree<K, V>
                 return null;
             }
 
+            // Keep the oldRootPage so that we can later access it
+            Page<K, V> oldRootPage = rootPage;
+
             if ( result instanceof RemoveResult )
             {
                 // The element was found, and removed
                 RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
 
-                Page<K, V> newPage = removeResult.getModifiedPage();
+                Page<K, V> modifiedPage = removeResult.getModifiedPage();
+
+                if ( isManaged() )
+                {
+                    // Write the modified page on disk
+                    // Note that we don't use the holder, the new root page will
+                    // remain in memory.
+                    ElementHolder<Page<K, V>, K, V> holder = recordManager.writePage( this, modifiedPage,
+                        revision );
+
+                    // Store the offset on disk in the page in memory
+                    ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( ( ReferenceHolder<Page<K, V>, K, V> ) holder )
+                        .getOffset() );
+                }
 
                 // This is a new root
-                rootPage = newPage;
+                rootPage = modifiedPage;
                 tuple = removeResult.getRemovedElement();
             }
 
@@ -911,6 +915,32 @@ public class BTree<K, V>
                 modificationsQueue.add( new Deletion<K, V>( key ) );
             }
 
+            // Decrease the number of elements in the current tree if the deletion is successful
+            if ( tuple != null )
+            {
+                btreeHeader.decrementNbElems();
+
+                // If the BTree is managed, we have to update the rootPage on disk
+                if ( isManaged() )
+                {
+                    // Update the BTree header now
+                    recordManager.updateBtreeHeader( this, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
+                }
+            }
+
+            // Store the created rootPage into the revision BTree
+            if ( keepRevisions )
+            {
+                if ( isManaged() )
+                {
+                    recordManager.storeRootPage( this, rootPage );
+                }
+                else
+                {
+                    // Todo
+                }
+            }
+
             // Return the value we have found if it was modified
             return tuple;
         }
@@ -939,6 +969,26 @@ public class BTree<K, V>
 
 
     /**
+     * Find a value in the tree, given its key, at a specific revision. If the key is not found,
+     * it will throw a KeyNotFoundException. <br/>
+     * Note that we can get a null value stored, or many values.
+     * 
+     * @param revision The revision for which we want to find a key
+     * @param key The key we are looking at
+     * @return The found value, or null if the key is not present in the tree
+     * @throws KeyNotFoundException If the key is not found in the BTree
+     * @throws IOException TODO
+     */
+    public V get( long revision, K key ) throws IOException, KeyNotFoundException
+    {
+        // Fetch the root page for this revision
+        Page<K, V> revisionRootPage = getRootPage( revision );
+
+        return revisionRootPage.get( key );
+    }
+
+
+    /**
      * Checks if the given key exists.
      *  
      * @param key The key we are looking at
@@ -1067,7 +1117,7 @@ public class BTree<K, V>
      * @param revision The revision to use
      * @return Existing value, if any.
      */
-    /* No qualifier*/V insert( K key, V value, long revision ) throws IOException
+    /*No qualifier*/V insert( K key, V value, long revision ) throws IOException
     {
         if ( key == null )
         {
@@ -1083,9 +1133,6 @@ public class BTree<K, V>
         // a Node or a Leaf
         InsertResult<K, V> result = rootPage.insert( revision, key, value );
 
-        // Keep the old RootPage so that we can later access it
-        Page<K, V> oldRootPage = rootPage;
-
         if ( result instanceof ModifyResult )
         {
             ModifyResult<K, V> modifyResult = ( ( ModifyResult<K, V> ) result );
@@ -1097,7 +1144,7 @@ public class BTree<K, V>
                 // Write the modified page on disk
                 // Note that we don't use the holder, the new root page will
                 // remain in memory.
-                ElementHolder<Page<K, V>, K, V> holder = recordManager.writePage( this, rootPage, modifiedPage,
+                ElementHolder<Page<K, V>, K, V> holder = recordManager.writePage( this, modifiedPage,
                     revision );
 
                 // Store the offset on disk in the page in memory
@@ -1126,14 +1173,14 @@ public class BTree<K, V>
             // and to keep a track of the two offsets for the upper node
             if ( isManaged() )
             {
-                ElementHolder<Page<K, V>, K, V> holderLeft = recordManager.writePage( this, rootPage,
+                ElementHolder<Page<K, V>, K, V> holderLeft = recordManager.writePage( this,
                     ( ( SplitResult ) result ).getLeftPage(), revision );
 
                 // Store the offset on disk in the page
                 ( ( AbstractPage ) ( ( SplitResult ) result ).getLeftPage() )
                     .setOffset( ( ( ReferenceHolder ) holderLeft ).getOffset() );
 
-                ElementHolder<Page<K, V>, K, V> holderRight = recordManager.writePage( this, rootPage,
+                ElementHolder<Page<K, V>, K, V> holderRight = recordManager.writePage( this,
                     ( ( SplitResult ) result ).getRightPage(),
                     revision );
 
@@ -1155,7 +1202,7 @@ public class BTree<K, V>
             if ( isManaged() )
             {
                 ElementHolder<Page<K, V>, K, V> holder = recordManager
-                    .writePage( this, rootPage, newRootPage, revision );
+                    .writePage( this, newRootPage, revision );
 
                 // Store the offset on disk in the page
                 ( ( AbstractPage<K, V> ) newRootPage ).setOffset( ( ( ReferenceHolder ) holder ).getOffset() );
@@ -1177,12 +1224,12 @@ public class BTree<K, V>
             btreeHeader.incrementNbElems();
         }
 
-        // Store the old RootPage into the 
+        // Store the created rootPage into the revision BTree
         if ( keepRevisions )
         {
             if ( isManaged() )
             {
-                recordManager.storeRootPage( this, oldRootPage );
+                recordManager.storeRootPage( this, rootPage );
             }
             else
             {

Modified: labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Node.java
URL: http://svn.apache.org/viewvc/labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Node.java?rev=1464552&r1=1464551&r2=1464552&view=diff
==============================================================================
--- labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Node.java (original)
+++ labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Node.java Thu Apr  4 13:59:46 2013
@@ -972,7 +972,7 @@ import org.apache.mavibot.btree.exceptio
     {
         if ( btree.isManaged() )
         {
-            ElementHolder<Page<K, V>, K, V> holder = btree.getRecordManager().writePage( btree, this,
+            ElementHolder<Page<K, V>, K, V> holder = btree.getRecordManager().writePage( btree,
                 page,
                 revision );
 

Modified: labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java
URL: http://svn.apache.org/viewvc/labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java?rev=1464552&r1=1464551&r2=1464552&view=diff
==============================================================================
--- labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java (original)
+++ labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RecordManager.java Thu Apr  4 13:59:46 2013
@@ -877,13 +877,14 @@ public class RecordManager
         btree.setBtreeOffset( btreeOffset );
 
         // Now store the BTree data in the pages :
-        // - the BTree name
-        // - the keySerializer FQCN
-        // - the valueSerializer FQCN
-        // - the BTree page size
         // - the BTree revision
         // - the BTree number of elements
         // - The RootPage offset
+        // - The next Btree offset 
+        // - the BTree page size
+        // - the BTree name
+        // - the keySerializer FQCN
+        // - the valueSerializer FQCN
         // Starts at 0
         long position = 0L;
 
@@ -1532,7 +1533,7 @@ public class RecordManager
      * @return The offset of the new page
      * @throws IOException 
      */
-    /* No qualifier*/ElementHolder writePage( BTree btree, Page oldPage, Page newPage, long newRevision )
+    /* No qualifier*/ElementHolder writePage( BTree btree, Page newPage, long newRevision )
         throws IOException
     {
         // We first need to save the new page on disk

Modified: labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RevisionNameSerializer.java
URL: http://svn.apache.org/viewvc/labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RevisionNameSerializer.java?rev=1464552&r1=1464551&r2=1464552&view=diff
==============================================================================
--- labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RevisionNameSerializer.java (original)
+++ labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/RevisionNameSerializer.java Thu Apr  4 13:59:46 2013
@@ -40,7 +40,9 @@ import org.apache.mavibot.btree.util.Str
  */
 public class RevisionNameSerializer extends AbstractElementSerializer<RevisionName>
 {
-
+    /**
+     * Create a new instance of a RevisionNameSerializer
+     */
     public RevisionNameSerializer()
     {
         super( new RevisionNameComparator() );
@@ -49,6 +51,7 @@ public class RevisionNameSerializer exte
 
     /**
      * A static method used to deserialize a RevisionName from a byte array.
+     * 
      * @param in The byte array containing the RevisionName
      * @return A RevisionName instance
      */
@@ -60,6 +63,7 @@ public class RevisionNameSerializer exte
 
     /**
      * A static method used to deserialize a RevisionName from a byte array.
+     * 
      * @param in The byte array containing the RevisionName
      * @param start the position in the byte[] we will deserialize the RevisionName from
      * @return A RevisionName instance
@@ -145,6 +149,9 @@ public class RevisionNameSerializer exte
     }
 
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public RevisionName deserialize( BufferHandler bufferHandler ) throws IOException
     {
@@ -171,10 +178,31 @@ public class RevisionNameSerializer exte
     }
 
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public RevisionName deserialize( ByteBuffer buffer ) throws IOException
     {
-        // TODO Auto-generated method stub
-        return null;
+        // The revision
+        long revision = buffer.getLong();
+
+        // The name's length
+        int len = buffer.getInt();
+
+        switch ( len )
+        {
+            case 0:
+                return new RevisionName( revision, "" );
+
+            case -1:
+                return new RevisionName( revision, null );
+
+            default:
+                byte[] nameBytes = new byte[len];
+                buffer.get( nameBytes );
+
+                return new RevisionName( revision, Strings.utf8ToString( nameBytes ) );
+        }
     }
 }

Modified: labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/test/java/org/apache/mavibot/btree/RecordManagerTest.java
URL: http://svn.apache.org/viewvc/labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/test/java/org/apache/mavibot/btree/RecordManagerTest.java?rev=1464552&r1=1464551&r2=1464552&view=diff
==============================================================================
--- labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/test/java/org/apache/mavibot/btree/RecordManagerTest.java (original)
+++ labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/test/java/org/apache/mavibot/btree/RecordManagerTest.java Thu Apr  4 13:59:46 2013
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertEqu
 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;
@@ -530,4 +531,125 @@ public class RecordManagerTest
         // Revision 3
         checkBTreeRevisionBrowseFrom( btree, rev3, 3L, 3L, 5L );
     }
+
+
+    /**
+     * Test a get() from a given revision
+     */
+    @Test
+    public void testGetWithRevision() throws IOException, BTreeAlreadyManagedException,
+        KeyNotFoundException
+    {
+        File tempFile = File.createTempFile( "mavibot", ".db" );
+        String tempFileName = tempFile.getAbsolutePath();
+        tempFile.deleteOnExit();
+
+        RecordManager recordManager = new RecordManager( tempFileName, 32 );
+
+        assertNotNull( recordManager );
+
+        // Create a new BTree
+        BTree<Long, String> btree = new BTree<Long, String>( "test", new LongSerializer(), new StringSerializer() );
+        btree.setKeepRevisions( true );
+
+        // And make it managed by the RM
+        recordManager.manage( btree );
+
+        // 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
+        RecordManager recordManager1 = new RecordManager( tempFileName );
+
+        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
+        }
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org