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