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/03 18:38:58 UTC

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

Author: elecharny
Date: Wed Apr  3 16:38:58 2013
New Revision: 1464093

URL: http://svn.apache.org/r1464093
Log:
o First drop of code to allow a user to access old revisions
o Moved the getOffset() method to the Page interface
o Added a first test for the access of old revisions

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/Page.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/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=1464093&r1=1464092&r2=1464093&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 Wed Apr  3 16:38:58 2013
@@ -127,6 +127,9 @@ public class BTree<K, V>
     /** Flag to enable duplicate key support */
     private boolean allowDuplicates;
 
+    /** A flag set to true if we want to keep old revisions */
+    private boolean keepRevisions = false;
+
 
     /**
      * Create a thread that is responsible of cleaning the transactions when
@@ -1005,6 +1008,28 @@ public class BTree<K, V>
 
 
     /**
+     * Creates a cursor starting at the beginning of the tree, for a given revision
+     * 
+     * @param revision The revision we would like to browse
+     * @return A cursor on the btree
+     * @throws IOException
+     */
+    public Cursor<K, V> browse( long revision ) throws IOException, KeyNotFoundException
+    {
+        Transaction<K, V> transaction = beginReadTransaction();
+
+        // Fetch the root page for this revision
+        LinkedList<ParentPos<K, V>> stack = new LinkedList<ParentPos<K, V>>();
+
+        Page<K, V> revisionRootPage = getRootPage( revision );
+
+        Cursor<K, V> cursor = revisionRootPage.browse( transaction, stack );
+
+        return cursor;
+    }
+
+
+    /**
      * Insert an entry in the BTree.
      * <p>
      * We will replace the value if the provided key already exists in the
@@ -1033,6 +1058,9 @@ 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 );
@@ -1124,6 +1152,19 @@ public class BTree<K, V>
             btreeHeader.incrementNbElems();
         }
 
+        // Store the old RootPage into the 
+        if ( keepRevisions )
+        {
+            if ( isManaged() )
+            {
+                recordManager.storeRootPage( this, oldRootPage );
+            }
+            else
+            {
+                // Todo
+            }
+        }
+
         // Return the value we have found if it was modified
         return modifiedValue;
     }
@@ -1431,6 +1472,20 @@ public class BTree<K, V>
     }
 
 
+    private Page<K, V> getRootPage( long revision ) throws IOException, KeyNotFoundException
+    {
+        if ( isManaged() )
+        {
+            return recordManager.getRootPage( this, revision );
+        }
+        else
+        {
+            // Atm, the in-memory BTree does not support searches in many revisions
+            return rootPage;
+        }
+    }
+
+
     /**
      * Flush the latest revision to disk. We will replace the current file by the new one, as
      * we flush in a temporary file.
@@ -1658,6 +1713,9 @@ public class BTree<K, V>
     }
 
 
+    /**
+     * @return true if this BTree allow duplicate values
+     */
     public boolean isAllowDuplicates()
     {
         return allowDuplicates;
@@ -1665,6 +1723,24 @@ public class BTree<K, V>
 
 
     /**
+     * @return the keepRevisions
+     */
+    public boolean isKeepRevisions()
+    {
+        return keepRevisions;
+    }
+
+
+    /**
+     * @param keepRevisions the keepRevisions to set
+     */
+    public void setKeepRevisions( boolean keepRevisions )
+    {
+        this.keepRevisions = keepRevisions;
+    }
+
+
+    /**
      * @see Object#toString()
      */
     public String toString()
@@ -1688,6 +1764,7 @@ public class BTree<K, V>
         }
 
         sb.append( "BTree" );
+        sb.append( "[" ).append( btreeHeader.getName() ).append( "]" );
         sb.append( "( pageSize:" ).append( btreeHeader.getPageSize() );
 
         if ( rootPage != null )

Modified: labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Page.java
URL: http://svn.apache.org/viewvc/labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Page.java?rev=1464093&r1=1464092&r2=1464093&view=diff
==============================================================================
--- labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Page.java (original)
+++ labs/mavibot/branches/mavibot-multivalue-support/mavibot/src/main/java/org/apache/mavibot/btree/Page.java Wed Apr  3 16:38:58 2013
@@ -242,4 +242,10 @@ import org.apache.mavibot.btree.exceptio
      * @throws IOException If we have an error while trying to access the page
      */
     boolean hasKey( K key ) throws IOException;
+
+
+    /**
+     * @return the offset
+     */
+    long getOffset();
 }

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=1464093&r1=1464092&r2=1464093&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 Wed Apr  3 16:38:58 2013
@@ -34,6 +34,7 @@ import java.util.Set;
 
 import org.apache.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.mavibot.btree.exception.EndOfFileExceededException;
+import org.apache.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.mavibot.btree.serializer.IntSerializer;
 import org.apache.mavibot.btree.serializer.LongArraySerializer;
 import org.apache.mavibot.btree.serializer.LongSerializer;
@@ -81,8 +82,8 @@ public class RecordManager
      **/
     private BTree<Integer, long[]> copiedPageBTree;
 
-    /** A BTree used to store all the vlid revisions for all the stroed BTrees */
-    private BTree<RevisionName, long[]> revisionBTree;
+    /** A BTree used to store all the valid revisions for all the stored BTrees */
+    private BTree<RevisionName, Long> revisionBTree;
 
     /** A constant for an offset on a non existing page */
     private static final long NO_PAGE = -1L;
