Author: elecharny
Date: Wed Mar 13 08:38:12 2013
New Revision: 1455840
URL: http://svn.apache.org/r1455840
Log:
o Added a enum to define the BTree type (in-memory, persisted and managed)
o Injected the RM into the BTree
o Added an Offset field in the BTree for when it's managed
o Update the BTree Header on disk when we modify the content of a Managed BTree
o Added toString() methods to the ValueHolder classes
o Injected the BTree in the ValueHolder classes
o Made the ValueHolder interface public
o Added an Offset in the BTree Pages to be able to retrieve them on disk
o First drop of code to save a Page on disk for Managed BTrees
o Added a method to access a ValueHolder from a Leaf, and the reference to the
children from a Node
o At the moment, Leaf store the values in memory only
o Modify the order in which the BTree header's element are stored, to be able
to update them with fixed position : the variable length fields are stored
after the fixed size ones
o Modified the readPages() so that we have an upper limit when we want to read
only a limited number of pages, to avoid spurious I/O
o Added the serailization of BTree pages
o Added a method to compute the number of pages needed to store some data
o Fixed various tests accordingly to those modifications
Added:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeTypeEnum.java
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/AbstractPage.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeFactory.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Leaf.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/MemoryValueHolder.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Node.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Page.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ReferenceValueHolder.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ValueHolder.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/store/RecordManager.java
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/BTreeFlushTest.java
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/LeafTest.java
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerPrivateMethodTest.java
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerTest.java
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/AbstractPage.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/AbstractPage.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/AbstractPage.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/AbstractPage.java
Wed Mar 13 08:38:12 2013
@@ -46,6 +46,9 @@ public abstract class AbstractPage<K, V>
/** The number of current values in the Page */
protected int nbElems;
+ /** The Page offset on disk if the BTree is managed */
+ private long offset;
+
/**
* Creates a default empty AbstractPage
@@ -273,6 +276,24 @@ public abstract class AbstractPage<K, V>
/**
+ * @return the offset
+ */
+ /* No qualifier */long getOffset()
+ {
+ return offset;
+ }
+
+
+ /**
+ * @param offset the offset to set
+ */
+ /* No qualifier */void setOffset( long offset )
+ {
+ this.offset = offset;
+ }
+
+
+ /**
* @see Object#toString()
*/
public String toString()
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTree.java
Wed Mar 13 08:38:12 2013
@@ -41,6 +41,7 @@ import org.apache.mavibot.btree.exceptio
import org.apache.mavibot.btree.serializer.BufferHandler;
import org.apache.mavibot.btree.serializer.ElementSerializer;
import org.apache.mavibot.btree.serializer.LongSerializer;
+import org.apache.mavibot.btree.store.RecordManager;
/**
@@ -86,6 +87,9 @@ public class BTree<K, V>
/** Number of entries in each Page. */
protected int pageSize;
+ /** The position on disk where this BTree is stored */
+ private long btreeOffset;
+
/** The size of the buffer used to write data in disk */
private int writeBufferSize;
@@ -101,8 +105,11 @@ public class BTree<K, V>
/** The associated file. If null, this is an in-memory btree */
private File file;
- /** A flag set to true when the BTree is a in-memory BTree */
- private boolean inMemory;
+ /** The RecordManager if the BTree is managed */
+ private RecordManager recordManager;
+
+ /** The BTree type : either in-memory, persistent or managed */
+ private BTreeTypeEnum type;
/** A flag used to tell the BTree that the journal is activated */
private boolean withJournal;
@@ -328,7 +335,7 @@ public class BTree<K, V>
if ( fileName == null )
{
- inMemory = true;
+ type = BTreeTypeEnum.IN_MEMORY;
}
else
{
@@ -347,7 +354,7 @@ public class BTree<K, V>
}
journal = new File( journalPath, journalName );
- inMemory = false;
+ type = BTreeTypeEnum.PERSISTENT;
}
pageSize = configuration.getPageSize();
@@ -427,7 +434,7 @@ public class BTree<K, V>
if ( ( path == null ) && ( file == null ) )
{
- inMemory = true;
+ type = BTreeTypeEnum.IN_MEMORY;
}
else
{
@@ -449,7 +456,7 @@ public class BTree<K, V>
this.journal = new File( path, file + JOURNAL_SUFFIX );
}
- inMemory = false;
+ type = BTreeTypeEnum.PERSISTENT;
}
setPageSize( pageSize );
@@ -479,7 +486,7 @@ public class BTree<K, V>
readTransactions = new ConcurrentLinkedQueue<Transaction<K, V>>();
// Create the queue containing the modifications, if it's not a
in-memory btree
- if ( !inMemory )
+ if ( type == BTreeTypeEnum.PERSISTENT )
{
modificationsQueue = new LinkedBlockingDeque<Modification<K, V>>();
}
@@ -551,7 +558,7 @@ public class BTree<K, V>
createTransactionManager();
// Initialize the Journal manager thread if it's not a in-memory btree
- if ( !inMemory && withJournal )
+ if ( ( type == BTreeTypeEnum.PERSISTENT ) && withJournal )
{
createJournalManager();
}
@@ -567,7 +574,7 @@ public class BTree<K, V>
readTransactionsThread.interrupt();
readTransactions.clear();
- if ( !inMemory )
+ if ( type == BTreeTypeEnum.PERSISTENT )
{
// Stop the journal manager thread, by injecting a poison pill into
// the queue this thread is using, so that all the epnding data
@@ -583,6 +590,24 @@ public class BTree<K, V>
/**
+ * @return the btreeOffset
+ */
+ public long getBtreeOffset()
+ {
+ return btreeOffset;
+ }
+
+
+ /**
+ * @param btreeOffset the btreeOffset to set
+ */
+ public void setBtreeOffset( long btreeOffset )
+ {
+ this.btreeOffset = btreeOffset;
+ }
+
+
+ /**
* Gets the number which is a power of 2 immediately above the given
positive number.
*/
private int getPowerOf2( int size )
@@ -635,6 +660,29 @@ public class BTree<K, V>
/**
+ * Gets the RecordManager for a managed BTree
+ *
+ * @return The recordManager if the BTree is managed
+ */
+ /* No qualifier */RecordManager getRecordManager()
+ {
+ return recordManager;
+ }
+
+
+ /**
+ * Inject a RecordManager for a managed BTree
+ *
+ * @param recordManager The injected RecordManager
+ */
+ /* No qualifier */void setRecordManager( RecordManager recordManager )
+ {
+ this.recordManager = recordManager;
+ this.type = BTreeTypeEnum.MANAGED;
+ }
+
+
+ /**
* @return the pageSize
*/
public int getPageSize()
@@ -784,7 +832,7 @@ public class BTree<K, V>
tuple = removeResult.getRemovedElement();
}
- if ( !inMemory )
+ if ( type == BTreeTypeEnum.PERSISTENT )
{
// Inject the modification into the modification queue
modificationsQueue.add( new Deletion<K, V>( key ) );
@@ -913,6 +961,13 @@ public class BTree<K, V>
rootPage = modifyResult.getModifiedPage();
modifiedValue = modifyResult.getModifiedValue();
+
+ // If the BTree is managed, we have to update the rootPage on
disk
+ if ( isManaged() )
+ {
+ // Update the BTree header now
+ recordManager.updateBtreeHeader( this, btreeOffset );
+ }
}
else
{
@@ -929,7 +984,7 @@ public class BTree<K, V>
}
// Inject the modification into the modification queue
- if ( !inMemory )
+ if ( type == BTreeTypeEnum.PERSISTENT )
{
modificationsQueue.add( new Addition<K, V>( key, value ) );
}
@@ -1251,7 +1306,7 @@ public class BTree<K, V>
*/
public void flush() throws IOException
{
- if ( !inMemory )
+ if ( type == BTreeTypeEnum.PERSISTENT )
{
// Then flush the file
flush( file );
@@ -1338,11 +1393,29 @@ public class BTree<K, V>
/**
- * @return the inMemory flag
+ * @return true if the BTree is fully in memory
*/
public boolean isInMemory()
{
- return inMemory;
+ return type == BTreeTypeEnum.IN_MEMORY;
+ }
+
+
+ /**
+ * @return true if the BTree is persisted on disk
+ */
+ public boolean isPersistent()
+ {
+ return type == BTreeTypeEnum.IN_MEMORY;
+ }
+
+
+ /**
+ * @return true if the BTree is managed by a RecordManager
+ */
+ public boolean isManaged()
+ {
+ return type == BTreeTypeEnum.MANAGED;
}
@@ -1354,13 +1427,13 @@ public class BTree<K, V>
*/
/* no qualifier */ValueHolder<K, V> createHolder( V value )
{
- if ( inMemory )
+ if ( type == BTreeTypeEnum.MANAGED )
{
- return new MemoryValueHolder<K, V>( value );
+ return new ReferenceValueHolder<K, V>( this, value, -1L );
}
else
{
- return new ReferenceValueHolder<K, V>( this, value );
+ return new MemoryValueHolder<K, V>( this, value );
}
}
@@ -1426,9 +1499,20 @@ public class BTree<K, V>
{
StringBuilder sb = new StringBuilder();
- if ( inMemory )
+ switch ( type )
{
- sb.append( "In-memory " );
+ case IN_MEMORY:
+ sb.append( "In-memory " );
+ break;
+
+ case MANAGED:
+ sb.append( "Managed " );
+ break;
+
+ case PERSISTENT:
+ sb.append( "Persistent " );
+ break;
+
}
sb.append( "BTree" );
@@ -1436,7 +1520,7 @@ public class BTree<K, V>
if ( rootPage != null )
{
- sb.append( ", nbEntries:" ).append( rootPage.getNbElems() );
+ sb.append( ", nbEntries:" ).append( nbElems );
}
else
{
@@ -1454,7 +1538,7 @@ public class BTree<K, V>
sb.append( comparator.getClass().getSimpleName() );
}
- if ( !inMemory )
+ if ( type == BTreeTypeEnum.PERSISTENT )
{
try
{
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeFactory.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeFactory.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeFactory.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeFactory.java
Wed Mar 13 08:38:12 2013
@@ -21,6 +21,7 @@ package org.apache.mavibot.btree;
import org.apache.mavibot.btree.serializer.ElementSerializer;
+import org.apache.mavibot.btree.store.RecordManager;
/**
@@ -175,4 +176,15 @@ public class BTreeFactory
{
btree.setPageSize( pageSize );
}
+
+
+ /**
+ * Set the RecordManager
+ *
+ * @param recordManager The injected RecordManager
+ */
+ public static void setRecordManager( BTree<?, ?> btree, RecordManager
recordManager )
+ {
+ btree.setRecordManager( recordManager );
+ }
}
Added:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeTypeEnum.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeTypeEnum.java?rev=1455840&view=auto
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeTypeEnum.java
(added)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/BTreeTypeEnum.java
Wed Mar 13 08:38:12 2013
@@ -0,0 +1,43 @@
+/*
+ * 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.mavibot.btree;
+
+
+/**
+ * An enum to describe the BTree type. We have three possible type :
+ * <ul>
+ * <li>IN_MEMORY : the BTree will remain in memory, and won't be persisted on
disk</li>
+ * <li>PERSISTENT : the BTree is in memory, but will be persisted on disk</li>
+ * <li>MANAGED : the BTree is managed by a RecordManager, and some pages may
+ * be swapped out from memory on demand</li>
+ * </ul>
+ * @author <a href="mailto:[email protected]">Mavibot labs Project</a>
+ */
+public enum BTreeTypeEnum
+{
+ /** Pure in-memory BTree, not persisted on disk */
+ IN_MEMORY,
+
+ /** In-memory BTree but persisted on disk */
+ PERSISTENT,
+
+ /** A BTree associated with a RecordManager */
+ MANAGED
+}
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Leaf.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Leaf.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
--- labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Leaf.java
(original)
+++ labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Leaf.java
Wed Mar 13 08:38:12 2013
@@ -20,6 +20,7 @@
package org.apache.mavibot.btree;
+import java.io.IOException;
import java.lang.reflect.Array;
import java.util.LinkedList;
@@ -64,8 +65,9 @@ public class Leaf<K, V> extends Abstract
/**
* {@inheritDoc}
+ * @throws IOException
*/
- public InsertResult<K, V> insert( long revision, K key, V value )
+ public InsertResult<K, V> insert( long revision, K key, V value ) throws
IOException
{
// Find the key into this leaf
int pos = findPos( key );
@@ -89,6 +91,17 @@ public class Leaf<K, V> extends Abstract
// We insert it into a copied page and return the result
Page<K, V> modifiedPage = addElement( revision, key, value, pos );
+ // If the BTree is managed, we now have to write the page on disk
+ // and to add this page to the list of modified pages
+ if ( btree.isManaged() )
+ {
+ ValueHolder holder = btree.getRecordManager()
+ .modifyPage( btree, this, revision, modifiedPage, revision
);
+
+ // Store the offset on disk in the page
+ ( ( AbstractPage<K, V> ) modifiedPage ).setOffset( ( (
ReferenceValueHolder ) holder ).getOffset() );
+ }
+
InsertResult<K, V> result = new ModifyResult<K, V>( modifiedPage,
null );
return result;
@@ -411,6 +424,22 @@ public class Leaf<K, V> extends Abstract
/**
* {@inheritDoc}
*/
+ public ValueHolder<K, V> getValue( int pos )
+ {
+ if ( pos < nbElems )
+ {
+ return values[pos];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
public Cursor<K, V> browse( K key, Transaction<K, V> transaction,
LinkedList<ParentPos<K, V>> stack )
{
int pos = findPos( key );
@@ -538,7 +567,10 @@ public class Leaf<K, V> extends Abstract
{
// First copy the current page, but add one element in the copied page
Leaf<K, V> newLeaf = new Leaf<K, V>( btree, revision, nbElems + 1 );
- ValueHolder<K, V> valueHolder = btree.createHolder( value );
+
+ // Atm, store the value in memory
+ ValueHolder<K, V> valueHolder = new MemoryValueHolder<K, V>( btree,
value );
+ //ValueHolder<K, V> valueHolder = btree.createHolder( value );
// Deal with the special case of an empty page
if ( nbElems == 0 )
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/MemoryValueHolder.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/MemoryValueHolder.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/MemoryValueHolder.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/MemoryValueHolder.java
Wed Mar 13 08:38:12 2013
@@ -20,8 +20,6 @@
package org.apache.mavibot.btree;
-
-
/**
* A In-Memory Value holder. The value is always present in memory.
*
@@ -31,6 +29,9 @@ package org.apache.mavibot.btree;
*/
/* No qualifier */class MemoryValueHolder<K, V> implements ValueHolder<K, V>
{
+ /** The BTree */
+ private BTree<K, V> btree;
+
/** The reference to the Value instance, or null if it's not present */
private V reference;
@@ -41,8 +42,9 @@ package org.apache.mavibot.btree;
* @param offset The offset in disk for this value
* @param value The value to store into a SoftReference
*/
- public MemoryValueHolder( V value )
+ public MemoryValueHolder( BTree<K, V> btree, V value )
{
+ this.btree = btree;
this.reference = value;
}
@@ -55,4 +57,23 @@ package org.apache.mavibot.btree;
{
return reference;
}
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( btree.getName() ).append( " : '" );
+
+ V value = getValue( btree );
+
+ sb.append( value );
+
+ sb.append( "'" );
+
+ return sb.toString();
+ }
}
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Node.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Node.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
--- labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Node.java
(original)
+++ labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Node.java
Wed Mar 13 08:38:12 2013
@@ -95,7 +95,7 @@ public class Node<K, V> extends Abstract
/**
* {@inheritDoc}
*/
- public InsertResult<K, V> insert( long revision, K key, V value )
+ public InsertResult<K, V> insert( long revision, K key, V value ) throws
IOException
{
// Find the key into this leaf
int pos = findPos( key );
@@ -774,6 +774,22 @@ public class Node<K, V> extends Abstract
/**
* {@inheritDoc}
*/
+ public Page<K, V> getReference( int pos )
+ {
+ if ( pos < nbElems + 1 )
+ {
+ return children[pos];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
public Cursor<K, V> browse( K key, Transaction<K, V> transaction,
LinkedList<ParentPos<K, V>> stack )
{
int pos = findPos( key );
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Page.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Page.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
--- labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Page.java
(original)
+++ labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/Page.java
Wed Mar 13 08:38:12 2013
@@ -59,7 +59,7 @@ public interface Page<K, V>
* @param value Inserted value
* @return Either a modified Page or an Overflow element if the Page was
full
*/
- InsertResult<K, V> insert( long revision, K key, V value );
+ InsertResult<K, V> insert( long revision, K key, V value ) throws
IOException;
/**
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ReferenceValueHolder.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ReferenceValueHolder.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ReferenceValueHolder.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ReferenceValueHolder.java
Wed Mar 13 08:38:12 2013
@@ -32,8 +32,11 @@ import java.lang.ref.SoftReference;
*
* @author <a href="mailto:[email protected]">Mavibot labs Project</a>
*/
-/* No qualifier */class ReferenceValueHolder<K, V> implements ValueHolder<K, V>
+public class ReferenceValueHolder<K, V> implements ValueHolder<K, V>
{
+ /** The BTree */
+ private BTree<K, V> btree;
+
/** The offset for a value stored on disk */
private long offset;
@@ -47,9 +50,10 @@ import java.lang.ref.SoftReference;
* @param offset The offset in disk for this value
* @param value The value to store into a SoftReference
*/
- public ReferenceValueHolder( BTree<K, V> btree, V value )
+ public ReferenceValueHolder( BTree<K, V> btree, V value, long offset )
{
- //this.offset = btree.getOffset();
+ this.btree = btree;
+ this.offset = offset;
this.reference = new SoftReference<V>( value );
}
@@ -80,4 +84,29 @@ import java.lang.ref.SoftReference;
{
return null;
}
+
+
+ /* No qualifier */long getOffset()
+ {
+ return offset;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( btree.getName() ).append( "[" ).append( offset ).append( "]
: '" );
+
+ V value = getValue( btree );
+
+ sb.append( value );
+
+ sb.append( "'" );
+
+ return sb.toString();
+ }
}
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ValueHolder.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ValueHolder.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ValueHolder.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/ValueHolder.java
Wed Mar 13 08:38:12 2013
@@ -29,7 +29,7 @@ package org.apache.mavibot.btree;
*
* @author <a href="mailto:[email protected]">Mavibot labs Project</a>
*/
-/* No qualifier */interface ValueHolder<K, V>
+public interface ValueHolder<K, V>
{
/**
* @param btree The Btree storing the value
Modified:
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/store/RecordManager.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/store/RecordManager.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/store/RecordManager.java
(original)
+++
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/store/RecordManager.java
Wed Mar 13 08:38:12 2013
@@ -34,12 +34,16 @@ import java.util.Set;
import org.apache.mavibot.btree.BTree;
import org.apache.mavibot.btree.BTreeFactory;
+import org.apache.mavibot.btree.Leaf;
import org.apache.mavibot.btree.Node;
import org.apache.mavibot.btree.Page;
+import org.apache.mavibot.btree.ReferenceValueHolder;
+import org.apache.mavibot.btree.ValueHolder;
import org.apache.mavibot.btree.exception.BTreeAlreadyManagedException;
import org.apache.mavibot.btree.exception.EndOfFileExceededException;
import org.apache.mavibot.btree.serializer.IntSerializer;
import org.apache.mavibot.btree.serializer.LongArraySerializer;
+import org.apache.mavibot.btree.serializer.LongSerializer;
import org.apache.mavinot.btree.utils.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -216,6 +220,7 @@ public class RecordManager
}
catch ( Exception e )
{
+ e.printStackTrace();
LOG.error( "Error while initializing the RecordManager : {}",
e.getMessage() );
}
}
@@ -247,7 +252,7 @@ public class RecordManager
nbBtree = 0;
firstFreePage = NO_PAGE;
lastFreePage = NO_PAGE;
- updateHeader();
+ updateRecordManagerHeader();
// Set the offset of the end of the file
endOfFileOffset = fileChannel.size();
@@ -302,12 +307,16 @@ public class RecordManager
// manage the modified pages. Once read, we can discard all
// the pages that are stored in it, as we have restarted
// the RecordManager.
- PageIO[] pageIos = readPages( HEADER_SIZE );
+ long btreeOffset = HEADER_SIZE;
+
+ PageIO[] pageIos = readPages( HEADER_SIZE, Long.MAX_VALUE );
long position = pageIos.length * pageSize + HEADER_SIZE;
// Create the BTree
copiedPageBTree = BTreeFactory.createBTree();
+ copiedPageBTree.setBtreeOffset( btreeOffset );
+ btreeOffset = position;
position = loadBTree( pageIos, position, copiedPageBTree );
// Then process the next ones
@@ -315,13 +324,15 @@ public class RecordManager
{
// Create the BTree
BTree<?, ?> btree = BTreeFactory.createBTree();
+ btree.setBtreeOffset( btreeOffset );
// Read the associated pages
- pageIos = readPages( position );
+ pageIos = readPages( position, Long.MAX_VALUE );
position = pageIos.length * pageSize;
// Load the BTree
position = loadBTree( pageIos, position, btree );
+ btreeOffset = position;
// Store it into the managedBtrees map
managedBTrees.put( btree.getName(), btree );
@@ -340,21 +351,31 @@ public class RecordManager
* @param position The position of the first page
* @return An array of pages
*/
- private PageIO[] readPages( long position ) throws IOException,
EndOfFileExceededException
+ private PageIO[] readPages( long position, long limit ) throws
IOException, EndOfFileExceededException
{
+ if ( limit <= 0 )
+ {
+ limit = Long.MAX_VALUE;
+ }
+
PageIO firstPage = fetchPage( position );
firstPage.setSize();
List<PageIO> listPages = new ArrayList<PageIO>();
listPages.add( firstPage );
+ long dataRead = pageSize - LONG_SIZE - INT_SIZE;
- // Iterate on the pages
- long nextPage = firstPage.getNextPage();
-
- while ( nextPage != NO_PAGE )
+ // Iterate on the pages, if needed
+ if ( dataRead < limit )
{
- PageIO page = fetchPage( nextPage );
- listPages.add( page );
- nextPage = page.getNextPage();
+ long nextPage = firstPage.getNextPage();
+
+ while ( ( nextPage != NO_PAGE ) && ( dataRead < limit ) )
+ {
+ PageIO page = fetchPage( nextPage );
+ listPages.add( page );
+ nextPage = page.getNextPage();
+ dataRead += pageSize - LONG_SIZE;
+ }
}
// Return
@@ -379,9 +400,27 @@ public class RecordManager
{
long dataPos = 0L;
+ // The BTree current revision
+ long revision = readLong( pageIos, dataPos );
+ BTreeFactory.setRevision( btree, revision );
+ dataPos += LONG_SIZE;
+
+ // The nb elems in the tree
+ int nbElems = readInt( pageIos, dataPos );
+ BTreeFactory.setNbElems( btree, nbElems );
+ dataPos += LONG_SIZE;
+
+ // The BTree rootPage offset
+ long rootPageOffset = readLong( pageIos, dataPos );
+ dataPos += LONG_SIZE;
+
+ // The BTree page size
+ int btreePageSize = readInt( pageIos, dataPos );
+ BTreeFactory.setPageSize( btree, btreePageSize );
+ dataPos += INT_SIZE;
+
// The tree name
byte[] btreeNameBytes = readBytes( pageIos, dataPos );
-
dataPos += INT_SIZE;
if ( btreeNameBytes != null )
@@ -431,33 +470,15 @@ public class RecordManager
BTreeFactory.setValueSerializer( btree, valueSerializerFqcn );
- // The BTree page size
- int btreePageSize = readInt( pageIos, dataPos );
- BTreeFactory.setPageSize( btree, btreePageSize );
- dataPos += INT_SIZE;
-
- // The BTree current revision
- long revision = readLong( pageIos, dataPos );
- BTreeFactory.setRevision( btree, revision );
- dataPos += LONG_SIZE;
-
- // The nb elems in the tree
- int nbElems = readInt( pageIos, dataPos );
- BTreeFactory.setNbElems( btree, nbElems );
- dataPos += LONG_SIZE;
-
- // Now, int the BTree
+ // Now, init the BTree
btree.init();
- // The BTree rootPage offset
- long rootPageOffset = readLong( pageIos, dataPos );
-
// Now, load the rootPage, which can be a Leaf or a Node, depending
// on the number of elements in the tree : if it's above the pageSize,
// it's a Node, otherwise it's a Leaf
// Read the rootPage pages on disk
- PageIO[] rootPageIos = readPages( rootPageOffset );
+ PageIO[] rootPageIos = readPages( rootPageOffset, Long.MAX_VALUE );
position += rootPageIos.length * pageSize;
Page btreeRoot = readPage( btree, revision, rootPageIos );
@@ -473,7 +494,7 @@ public class RecordManager
Page node = BTreeFactory.createNode( btree, revision, nbElems );
// Read the rootPage pages on disk
- PageIO[] pageIos = readPages( offset );
+ PageIO[] pageIos = readPages( offset, Long.MAX_VALUE );
return node;
}
@@ -734,6 +755,8 @@ public class RecordManager
*/
public synchronized void manage( BTree<?, ?> btree ) throws
BTreeAlreadyManagedException, IOException
{
+ BTreeFactory.setRecordManager( btree, this );
+
String name = btree.getName();
if ( managedBTrees.containsKey( name ) )
@@ -767,6 +790,10 @@ public class RecordManager
// Get the pageIOs we need to store the data. We may need more than
one.
PageIO[] pageIos = getFreePageIOs( bufferSize );
+ // Store the BTree Offset into the BTree
+ long btreeOffset = pageIos[0].getOffset();
+ btree.setBtreeOffset( btreeOffset );
+
// Now store the BTree data in the pages :
// - the BTree name
// - the keySerializer FQCN
@@ -778,18 +805,6 @@ public class RecordManager
// Starts at 0
long position = 0L;
- // The tree name
- position = store( position, btreeNameBytes, pageIos );
-
- // The keySerializer FQCN
- position = store( position, keySerializerBytes, pageIos );
-
- // The valueSerialier FQCN
- position = store( position, valueSerializerBytes, pageIos );
-
- // The BTree page size
- position = store( position, btree.getPageSize(), pageIos );
-
// The BTree current revision
position = store( position, btree.getRevision(), pageIos );
@@ -799,7 +814,7 @@ public class RecordManager
// Serialize the BTree root page
Page rootPage = BTreeFactory.getRoot( btree );
- PageIO[] rootPageIos = createSerializedPage( btree.getRevision(),
rootPage );
+ PageIO[] rootPageIos = serializePage( btree, btree.getRevision(),
rootPage );
// Get the reference on the first page
PageIO rootPageIo = rootPageIos[0];
@@ -807,6 +822,18 @@ public class RecordManager
// Now, we can inject the BTree rootPage offset into the BTree header
position = store( position, rootPageIo.getOffset(), pageIos );
+ // The BTree page size
+ position = store( position, btree.getPageSize(), pageIos );
+
+ // The tree name
+ position = store( position, btreeNameBytes, pageIos );
+
+ // The keySerializer FQCN
+ position = store( position, keySerializerBytes, pageIos );
+
+ // The valueSerialier FQCN
+ position = store( position, valueSerializerBytes, pageIos );
+
// And flush the pages to disk now
flushPages( pageIos );
flushPages( rootPageIos );
@@ -814,7 +841,7 @@ public class RecordManager
nbBtree++;
// Last, not last, update the number of managed BTrees in the header
- updateHeader();
+ updateRecordManagerHeader();
}
@@ -835,7 +862,7 @@ public class RecordManager
* @return An array of pages containing the serialized node
* @throws IOException
*/
- private PageIO[] createSerializedPage( long revision, Page page ) throws
IOException
+ private PageIO[] serializePage( BTree btree, long revision, Page page )
throws IOException
{
int nbElems = page.getNbElems();
@@ -871,8 +898,68 @@ public class RecordManager
}
else
{
- // Allocate the array to store the result
- PageIO[] pageIos = new PageIO[1];
+ // Prepare a list of byte[] that will contain the serialized page
+ int nbBuffers = 1 + 1 + nbElems * 2;
+ int dataSize = 0;
+
+ if ( page instanceof Node )
+ {
+ // A Node has one more value to store
+ nbBuffers++;
+ }
+
+ // Now, we can create the list with the right size
+ List<byte[]> serializedData = new ArrayList<byte[]>( nbBuffers );
+
+ // The revision
+ byte[] buffer = LongSerializer.serialize( revision );
+ serializedData.add( buffer );
+ dataSize += buffer.length;
+
+ // The number of elements
+ buffer = IntSerializer.serialize( nbElems );
+ serializedData.add( buffer );
+ dataSize += buffer.length;
+
+ // Iterate on the keys
+ for ( int pos = 0; pos < nbElems; pos++ )
+ {
+ // Start with the value
+ if ( page instanceof Node )
+ {
+ Page child = ( ( Node ) page ).getReference( pos );
+ //serializedData.add(
btree.getValueSerializer().serialize( child..get );
+ }
+ else
+ {
+ ValueHolder value = ( ( Leaf ) page ).getValue( pos );
+ buffer = btree.getValueSerializer().serialize(
value.getValue( btree ) );
+ serializedData.add( buffer );
+ dataSize += buffer.length;
+ }
+
+ // and the key
+ buffer = btree.getKeySerializer().serialize( page.getKey( pos
) );
+ serializedData.add( buffer );
+ dataSize += buffer.length;
+ }
+
+ // Nodes have one mor evalue to serialize
+ if ( page instanceof Node )
+ {
+ // TODO
+ }
+
+ // We are done. Allocate the pages we need to store the data
+ PageIO[] pageIos = getFreePageIOs( dataSize );
+
+ // And store the data into those pages
+ long position = 0L;
+
+ for ( byte[] bytes : serializedData )
+ {
+ position = storeRaw( position, bytes, pageIos );
+ }
return pageIos;
}
@@ -882,7 +969,7 @@ public class RecordManager
/**
* Update the header, injecting the nbBtree, firstFreePage and lastFreePage
*/
- private void updateHeader() throws IOException
+ private void updateRecordManagerHeader() throws IOException
{
// The page size
ByteBuffer header = ByteBuffer.allocate( HEADER_SIZE );
@@ -906,6 +993,43 @@ public class RecordManager
/**
+ * Update the BTree header after a BTree modification. We update the
following fields :
+ * <ul>
+ * <li>the revision</li>
+ * <li>the number of elements</li>
+ * <li>the rootPage offset</li>
+ * </ul>
+ * @param btree
+ * @throws IOException
+ * @throws EndOfFileExceededException
+ */
+ public void updateBtreeHeader( BTree btree, long rootPageOffset ) throws
EndOfFileExceededException, IOException
+ {
+ // Read the pageIOs associated with this BTree
+ long offset = btree.getBtreeOffset();
+ long headerSize = LONG_SIZE + LONG_SIZE + LONG_SIZE;
+
+ PageIO[] pageIos = readPages( offset, headerSize );
+
+ // Now, update the revision
+ long position = 0;
+
+ position = store( position, btree.getRevision(), pageIos );
+ position = store( position, btree.getNbElems(), pageIos );
+ position = store( position, rootPageOffset, pageIos );
+
+ // Flush only the needed pages : we have stored the revision, the
number of elements
+ // and the rootPage offset, three longs.
+ int nbPages = computeNbPages( ( int ) headerSize );
+
+ for ( int i = 0; i < nbPages; i++ )
+ {
+ flushPages( pageIos[i] );
+ }
+ }
+
+
+ /**
* Write the pages in the disk, either at the end of the file, or at
* the position they were taken from.
*
@@ -1026,6 +1150,72 @@ public class RecordManager
/**
+ * Stores a byte[] into one ore more pageIO (depending if the long is
stored
+ * across a boundary or not). We don't add the byte[] size, it's already
present
+ * in the received byte[].
+ *
+ * @param position The position in a virtual byte[] if all the pages were
contiguous
+ * @param bytes The byte[] to serialize
+ * @param pageIos The pageIOs we have to store the data in
+ * @return The new position
+ */
+ private long storeRaw( long position, byte[] bytes, PageIO... pageIos )
+ {
+ if ( bytes != null )
+ {
+ // Compute the page in which we will store the data given the
+ // current position
+ int pageNb = computePageNb( position );
+
+ // Get back the buffer in this page
+ ByteBuffer pageData = pageIos[pageNb].getData();
+
+ // Compute the position in the current page
+ int pagePos = ( int ) ( position + ( pageNb + 1 ) * LONG_SIZE +
INT_SIZE ) - pageNb * pageSize;
+
+ // Compute the remaining size in the page
+ int remaining = pageData.capacity() - pagePos;
+ int nbStored = bytes.length;
+
+ // And now, write the bytes until we have none
+ while ( nbStored > 0 )
+ {
+ if ( remaining > nbStored )
+ {
+ pageData.mark();
+ pageData.position( pagePos );
+ pageData.put( bytes, bytes.length - nbStored, nbStored );
+ pageData.reset();
+ nbStored = 0;
+ }
+ else
+ {
+ pageData.mark();
+ pageData.position( pagePos );
+ pageData.put( bytes, bytes.length - nbStored, remaining );
+ pageData.reset();
+ pageNb++;
+ pageData = pageIos[pageNb].getData();
+ pagePos = LINK_SIZE;
+ nbStored -= remaining;
+ remaining = pageData.capacity() - pagePos;
+ }
+ }
+
+ // We are done
+ position += bytes.length;
+ }
+ else
+ {
+ // No bytes : write 0 and return
+ position = store( position, 0, pageIos );
+ }
+
+ return position;
+ }
+
+
+ /**
* Stores an Integer into one ore more pageIO (depending if the int is
stored
* across a boundary or not)
*
@@ -1208,21 +1398,47 @@ public class RecordManager
/**
- * Get as many pages as needed to store the data which size is provided
- *
- * @param dataSize The data size
- * @return An array of pages, enough to store the full data
+ * Stores a new page on disk. We will add the modified page into the tree
of copied pages.
+ * The new page is serialized and saved on disk.
+ *
+ * @param oldPage
+ * @param oldRevision
+ * @param newPage
+ * @param newRevision
+ * @return The offset of the new page
+ * @throws IOException
*/
- private PageIO[] getFreePageIOs( int dataSize ) throws IOException
+ public ValueHolder modifyPage( BTree btree, Page oldPage, long
oldRevision, Page newPage, long newRevision )
+ throws IOException
{
- if ( dataSize == 0 )
+ // We first need to save the new page on disk
+ PageIO[] pageIos = serializePage( btree, newRevision, newPage );
+
+ // Write the page on disk
+ flushPages( pageIos );
+
+ // Build the resulting reference
+ ValueHolder valueHolder = new ReferenceValueHolder( btree, newPage,
pageIos[0].getOffset() );
+
+ return valueHolder;
+ }
+
+
+ /**
+ * Compute the number of pages needed to store some specific size of data.
+ *
+ * @param dataSize The size of the data we want to store in pages
+ * @return The number of pages needed
+ */
+ private int computeNbPages( int dataSize )
+ {
+ if ( dataSize <= 0 )
{
- return new PageIO[]
- {};
+ return 0;
}
// Compute the number of pages needed.
- // Considering that each page coan contain PageSize bytes,
+ // Considering that each page can contain PageSize bytes,
// but that the first 8 bytes are used for links and we
// use 4 bytes to store the data size, the number of needed
// pages is :
@@ -1244,6 +1460,26 @@ public class RecordManager
}
}
+ return nbNeededPages;
+ }
+
+
+ /**
+ * Get as many pages as needed to store the data which size is provided
+ *
+ * @param dataSize The data size
+ * @return An array of pages, enough to store the full data
+ */
+ private PageIO[] getFreePageIOs( int dataSize ) throws IOException
+ {
+ if ( dataSize == 0 )
+ {
+ return new PageIO[]
+ {};
+ }
+
+ int nbNeededPages = computeNbPages( dataSize );
+
PageIO[] pageIOs = new PageIO[nbNeededPages];
// The first page : set the size
@@ -1474,7 +1710,7 @@ public class RecordManager
for ( int i = 0; i < nbBTree; i++ )
{
System.out.println( " Btree[" + i + "]" );
- PageIO[] pageIos = readPages( position );
+ PageIO[] pageIos = readPages( position, Long.MAX_VALUE );
for ( PageIO pageIo : pageIos )
{
Modified:
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/BTreeFlushTest.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/BTreeFlushTest.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/BTreeFlushTest.java
(original)
+++
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/BTreeFlushTest.java
Wed Mar 13 08:38:12 2013
@@ -33,7 +33,6 @@ import org.apache.mavibot.btree.exceptio
import org.apache.mavibot.btree.serializer.IntSerializer;
import org.apache.mavibot.btree.serializer.LongSerializer;
import org.apache.mavibot.btree.serializer.StringSerializer;
-import org.junit.BeforeClass;
import org.junit.Test;
@@ -44,9 +43,6 @@ import org.junit.Test;
*/
public class BTreeFlushTest
{
- /** A file containing 100 000 elements */
- private static String data100K;
-
// Some values to inject in a btree
private static int[] sortedValues = new int[]
{
@@ -116,7 +112,7 @@ public class BTreeFlushTest
};
- private static void create1MElementsFile() throws IOException
+ private String create100KElementsFile() throws IOException
{
Random random = new Random( System.nanoTime() );
@@ -146,7 +142,7 @@ public class BTreeFlushTest
System.out.println( "Error while adding " + value );
nbError++;
- return;
+ return null;
}
if ( i % 10000 == 0 )
@@ -181,14 +177,7 @@ public class BTreeFlushTest
System.out.println( "Time to flush 100 000 elements : " + ( t1 - t0 )
+ "ms" );
btree.close();
- data100K = tempFile.getCanonicalPath();
- }
-
-
- @BeforeClass
- public static void setup() throws IOException
- {
- create1MElementsFile();
+ return tempFile.getCanonicalPath();
}
@@ -294,6 +283,7 @@ public class BTreeFlushTest
@Test
public void testLoadBTreeFromFile() throws Exception
{
+ String data100K = create100KElementsFile();
File dataFile = new File( data100K );
BTree<Long, String> btree = new BTree<Long, String>(
"test",
Modified:
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/LeafTest.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/LeafTest.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/LeafTest.java
(original)
+++
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/LeafTest.java
Wed Mar 13 08:38:12 2013
@@ -64,8 +64,9 @@ public class LeafTest
/**
* A helper method to insert elements in a Leaf
+ * @throws IOException
*/
- private Leaf<Long, String> insert( Leaf<Long, String> leaf, long key,
String value )
+ private Leaf<Long, String> insert( Leaf<Long, String> leaf, long key,
String value ) throws IOException
{
InsertResult<Long, String> result = leaf.insert( 1L, key, value );
@@ -206,9 +207,10 @@ public class LeafTest
/**
* Check that deleting an element from a leaf with N/2 element works when
we borrow
* an element in a left page with more than N/2 elements
+ * @throws IOException
*/
@Test
- public void testDeleteBorrowingFromLeftSibling()
+ public void testDeleteBorrowingFromLeftSibling() throws IOException
{
Node<Long, String> parent = new Node<Long, String>( btree, 1L, 2 );
Leaf<Long, String> left = new Leaf<Long, String>( btree );
@@ -275,9 +277,10 @@ public class LeafTest
/**
* Check that deleting an element from a leaf with N/2 element works when
we borrow
* an element in a right page with more than N/2 elements
+ * @throws IOException
*/
@Test
- public void testDeleteBorrowingFromRightSibling()
+ public void testDeleteBorrowingFromRightSibling() throws IOException
{
Node<Long, String> parent = new Node<Long, String>( btree, 1L, 2 );
Leaf<Long, String> left = new Leaf<Long, String>( btree );
@@ -345,9 +348,10 @@ public class LeafTest
/**
* Check that deleting an element from a leaf with N/2 element works when
we merge
* it with one of its sibling, if both has N/2 elements
+ * @throws IOException
*/
@Test
- public void testDeleteMergeWithSibling()
+ public void testDeleteMergeWithSibling() throws IOException
{
Node<Long, String> parent = new Node<Long, String>( btree, 1L, 2 );
Leaf<Long, String> left = new Leaf<Long, String>( btree );
Modified:
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerPrivateMethodTest.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerPrivateMethodTest.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerPrivateMethodTest.java
(original)
+++
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerPrivateMethodTest.java
Wed Mar 13 08:38:12 2013
@@ -73,4 +73,38 @@ public class RecordManagerPrivateMethodT
assertEquals( 3, pages.length );
}
}
+
+
+ /**
+ * Test the ComputeNbPages method
+ */
+ @Test
+ public void testComputeNbPages() throws IOException, SecurityException,
NoSuchMethodException,
+ IllegalArgumentException, IllegalAccessException,
InvocationTargetException
+ {
+ File tempFile = File.createTempFile( "mavibot", ".db" );
+ String tempFileName = tempFile.getAbsolutePath();
+ tempFile.deleteOnExit();
+
+ RecordManager recordManager = new RecordManager( tempFileName, 32 );
+ 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() );
+ }
+ }
}
Modified:
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerTest.java
URL:
http://svn.apache.org/viewvc/labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerTest.java?rev=1455840&r1=1455839&r2=1455840&view=diff
==============================================================================
---
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerTest.java
(original)
+++
labs/mavibot/trunk/mavibot/src/test/java/org/apache/mavibot/btree/store/RecordManagerTest.java
Wed Mar 13 08:38:12 2013
@@ -36,12 +36,14 @@ import org.junit.Test;
/**
- *
+ * test the RecordManager
* @author <a href="mailto:[email protected]">Mavibot labs Project</a>
*/
public class RecordManagerTest
{
-
+ /**
+ * Test the creation of a RecordManager, and that we can read it back.
+ */
@Test
public void testRecordManager() throws IOException,
BTreeAlreadyManagedException
{
@@ -83,5 +85,57 @@ public class RecordManagerTest
assertEquals( btree.getPageSize(), btree1.getPageSize() );
assertEquals( btree.getRevision(), btree1.getRevision() );
assertEquals( btree.getValueSerializer().getClass().getName(),
btree1.getValueSerializer().getClass().getName() );
+
+ recordManager1.close();
+ }
+
+
+ /**
+ * Test the creation of a RecordManager with a BTree containing data.
+ */
+ @Test
+ public void testRecordManagerWithBTree() throws IOException,
BTreeAlreadyManagedException
+ {
+ 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() );
+
+ // And make it managed by the RM
+ recordManager.manage( btree );
+
+ // Now, add some elemnts in the BTree
+ btree.insert( 1L, "V1" );
+
+ // 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 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() );
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]