Author: elecharny
Date: Fri Mar 15 10:58:16 2013
New Revision: 1456886
URL: http://svn.apache.org/r1456886
Log:
o Added a method in AbtsractPage to inject a key into a specific position (used
by the deserialization process)
o Added a method in Leaf and Node to store a value at a given position (used by
the deserialization process)
o Moved all the BTree common data into a BTreeHeader class
o Added the NextBtreeOffset field to manage the links between btrees
o Made the MemoryValueHolder public
o Improved the ReferenceValueHolder toString() method
o Now manage the link between BTrees in the RM
o Fixed the Page serialization/deserialization
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/ReferenceValueHolder.java
labs/mavibot/trunk/mavibot/src/main/java/org/apache/mavibot/btree/store/RecordManager.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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -276,6 +276,17 @@ public abstract class AbstractPage<K, V>
/**
+ * Set the key at a give position
+ * @param pos The position in the keys array
+ * @param key the key to inject
+ */
+ /* No qualifier*/void setKey( int pos, K key )
+ {
+ keys[pos] = key;
+ }
+
+
+ /**
* @return the offset
*/
/* No qualifier */long getOffset()
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -34,13 +34,13 @@ import java.util.LinkedList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.mavibot.btree.exception.KeyNotFoundException;
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.BTreeHeader;
import org.apache.mavibot.btree.store.RecordManager;
@@ -54,6 +54,9 @@ import org.apache.mavibot.btree.store.Re
*/
public class BTree<K, V>
{
+ /** The Hader for a managed BTree */
+ private BTreeHeader btreeHeader;
+
/** Default page size (number of entries per node) */
public static final int DEFAULT_PAGE_SIZE = 16;
@@ -69,12 +72,6 @@ public class BTree<K, V>
/** The default journal file suffix */
public static final String JOURNAL_SUFFIX = ".log";
- /** The BTree name */
- private String name;
-
- /** A field used to generate new revisions in a thread safe way */
- private AtomicLong revision = new AtomicLong( 0L );
-
/** Comparator used to index entries. */
private Comparator<K> comparator;
@@ -84,12 +81,6 @@ public class BTree<K, V>
/** The list of read transactions being executed */
private ConcurrentLinkedQueue<Transaction<K, V>> readTransactions;
- /** 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;
@@ -117,9 +108,6 @@ public class BTree<K, V>
/** The associated journal. If null, this is an in-memory btree */
private File journal;
- /** The number of elements in the current revision */
- private AtomicLong nbElems = new AtomicLong( 0L );
-
/** A lock used to protect the write operation against concurrent access */
private ReentrantLock writeLock;
@@ -319,6 +307,8 @@ public class BTree<K, V>
*/
public BTree()
{
+ btreeHeader = new BTreeHeader( null );
+ type = BTreeTypeEnum.MANAGED;
}
@@ -357,7 +347,8 @@ public class BTree<K, V>
type = BTreeTypeEnum.PERSISTENT;
}
- pageSize = configuration.getPageSize();
+ btreeHeader = new BTreeHeader( configuration.getName() );
+ btreeHeader.setPageSize( configuration.getPageSize() );
keySerializer = configuration.getKeySerializer();
valueSerializer = configuration.getValueSerializer();
comparator = keySerializer.getComparator();
@@ -430,7 +421,7 @@ public class BTree<K, V>
int pageSize )
throws IOException
{
- this.name = name;
+ btreeHeader = new BTreeHeader( name );
if ( ( path == null ) && ( file == null ) )
{
@@ -463,7 +454,13 @@ public class BTree<K, V>
writeBufferSize = DEFAULT_WRITE_BUFFER_SIZE;
this.keySerializer = keySerializer;
+
+ btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
+
this.valueSerializer = valueSerializer;
+
+ btreeHeader.setValueSerializerFQCN(
valueSerializer.getClass().getName() );
+
comparator = keySerializer.getComparator();
// Create the first root page, with revision 0L. It will be empty
@@ -594,7 +591,7 @@ public class BTree<K, V>
*/
public long getBtreeOffset()
{
- return btreeOffset;
+ return btreeHeader.getBTreeOffset();
}
@@ -603,7 +600,43 @@ public class BTree<K, V>
*/
public void setBtreeOffset( long btreeOffset )
{
- this.btreeOffset = btreeOffset;
+ btreeHeader.setBTreeOffset( btreeOffset );
+ }
+
+
+ /**
+ * @return the rootPageOffset
+ */
+ public long getRootPageOffset()
+ {
+ return btreeHeader.getRootPageOffset();
+ }
+
+
+ /**
+ * @param rootPageOffset the rootPageOffset to set
+ */
+ public void setRootPageOffset( long rootPageOffset )
+ {
+ btreeHeader.setRootPageOffset( rootPageOffset );
+ }
+
+
+ /**
+ * @return the nextBTreeOffset
+ */
+ public long getNextBTreeOffset()
+ {
+ return btreeHeader.getNextBTreeOffset();
+ }
+
+
+ /**
+ * @param nextBTreeOffset the nextBTreeOffset to set
+ */
+ public void setNextBTreeOffset( long nextBTreeOffset )
+ {
+ btreeHeader.setNextBTreeOffset( nextBTreeOffset );
}
@@ -636,14 +669,14 @@ public class BTree<K, V>
*/
public void setPageSize( int pageSize )
{
- this.pageSize = pageSize;
-
if ( pageSize <= 2 )
{
- this.pageSize = DEFAULT_PAGE_SIZE;
+ btreeHeader.setPageSize( DEFAULT_PAGE_SIZE );
+ }
+ else
+ {
+ btreeHeader.setPageSize( getPowerOf2( pageSize ) );
}
-
- this.pageSize = getPowerOf2( pageSize );
}
@@ -687,7 +720,7 @@ public class BTree<K, V>
*/
public int getPageSize()
{
- return pageSize;
+ return btreeHeader.getPageSize();
}
@@ -699,7 +732,7 @@ public class BTree<K, V>
/** No qualifier */
long generateRevision()
{
- return revision.incrementAndGet();
+ return btreeHeader.incrementRevision();
}
@@ -731,7 +764,7 @@ public class BTree<K, V>
// and does not replace an element
if ( existingValue == null )
{
- nbElems.getAndIncrement();
+ btreeHeader.incrementNbElems();
}
// If the BTree is managed, we have to update the rootPage on disk
@@ -772,7 +805,7 @@ public class BTree<K, V>
// Decrease the number of element in the current tree if the delete is
successful
if ( deleted != null )
{
- nbElems.getAndDecrement();
+ btreeHeader.decrementNbElems();
}
return deleted;
@@ -806,7 +839,7 @@ public class BTree<K, V>
// Decrease the number of element in the current tree if the delete is
successful
if ( deleted != null )
{
- nbElems.getAndDecrement();
+ btreeHeader.decrementNbElems();
}
return deleted;
@@ -1009,7 +1042,7 @@ public class BTree<K, V>
*/
private Transaction<K, V> beginReadTransaction()
{
- Transaction<K, V> readTransaction = new Transaction<K, V>( rootPage,
revision.get() - 1,
+ Transaction<K, V> readTransaction = new Transaction<K, V>( rootPage,
btreeHeader.getRevision() - 1,
System.currentTimeMillis() );
readTransactions.add( readTransaction );
@@ -1051,6 +1084,7 @@ public class BTree<K, V>
public void setKeySerializer( ElementSerializer<K> keySerializer )
{
this.keySerializer = keySerializer;
+ btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
}
@@ -1060,6 +1094,7 @@ public class BTree<K, V>
public void setValueSerializer( ElementSerializer<V> valueSerializer )
{
this.valueSerializer = valueSerializer;
+ btreeHeader.setValueSerializerFQCN(
valueSerializer.getClass().getName() );
}
@@ -1143,7 +1178,7 @@ public class BTree<K, V>
}
// Write the number of elements first
- bb.putLong( nbElems.get() );
+ bb.putLong( btreeHeader.getNbElems() );
while ( cursor.hasNext() )
{
@@ -1266,7 +1301,7 @@ public class BTree<K, V>
BufferHandler bufferHandler = new BufferHandler( channel, buffer );
long nbElems = LongSerializer.deserialize( bufferHandler.read( 8 ) );
- this.nbElems.set( nbElems );
+ btreeHeader.setNbElems( nbElems );
// Prepare a list of keys and values read from the disk
//List<K> keys = new ArrayList<K>();
@@ -1345,7 +1380,7 @@ public class BTree<K, V>
*/
public String getName()
{
- return name;
+ return btreeHeader.getName();
}
@@ -1354,7 +1389,7 @@ public class BTree<K, V>
*/
public void setName( String name )
{
- this.name = name;
+ btreeHeader.setName( name );
}
@@ -1450,6 +1485,15 @@ public class BTree<K, V>
/**
+ * @return the keySerializer FQCN
+ */
+ public String getKeySerializerFQCN()
+ {
+ return btreeHeader.getKeySerializerFQCN();
+ }
+
+
+ /**
* @return the valueSerializer
*/
public ElementSerializer<V> getValueSerializer()
@@ -1458,12 +1502,21 @@ public class BTree<K, V>
}
+ /**
+ * @return the valueSerializer FQCN
+ */
+ public String getValueSerializerFQCN()
+ {
+ return btreeHeader.getValueSerializerFQCN();
+ }
+
+
/**
* @return The current BTree revision
*/
public long getRevision()
{
- return revision.get();
+ return btreeHeader.getRevision();
}
@@ -1472,7 +1525,7 @@ public class BTree<K, V>
*/
/* No qualifier */void setRevision( long revision )
{
- this.revision.set( revision );
+ btreeHeader.setRevision( revision );
}
@@ -1481,7 +1534,7 @@ public class BTree<K, V>
*/
public long getNbElems()
{
- return nbElems.get();
+ return btreeHeader.getNbElems();
}
@@ -1490,7 +1543,7 @@ public class BTree<K, V>
*/
/* No qualifier */void setNbElems( long nbElems )
{
- this.nbElems.set( nbElems );
+ btreeHeader.setNbElems( nbElems );
}
@@ -1518,11 +1571,11 @@ public class BTree<K, V>
}
sb.append( "BTree" );
- sb.append( "( pageSize:" ).append( pageSize );
+ sb.append( "( pageSize:" ).append( btreeHeader.getPageSize() );
if ( rootPage != null )
{
- sb.append( ", nbEntries:" ).append( nbElems );
+ sb.append( ", nbEntries:" ).append( btreeHeader.getNbElems() );
}
else
{
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -122,6 +122,24 @@ public class BTreeFactory
/**
+ * @param rootPageOffset the rootPageOffset to set
+ */
+ public static void setRootPageOffset( BTree<?, ?> btree, long
rootPageOffset )
+ {
+ btree.setRootPageOffset( rootPageOffset );
+ }
+
+
+ /**
+ * @param nextBTreeOffset the nextBTreeOffset to set
+ */
+ public static void setNextBTreeOffset( BTree<?, ?> btree, long
nextBTreeOffset )
+ {
+ btree.setNextBTreeOffset( nextBTreeOffset );
+ }
+
+
+ /**
* @param name the name to set
*/
public static void setName( BTree<?, ?> btree, String name )
@@ -187,4 +205,37 @@ public class BTreeFactory
{
btree.setRecordManager( recordManager );
}
+
+
+ /**
+ * Set the key at a give position
+ * @param pos The position in the keys array
+ * @param key the key to inject
+ */
+ public static void setKey( Page page, int pos, Object key )
+ {
+ ( ( AbstractPage ) page ).setKey( pos, key );
+ }
+
+
+ /**
+ * Set the value at a give position
+ * @param pos The position in the values array
+ * @param value the value to inject
+ */
+ public static void setValue( Leaf page, int pos, ValueHolder value )
+ {
+ page.setValue( pos, value );
+ }
+
+
+ /**
+ * Set the value at a give position
+ * @param pos The position in the values array
+ * @param value the value to inject
+ */
+ public static void setValue( Node page, int pos, ValueHolder value )
+ {
+ page.setValue( pos, value );
+ }
}
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -85,7 +85,7 @@ public class Leaf<K, V> extends Abstract
}
// The key is not present in the leaf. We have to add it in the page
- if ( nbElems < btree.pageSize )
+ if ( nbElems < btree.getPageSize() )
{
// The current page is not full, it can contain the added element.
// We insert it into a copied page and return the result
@@ -153,7 +153,7 @@ public class Leaf<K, V> extends Abstract
{
// The current page is not the root. Check if the leaf has more
than N/2
// elements
- int halfSize = btree.pageSize / 2;
+ int halfSize = btree.getPageSize() / 2;
if ( nbElems == halfSize )
{
@@ -216,7 +216,7 @@ public class Leaf<K, V> extends Abstract
{
// Create the new page. It will contain N - 1 elements (the maximum
number)
// as we merge two pages that contain N/2 elements minus the one we
remove
- Leaf<K, V> newLeaf = new Leaf<K, V>( btree, revision, btree.pageSize -
1 );
+ Leaf<K, V> newLeaf = new Leaf<K, V>( btree, revision,
btree.getPageSize() - 1 );
Tuple<K, V> removedElement = new Tuple<K, V>( keys[pos],
values[pos].getValue( btree ) );
if ( isLeft )
@@ -438,6 +438,17 @@ public class Leaf<K, V> extends Abstract
/**
+ * Set the value at a give position
+ * @param pos The position in the values array
+ * @param value the value to inject
+ */
+ public void setValue( int pos, ValueHolder<K, V> value )
+ {
+ values[pos] = value;
+ }
+
+
+ /**
* {@inheritDoc}
*/
public Cursor<K, V> browse( K key, Transaction<K, V> transaction,
LinkedList<ParentPos<K, V>> stack )
@@ -615,7 +626,7 @@ public class Leaf<K, V> extends Abstract
*/
private InsertResult<K, V> addAndSplit( long revision, K key, V value, int
pos )
{
- int middle = btree.pageSize >> 1;
+ int middle = btree.getPageSize() >> 1;
Leaf<K, V> leftLeaf = null;
Leaf<K, V> rightLeaf = null;
ValueHolder<K, V> valueHolder = btree.createHolder( value );
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -27,7 +27,7 @@ package org.apache.mavibot.btree;
*
* @author <a href="mailto:[email protected]">Mavibot labs Project</a>
*/
-/* No qualifier */class MemoryValueHolder<K, V> implements ValueHolder<K, V>
+public class MemoryValueHolder<K, V> implements ValueHolder<K, V>
{
/** The BTree */
private BTree<K, V> btree;
@@ -66,7 +66,7 @@ package org.apache.mavibot.btree;
{
StringBuilder sb = new StringBuilder();
- sb.append( btree.getName() ).append( " : '" );
+ sb.append( "'" );
V value = getValue( btree );
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -381,9 +381,9 @@ public class Node<K, V> extends Abstract
{
// Create the new node. It will contain N - 1 elements (the maximum
number)
// as we merge two nodes that contain N/2 elements minus the one we
remove
- Node<K, V> newNode = new Node<K, V>( btree, revision, btree.pageSize );
+ Node<K, V> newNode = new Node<K, V>( btree, revision,
btree.getPageSize() );
Tuple<K, V> removedElement = mergedResult.getRemovedElement();
- int half = btree.pageSize / 2;
+ int half = btree.getPageSize() / 2;
int index = Math.abs( pos );
if ( isLeft )
@@ -553,7 +553,7 @@ public class Node<K, V> extends Abstract
}
// We have some parent. Check if the current page is not half full
- int halfSize = btree.pageSize / 2;
+ int halfSize = btree.getPageSize() / 2;
if ( nbElems > halfSize )
{
@@ -772,6 +772,17 @@ public class Node<K, V> extends Abstract
/**
+ * Set the value at a give position
+ * @param pos The position in the values array
+ * @param value the value to inject
+ */
+ public void setValue( int pos, ValueHolder<K, V> value )
+ {
+ children[pos] = ( Page<K, V> ) value.getValue( btree );
+ }
+
+
+ /**
* {@inheritDoc}
*/
public Page<K, V> getReference( int pos )
@@ -908,7 +919,7 @@ public class Node<K, V> extends Abstract
*/
private InsertResult<K, V> addAndSplit( long revision, K pivot, Page<K, V>
leftPage, Page<K, V> rightPage, int pos )
{
- int middle = btree.pageSize >> 1;
+ int middle = btree.getPageSize() >> 1;
// Create two new pages
Node<K, V> newLeftPage = new Node<K, V>( btree, revision, middle );
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -99,13 +99,16 @@ public class ReferenceValueHolder<K, V>
{
StringBuilder sb = new StringBuilder();
- sb.append( btree.getName() ).append( "[" ).append( offset ).append( "]
: '" );
+ V value = reference.get();
- V value = getValue( btree );
-
- sb.append( value );
-
- sb.append( "'" );
+ if ( value != null )
+ {
+ sb.append( value );
+ }
+ else
+ {
+ sb.append( btree.getName() ).append( "[" ).append( offset
).append( "]" );
+ }
return sb.toString();
}
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=1456886&r1=1456885&r2=1456886&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
Fri Mar 15 10:58:16 2013
@@ -26,8 +26,8 @@ import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -35,6 +35,7 @@ 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.MemoryValueHolder;
import org.apache.mavibot.btree.Node;
import org.apache.mavibot.btree.Page;
import org.apache.mavibot.btree.ReferenceValueHolder;
@@ -123,7 +124,10 @@ public class RecordManager
private ByteBuffer blockBuffer;
/** The set of managed BTrees */
- private Map<String, BTree<?, ?>> managedBTrees = new HashMap<String,
BTree<?, ?>>();
+ private Map<String, BTree<?, ?>> managedBTrees = new LinkedHashMap<String,
BTree<?, ?>>();
+
+ /** The offset on the last added BTree */
+ private long lastAddedBTreeOffset = NO_PAGE;
/** The default file name */
private static final String DEFAULT_FILE_NAME = "mavibot.db";
@@ -316,23 +320,22 @@ public class RecordManager
copiedPageBTree = BTreeFactory.createBTree();
copiedPageBTree.setBtreeOffset( btreeOffset );
- position = loadBTree( pageIos, position, copiedPageBTree );
- btreeOffset = position;
+ loadBTree( pageIos, copiedPageBTree );
+ long nextBtreeOffset = copiedPageBTree.getNextBTreeOffset();
// Then process the next ones
for ( int i = 1; i < nbBtree; i++ )
{
// Create the BTree
BTree<?, ?> btree = BTreeFactory.createBTree();
- btree.setBtreeOffset( btreeOffset );
+ btree.setBtreeOffset( nextBtreeOffset );
// Read the associated pages
- pageIos = readPages( position, Long.MAX_VALUE );
- position = pageIos.length * pageSize;
+ pageIos = readPages( nextBtreeOffset, Long.MAX_VALUE );
// Load the BTree
- position = loadBTree( pageIos, position, btree );
- btreeOffset = position;
+ loadBTree( pageIos, btree );
+ nextBtreeOffset = btree.getNextBTreeOffset();
// Store it into the managedBtrees map
managedBTrees.put( btree.getName(), btree );
@@ -388,14 +391,12 @@ public class RecordManager
* Read a BTree from the disk. The meta-data are at the given position in
the list of pages.
*
* @param pageIos The list of pages containing the meta-data
- * @param position The position in the pageIos
* @param btree The BTree we have to initialize
- * @return The new position in the list of given pages
* @throws InstantiationException
* @throws IllegalAccessException
* @throws ClassNotFoundException
*/
- private long loadBTree( PageIO[] pageIos, long position, BTree<?, ?> btree
) throws EndOfFileExceededException,
+ private void loadBTree( PageIO[] pageIos, BTree<?, ?> btree ) throws
EndOfFileExceededException,
IOException, ClassNotFoundException, IllegalAccessException,
InstantiationException
{
long dataPos = 0L;
@@ -406,12 +407,18 @@ public class RecordManager
dataPos += LONG_SIZE;
// The nb elems in the tree
- int nbElems = readInt( pageIos, dataPos );
+ long nbElems = readLong( pageIos, dataPos );
BTreeFactory.setNbElems( btree, nbElems );
dataPos += LONG_SIZE;
// The BTree rootPage offset
long rootPageOffset = readLong( pageIos, dataPos );
+ BTreeFactory.setRootPageOffset( btree, rootPageOffset );
+ dataPos += LONG_SIZE;
+
+ // The next BTree offset
+ long nextBTreeOffset = readLong( pageIos, dataPos );
+ BTreeFactory.setNextBTreeOffset( btree, nextBTreeOffset );
dataPos += LONG_SIZE;
// The BTree page size
@@ -479,13 +486,10 @@ public class RecordManager
// Read the rootPage pages on disk
PageIO[] rootPageIos = readPages( rootPageOffset, Long.MAX_VALUE );
- position += rootPageIos.length * pageSize;
- Page btreeRoot = readPage( btree, revision, rootPageIos );
+ Page btreeRoot = readPage( btree, rootPageIos );
BTreeFactory.setRoot( btree, btreeRoot );
-
- return position;
}
@@ -500,19 +504,50 @@ public class RecordManager
}
- private Page readPage( BTree btree, long revision, PageIO[] pageIos )
throws IOException
+ private Page readPage( BTree btree, PageIO[] pageIos ) throws IOException
{
// Deserialize the rootPage now
long position = 0L;
+ // The revision
+ long revision = readLong( pageIos, position );
+ position += LONG_SIZE;
+
+ // The number of elements in the page
int nbElems = readInt( pageIos, position );
+ position += INT_SIZE;
+ // The size of the data containing the keys and values
Page page = null;
+ ByteBuffer byteBuffer = null;
+
+ // Reads the bytes containing all the keys and values, if we have some
+ byte[] data = readBytes( pageIos, position );
+
+ if ( data != null )
+ {
+ byteBuffer = ByteBuffer.allocate( data.length );
+ byteBuffer.put( data );
+ byteBuffer.rewind();
+ }
if ( nbElems >= 0 )
{
// Its a leaf
page = BTreeFactory.createLeaf( btree, revision, nbElems );
+
+ // Read each value and key
+ for ( int i = 0; i < nbElems; i++ )
+ {
+ Object value = btree.getValueSerializer().deserialize(
byteBuffer );
+
+ ValueHolder valueHolder = new MemoryValueHolder( btree, value
);
+ BTreeFactory.setValue( ( ( Leaf ) page ), i, valueHolder );
+
+ Object key = btree.getKeySerializer().deserialize( byteBuffer
);
+
+ BTreeFactory.setKey( page, i, key );
+ }
}
else
{
@@ -770,10 +805,8 @@ public class RecordManager
// We will add the newly managed BTree at the end of the header.
byte[] btreeNameBytes = Strings.getBytesUtf8( name );
- String keySerializerFqcn =
btree.getKeySerializer().getClass().getName();
- byte[] keySerializerBytes = Strings.getBytesUtf8( keySerializerFqcn );
- String valueSerializerFqcn =
btree.getValueSerializer().getClass().getName();
- byte[] valueSerializerBytes = Strings.getBytesUtf8(
valueSerializerFqcn );
+ byte[] keySerializerBytes = Strings.getBytesUtf8(
btree.getKeySerializerFQCN() );
+ byte[] valueSerializerBytes = Strings.getBytesUtf8(
btree.getValueSerializerFQCN() );
int bufferSize =
INT_SIZE + // The name size
@@ -785,6 +818,7 @@ public class RecordManager
INT_SIZE + // The page size
LONG_SIZE + // The revision
LONG_SIZE + // the number of element
+ LONG_SIZE + // the nextBtree offset
LONG_SIZE; // The root offset
// Get the pageIOs we need to store the data. We may need more than
one.
@@ -821,6 +855,10 @@ public class RecordManager
// Now, we can inject the BTree rootPage offset into the BTree header
position = store( position, rootPageIo.getOffset(), pageIos );
+ btree.setRootPageOffset( rootPageIo.getOffset() );
+
+ // The next BTree Header offset (-1L, as it's a new BTree)
+ position = store( position, NO_PAGE, pageIos );
// The BTree page size
position = store( position, btree.getPageSize(), pageIos );
@@ -840,6 +878,20 @@ public class RecordManager
nbBtree++;
+ // Now, if this added BTree is not the first BTree, we have to link it
with the
+ // latest added BTree
+ if ( lastAddedBTreeOffset != NO_PAGE )
+ {
+ // We have to update the nextBtreeOffset from the previous
BTreeHeader
+ pageIos = readPages( lastAddedBTreeOffset, LONG_SIZE + LONG_SIZE +
LONG_SIZE + LONG_SIZE );
+ store( LONG_SIZE + LONG_SIZE + LONG_SIZE, btreeOffset, pageIos );
+
+ // Write the pages on disk
+ flushPages( pageIos );
+ }
+
+ lastAddedBTreeOffset = btreeOffset;
+
// Last, not last, update the number of managed BTrees in the header
updateRecordManagerHeader();
}
@@ -850,6 +902,7 @@ public class RecordManager
* <ul>
* <li>the revision : a long</li>
* <li>the number of elements : an int (if <= 0, it's a Node, otherwise
it's a Leaf)</li>
+ * <li>the size of the values/keys when serialized
* <li>the keys : an array of serialized keys</li>
* <li>the values : an array of references to the children pageIO offset
(stored as long)
* if it's a Node, or a list of values if it's a Leaf</li>
@@ -899,8 +952,9 @@ public class RecordManager
else
{
// Prepare a list of byte[] that will contain the serialized page
- int nbBuffers = 1 + 1 + nbElems * 2;
+ int nbBuffers = 1 + 1 + 1 + nbElems * 2;
int dataSize = 0;
+ int serializedSize = 0;
if ( page instanceof Node )
{
@@ -914,12 +968,12 @@ public class RecordManager
// The revision
byte[] buffer = LongSerializer.serialize( revision );
serializedData.add( buffer );
- dataSize += buffer.length;
+ serializedSize += buffer.length;
// The number of elements
buffer = IntSerializer.serialize( nbElems );
serializedData.add( buffer );
- dataSize += buffer.length;
+ serializedSize += buffer.length;
// Iterate on the keys
for ( int pos = 0; pos < nbElems; pos++ )
@@ -950,8 +1004,15 @@ public class RecordManager
// TODO
}
+ // Store the data size
+ buffer = IntSerializer.serialize( dataSize );
+ serializedData.add( 2, buffer );
+ serializedSize += buffer.length;
+
+ serializedSize += dataSize;
+
// We are done. Allocate the pages we need to store the data
- PageIO[] pageIos = getFreePageIOs( dataSize );
+ PageIO[] pageIos = getFreePageIOs( serializedSize );
// And store the data into those pages
long position = 0L;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]