@@ -266,8 +267,8 @@ public class RecordManager
         copiedPageBTree = new BTree<Integer, long[]>( "copiedPageBTree", new IntSerializer(), new LongArraySerializer() );
 
         // and initialize the Revision BTree
-        revisionBTree = new BTree<RevisionName, long[]>( "revisionBTree", new RevisionNameSerializer(),
-            new LongArraySerializer() );
+        revisionBTree = new BTree<RevisionName, Long>( "revisionBTree", new RevisionNameSerializer(),
+            new LongSerializer() );
 
         // Inject these BTrees into the RecordManager
         try
@@ -1873,6 +1874,50 @@ public class RecordManager
 
 
     /**
+     * Store a reference to an old rootPage into the Revision BTree
+     * 
+     * @param btree The BTree we want to keep an old RootPage for
+     * @param rootPage The old rootPage
+     * @throws IOException If we have an issue while writing on disk
+     */
+    /* No qualifier */void storeRootPage( BTree btree, Page rootPage ) throws IOException
+    {
+        RevisionName revisionName = new RevisionName( rootPage.getRevision(), btree.getName() );
+
+        revisionBTree.insert( revisionName, rootPage.getOffset() );
+    }
+
+
+    /**
+     * Fetch the rootPage of a given BTree for a given revision.
+     * 
+     * @param btree The BTree we are interested in
+     * @param revision The revision we want to get back
+     * @return The rootPage for this BTree and this revision, if any
+     * @throws KeyNotFoundException If we can't find the rootPage for this revision and this BTree
+     * @throws IOException If we had an ise while accessing the data on disk
+     */
+    /* No qualifier */Page getRootPage( BTree btree, long revision ) throws KeyNotFoundException, IOException
+    {
+        if ( btree.getRevision() == revision )
+        {
+            // We are asking for the current revision
+            return btree.rootPage;
+        }
+
+        RevisionName revisionName = new RevisionName( revision, btree.getName() );
+        long rootPageOffset = revisionBTree.get( revisionName );
+
+        // Read the rootPage pages on disk
+        PageIO[] rootPageIos = readPages( rootPageOffset, Long.MAX_VALUE );
+
+        Page btreeRoot = readPage( btree, rootPageIos );
+
+        return btreeRoot;
+    }
+
+
+    /**
      * Get one managed trees, knowing its name. 
      * 
      * @return The managed BTrees

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=1464093&r1=1464092&r2=1464093&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 Wed Apr  3 16:38:58 2013
@@ -28,8 +28,6 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Set;
 
-import org.apache.mavibot.btree.BTree;
-import org.apache.mavibot.btree.RecordManager;
 import org.apache.mavibot.btree.exception.BTreeAlreadyManagedException;
 import org.apache.mavibot.btree.exception.KeyNotFoundException;
 import org.apache.mavibot.btree.serializer.LongSerializer;
@@ -294,4 +292,145 @@ public class RecordManagerTest
 
         System.out.println( "File size : " + tempFile.length() );
     }
+
+
+    /**
+     * Test the creation of a RecordManager with a BTree containing data, where we keep the revisions.
+     */
+    @Test
+    public void testRecordManagerWithBTreeKeepRevisions() 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();
+
+        // Check that we can browse each revision
+        // revision 1
+        Cursor<Long, String> cursor = btree.browse( rev1 );
+
+        int nb = 0;
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> res = cursor.next();
+            nb++;
+
+            assertEquals( 3L, ( long ) res.getKey() );
+            assertEquals( "V3", res.getValue() );
+        }
+
+        assertEquals( 1, nb );
+        cursor.close();
+
+        // Revision 2
+        cursor = btree.browse( rev2 );
+
+        nb = 0;
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> res = cursor.next();
+            nb++;
+
+            switch ( nb )
+            {
+                case 1:
+                    assertEquals( 1L, ( long ) res.getKey() );
+                    assertEquals( "V1", res.getValue() );
+                    break;
+
+                case 2:
+                    assertEquals( 3L, ( long ) res.getKey() );
+                    assertEquals( "V3", res.getValue() );
+                    break;
+            }
+        }
+
+        assertEquals( 2, nb );
+        cursor.close();
+
+        // Revision 3
+        cursor = btree.browse( rev3 );
+
+        nb = 0;
+        while ( cursor.hasNext() )
+        {
+            Tuple<Long, String> res = cursor.next();
+            nb++;
+
+            switch ( nb )
+            {
+                case 1:
+                    assertEquals( 1L, ( long ) res.getKey() );
+                    assertEquals( "V1", res.getValue() );
+                    break;
+
+                case 2:
+                    assertEquals( 3L, ( long ) res.getKey() );
+                    assertEquals( "V3", res.getValue() );
+                    break;
+
+                case 3:
+                    assertEquals( 5L, ( long ) res.getKey() );
+                    assertEquals( "V5", res.getValue() );
+                    break;
+            }
+        }
+
+        assertEquals( 3, nb );
+        cursor.close();
+
+        // Close the recordManager
+        recordManager.close();
+
+        // 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 ) );
+        assertTrue( btree1.hasKey( 3L ) );
+        assertTrue( btree1.hasKey( 5L ) );
+        assertEquals( "V1", btree1.get( 1L ) );
+        assertEquals( "V3", btree1.get( 3L ) );
+        assertEquals( "V5", btree1.get( 5L ) );
+    }
 }



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