You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2017/10/09 20:33:00 UTC
svn commit: r1811602 [1/6] - in
/directory/mavibot/branches/single-value/mavibot: ./
src/main/java/org/apache/directory/mavibot/btree/
src/main/java/org/apache/directory/mavibot/btree/exception/
src/test/java/org/apache/directory/mavibot/btree/
Author: elecharny
Date: Mon Oct 9 20:32:59 2017
New Revision: 1811602
URL: http://svn.apache.org/viewvc?rev=1811602&view=rev
Log:
Vast refactoring to add transaction support to Mavibot.
This is a temporary commit, as there are still many compilation errors, and failing tests. More to come !
Added:
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java
- copied, changed from r1811601, directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/exception/BTreeNotFoundException.java
Removed:
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageHolder.java
Modified:
directory/mavibot/branches/single-value/mavibot/pom.xml
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeInfo.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BulkLoader.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/DeleteResult.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/KeyCursor.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Leaf.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/LevelInfo.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/MavibotInspector.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/ModifyResult.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Node.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/NotPresentResult.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageReclaimer.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/ReadTransaction.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManager.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RecordManagerHeader.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RemoveResult.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/RevisionOffsets.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/Transaction.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/TupleCursor.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/ValueHolder.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/WALObject.java
directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/WriteTransaction.java
directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/BTreeBrowseTest.java
directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/BTreeBuilderTest.java
directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/BulkLoaderTest.java
directory/mavibot/branches/single-value/mavibot/src/test/java/org/apache/directory/mavibot/btree/PageReclaimerTest.java
Modified: directory/mavibot/branches/single-value/mavibot/pom.xml
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/pom.xml?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/pom.xml (original)
+++ directory/mavibot/branches/single-value/mavibot/pom.xml Mon Oct 9 20:32:59 2017
@@ -52,6 +52,12 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ <version>3.4.0</version>
+ </dependency>
+
<!-- Logging dependencies -->
<dependency>
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractDeleteResult.java Mon Oct 9 20:32:59 2017
@@ -31,14 +31,16 @@ import java.util.List;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-/* No qualifier*/abstract class AbstractDeleteResult<K, V> extends AbstractResult<K, V> implements
- DeleteResult<K, V>
+/* No qualifier*/abstract class AbstractDeleteResult<K, V> extends AbstractResult<K, V> implements DeleteResult<K, V>
{
/** The modified page reference */
private Page<K, V> modifiedPage;
/** The removed element if the key was found in the tree*/
private Tuple<K, V> removedElement;
+
+ /** The key following the deleted key (may be null) */
+ private K nextKey;
/**
@@ -75,6 +77,25 @@ import java.util.List;
* {@inheritDoc}
*/
@Override
+ public K getNextKey()
+ {
+ return nextKey;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setNextKey( K nextKey )
+ {
+ this.nextKey = nextKey;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
public Page<K, V> getModifiedPage()
{
return modifiedPage;
@@ -84,7 +105,6 @@ import java.util.List;
/**
* {@inheritDoc}
*/
- @Override
public Tuple<K, V> getRemovedElement()
{
return removedElement;
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractPage.java Mon Oct 9 20:32:59 2017
@@ -23,12 +23,13 @@ package org.apache.directory.mavibot.btr
import java.io.IOException;
import java.lang.reflect.Array;
-import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
-
-
/**
- * A MVCC abstract Page. It stores the field and the methods shared by the Node and Leaf
- * classes (the keys and values/children).
+ * A MVCC abstract Page. It stores the keys/children and the methods shared by the {@link Node} and {@link Leaf}
+ * classes (the keys and values/children). It also hold the number of elements the page contains, and its current revision.
+ * <p>
+ * Keys are stored in {@link KeyHolder}s, values in {@link ValueHolder}.
+ * <p>
+ * The {@link Page} extends {@link AbstractWALObject} as any pae may be stored in the WAL at some point.
*
* @param <K> The type for the Key
* @param <V> The type for the stored value
@@ -41,22 +42,19 @@ import org.apache.directory.mavibot.btre
protected KeyHolder<K>[] keys;
/** Children pages associated with keys. */
- protected PageHolder<K, V>[] children;
+ protected long[] children;
/** The number of current values in the Page */
- protected int nbPageElems;
-
- /** This Page's revision */
- protected long revision;
+ protected int pageNbElems;
/**
* Creates a default empty AbstractPage
*
- * @param btree The associated BTree
+ * @param btreeInfo The associated BTree info
*/
- protected AbstractPage( BTree<K, V> btree )
+ protected AbstractPage( BTreeInfo<K, V> btreeInfo )
{
- this.btree = btree;
+ super( btreeInfo );
}
@@ -65,12 +63,12 @@ import org.apache.directory.mavibot.btre
*/
@SuppressWarnings("unchecked")
// Cannot create an array of generic objects
- protected AbstractPage( BTree<K, V> btree, long revision, int nbPageElems )
+ protected AbstractPage( BTreeInfo<K, V> btreeInfo, long revision, int pageNbElems )
{
- this.btree = btree;
+ super( btreeInfo );
this.revision = revision;
- this.nbPageElems = nbPageElems;
- this.keys = ( KeyHolder[] ) Array.newInstance( KeyHolder.class, btree.getPageNbElem() );
+ this.pageNbElems = pageNbElems;
+ this.keys = ( KeyHolder[] ) Array.newInstance( KeyHolder.class, btreeInfo.getPageNbElem() );
}
@@ -78,29 +76,32 @@ import org.apache.directory.mavibot.btre
* {@inheritDoc}
*/
@Override
- public int getNbPageElems()
+ public int getPageNbElems()
{
- return nbPageElems;
+ return pageNbElems;
}
/**
* Sets the number of element in this page
- * @param nbPageElems The number of elements
+ *
+ * @param pageNbElems The number of elements
*/
- /* no qualifier */void setNbPageElems( int nbPageElems )
+ /* no qualifier */void setPageNbElems( int pageNbElems )
{
- this.nbPageElems = nbPageElems;
+ this.pageNbElems = pageNbElems;
}
/**
- * {@inheritDoc}
+ * Returns the key at a given position
+ *
+ * @param pos The position of the key we want to retrieve
+ * @return The key found at the given position
*/
- @Override
- public K getKey( int pos )
+ protected K getKey( int pos )
{
- if ( ( pos < nbPageElems ) && ( keys[pos] != null ) )
+ if ( ( pos < pageNbElems ) && ( keys[pos] != null ) )
{
return keys[pos].getKey();
}
@@ -109,224 +110,54 @@ import org.apache.directory.mavibot.btre
return null;
}
}
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean hasKey( K key ) throws IOException
- {
- int pos = findPos( key );
-
- if ( pos < 0 )
- {
- // Here, if we have found the key in the node, then we must go down into
- // the right child, not the left one
- return children[-pos].getValue().hasKey( key );
- }
- else
- {
- Page<K, V> page = children[pos].getValue();
-
- return page.hasKey( key );
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- /* no qualifier */Page<K, V> getReference( int pos ) throws IOException
- {
- if ( pos < nbPageElems + 1 )
- {
- if ( children[pos] != null )
- {
- return children[pos].getValue();
- }
- else
- {
- return null;
- }
- }
- else
- {
- return null;
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public TupleCursor<K, V> browse( Transaction transaction, K key, ParentPos<K, V>[] stack, int depth )
- throws IOException
- {
- int pos = findPos( key );
-
- if ( pos < 0 )
- {
- pos = -pos;
- }
-
- // We first stack the current page
- stack[depth++] = new ParentPos<>( this, pos );
-
- Page<K, V> page = children[pos].getValue();
-
- return page.browse( transaction, key, stack, depth );
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean contains( K key, V value ) throws IOException
- {
- int pos = findPos( key );
-
- if ( pos < 0 )
- {
- // Here, if we have found the key in the node, then we must go down into
- // the right child, not the left one
- return children[-pos].getValue().contains( key, value );
- }
- else
- {
- return children[pos].getValue().contains( key, value );
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public DeleteResult<K, V> delete( WriteTransaction transaction, K key ) throws IOException
- {
- return delete( transaction, key, null, -1 );
- }
-
-
- /**
- * The real delete implementation. It can be used for internal deletion in the B-tree.
- *
- * @param key The key to delete
- * @param parent The parent page
- * @param parentPos The position of this page in the parent page
- * @return The result
- * @throws IOException If we had an issue while processing the deletion
- */
- /* no qualifier */abstract DeleteResult<K, V> delete( WriteTransaction transaction, K key, Page<K, V> parent,
- int parentPos ) throws IOException;
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V get( K key ) throws IOException, KeyNotFoundException
- {
- int pos = findPos( key );
-
- if ( pos < 0 )
- {
- // Here, if we have found the key in the node, then we must go down into
- // the right child, not the left one
- return children[-pos].getValue().get( key );
- }
- else
- {
- return children[pos].getValue().get( key );
- }
- }
-
-
+
+
/**
- * {@inheritDoc}
+ * Set a parent page child value, either an offset (a positive value) or an ID (a negative value) if the offset is -1.
+ *
+ * @param parent The node to update
+ * @param pos The position in the parent node
+ * @param child The child to refer to
*/
- /* no qualifier */Page<K, V> getPage( int pos )
+ protected void setChild( Node<K, V> parent, int pos, Page<K, V> child )
{
- if ( ( pos >= 0 ) && ( pos < children.length ) && ( children[pos] != null ) )
- {
- return children[pos].getValue();
- }
- else
+ parent.children[pos] = child.getOffset();
+
+ if ( parent.children[pos] == BTreeConstants.NO_PAGE )
{
- return null;
+ parent.children[pos] = -child.getId();
}
}
-
-
+
+
/**
- * Inject a pageHolder into the node, at a given position
+ * Set the page child value, either an offset (a positive value) or an ID (a negative value) if the offset is -1.
*
- * @param pos The position of the added pageHolder
- * @param pageHolder The pageHolder to add
+ * @param children The parent's children
+ * @param pos The position in the parent node
+ * @param child The child to refer to
*/
- /* no qualifier */void setPageHolder( int pos, PageHolder<K, V> pageHolder )
+ protected void setChild( long[] children, int pos, Page<K, V> child )
{
- if ( ( pos >= 0 ) && ( pos < children.length ) )
+ children[pos] = child.getOffset();
+
+ if ( children[pos] == BTreeConstants.NO_PAGE )
{
- children[pos] = pageHolder;
+ children[pos] = -child.getId();
}
}
/**
- * Sets the value at a give position
- * @param pos The position in the values array
- * @param value the value to inject
- */
- /* no qualifier */void setValue( int pos, ValueHolder<V> value )
- {
- // Implementation in the leaves
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public TupleCursor<K, V> browse( Transaction transaction, ParentPos<K, V>[] stack, int depth )
- throws IOException
- {
- stack[depth++] = new ParentPos<>( this, 0 );
-
- Page<K, V> page = children[0].getValue();
-
- return page.browse( transaction, stack, depth );
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public KeyCursor<K> browseKeys( Transaction transaction, ParentPos<K, K>[] stack, int depth )
- throws IOException
- {
- stack[depth++] = new ParentPos( this, 0 );
-
- Page<K, V> page = children[0].getValue();
-
- return page.browseKeys( transaction, stack, depth );
- }
-
-
- /**
* Selects the sibling (the previous or next page with the same parent) which has
* the more element assuming it's above N/2
*
+ * @param transaction The {@link Transaction} we are running in
* @param parent The parent of the current page
- * @param The position of the current page reference in its parent
+ * @param parentPos The position of the current page reference in its parent
* @return The position of the sibling, or -1 if we have'nt found any sibling
- * @throws IOException If we have an error while trying to access the page
*/
- protected int selectSibling( Transaction transaction, Page<K, V> parent, int parentPos ) throws IOException
+ protected int selectSibling( Transaction transaction, Node<K, V> parent, int parentPos ) throws IOException
{
if ( parentPos == 0 )
{
@@ -335,18 +166,24 @@ import org.apache.directory.mavibot.btre
return 1;
}
- if ( parentPos == parent.getNbPageElems() )
+ if ( parentPos == parent.getPageNbElems() )
{
// The current page is referenced on the right of its parent's page :
// we will not have a next page with the same parent
return parentPos - 1;
}
- Page<K, V> prevPage = ( ( AbstractPage<K, V> ) parent ).getPage( parentPos - 1 );
- Page<K, V> nextPage = ( ( AbstractPage<K, V> ) parent ).getPage( parentPos + 1 );
+ // Ok, in the middle of a page, select the one with the higher number of children,
+ // or the left one
+ Page<K, V> prevPage = parent.getPage( transaction, parentPos - 1 );
+ Page<K, V> nextPage = parent.getPage( transaction, parentPos + 1 );
- int prevPageSize = prevPage.getNbPageElems();
- int nextPageSize = nextPage.getNbPageElems();
+ if ( prevPage == null )
+ {
+ prevPage = parent.getPage( transaction, parentPos - 1 );
+ }
+ int prevPageSize = prevPage.getPageNbElems();
+ int nextPageSize = nextPage.getPageNbElems();
if ( prevPageSize >= nextPageSize )
{
@@ -360,29 +197,9 @@ import org.apache.directory.mavibot.btre
/**
- * {@inheritDoc}
- */
- @Override
- public K getLeftMostKey()
- {
- return keys[0].getKey();
- }
-
-
- /**
- * {@inheritDoc}
+ * @return the array containing the {@link Page}'s keys.
*/
- @Override
- public K getRightMostKey()
- {
- return keys[nbPageElems - 1].getKey();
- }
-
-
- /**
- * @return the keys
- */
- /* no qualifier */KeyHolder<K>[] getKeys()
+ public KeyHolder<K>[] getKeys()
{
return keys;
}
@@ -392,7 +209,7 @@ import org.apache.directory.mavibot.btre
* Sets the key at a give position
*
* @param pos The position in the keys array
- * @param key the key to inject
+ * @param key The key to inject
*/
/* no qualifier */void setKey( int pos, KeyHolder<K> key )
{
@@ -401,7 +218,7 @@ import org.apache.directory.mavibot.btre
/**
- * @param revision the keys to set
+ * @param keys The keys to set
*/
/* no qualifier */void setKeys( KeyHolder<K>[] keys )
{
@@ -410,25 +227,6 @@ import org.apache.directory.mavibot.btre
/**
- * @return the revision
- */
- @Override
- public long getRevision()
- {
- return revision;
- }
-
-
- /**
- * @param revision the revision to set
- */
- /* no qualifier */void setRevision( long revision )
- {
- this.revision = revision;
- }
-
-
- /**
* Compares two keys
*
* @param key1 The first key
@@ -453,7 +251,7 @@ import org.apache.directory.mavibot.btre
return -1;
}
- return btree.getKeyComparator().compare( key1, key2 );
+ return btreeInfo.getKeySerializer().getComparator().compare( key1, key2 );
}
@@ -493,17 +291,16 @@ import org.apache.directory.mavibot.btre
* @param key The key to find
* @return The position in the page.
*/
- @Override
- public int findPos( K key )
+ protected int findPos( K key )
{
// Deal with the special key where we have an empty page
- if ( nbPageElems == 0 )
+ if ( pageNbElems == 0 )
{
return 0;
}
int min = 0;
- int max = nbPageElems - 1;
+ int max = pageNbElems - 1;
// binary search
while ( min < max )
@@ -551,62 +348,6 @@ import org.apache.directory.mavibot.btre
/**
- * {@inheritDoc}
- */
- @Override
- public Tuple<K, V> findLeftMost() throws IOException
- {
- return children[0].getValue().findLeftMost();
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Tuple<K, V> findRightMost() throws IOException
- {
- return children[nbPageElems].getValue().findRightMost();
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName()
- {
- return btree.getName();
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String dumpPage( String tabs )
- {
- StringBuilder sb = new StringBuilder();
-
- if ( nbPageElems > 0 )
- {
- // Start with the first child
- sb.append( children[0].getValue().dumpPage( tabs + " " ) );
-
- for ( int i = 0; i < nbPageElems; i++ )
- {
- sb.append( tabs );
- sb.append( "<" );
- sb.append( getKey( i ) ).append( ">\n" );
- sb.append( children[i + 1].getValue().dumpPage( tabs + " " ) );
- }
- }
-
- return sb.toString();
- }
-
-
- /**
* @see Object#toString()
*/
@Override
@@ -615,7 +356,8 @@ import org.apache.directory.mavibot.btre
StringBuilder sb = new StringBuilder();
sb.append( "r" ).append( revision );
- sb.append( ", nbPageElems:" ).append( nbPageElems );
+ sb.append( ", B-tree:" ).append( getName() );
+ sb.append( ", pageNbElems:" ).append( pageNbElems );
sb.append( ", id:" ).append( id );
if ( offset > 0 )
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractTransaction.java Mon Oct 9 20:32:59 2017
@@ -23,6 +23,8 @@ package org.apache.directory.mavibot.btr
import java.io.IOException;
import java.util.Date;
+import org.apache.directory.mavibot.btree.exception.BTreeNotFoundException;
+
/**
* A read transaction is used to insure that reads are always done against
@@ -67,6 +69,7 @@ public abstract class AbstractTransactio
this( recordManager, DEFAULT_TIMEOUT );
}
+
/**
* Creates a new read transaction, with a specific tiemout. It create a new copy of
* the recordManager header
@@ -78,7 +81,6 @@ public abstract class AbstractTransactio
{
assert recordManager != null;
this.recordManager = recordManager;
- recordManagerHeader = recordManager.getRecordManagerHeader();
this.timeout = timeout;
}
@@ -88,6 +90,16 @@ public abstract class AbstractTransactio
* {@inheritDoc}
*/
@Override
+ public <K, V> Page<K, V> getPage( BTreeInfo<K, V> btreeInfo, long offset ) throws IOException
+ {
+ return ( Page<K, V> ) recordManager.getPage( btreeInfo, recordManagerHeader.pageSize, offset );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public RecordManager getRecordManager()
{
return recordManager;
@@ -171,6 +183,25 @@ public abstract class AbstractTransactio
{
closed = true;
}
+
+
+ /**
+ * {@inheritDoc}
+ * @param name The B-tree we are looking for
+ * @return The found B-tree, or a BTreeNotFoundException if teh B-tree does not exist.
+ */
+ @Override
+ public <K, V> BTree<K, V> getBTree( String name )
+ {
+ BTree<K, V> btree = recordManagerHeader.getBTree( name );
+
+ if ( btree == null )
+ {
+ throw new BTreeNotFoundException( "Cannot find btree " + name );
+ }
+
+ return btree;
+ }
/**
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/AbstractWALObject.java Mon Oct 9 20:32:59 2017
@@ -7,17 +7,37 @@ package org.apache.directory.mavibot.btr
*/
public abstract class AbstractWALObject<K, V> implements WALObject<K, V>
{
- /** The B-tree this header is associated with */
- protected BTree<K, V> btree;
+ /** The current revision */
+ protected long revision = 0L;
+
+ /** The B-tree information this object is associated with */
+ protected BTreeInfo<K, V> btreeInfo;
/** The PageIO of the serialized WALObject */
protected PageIO[] pageIOs;
/** The first {@link PageIO} storing the serialized Page on disk */
- protected long offset = RecordManager.NO_PAGE;
+ protected long offset = BTreeConstants.NO_PAGE;
/** This page ID */
protected long id;
+
+ /**
+ * Create a new instance of WALObject
+ */
+ public AbstractWALObject()
+ {
+ }
+
+ /**
+ * Create a new instance of WALObject
+ * @param btreeInfo The associated BTree information
+ */
+ public AbstractWALObject( BTreeInfo<K, V> btreeInfo )
+ {
+ this.btreeInfo = btreeInfo;
+ }
+
/**
* {@inheritDoc}
@@ -44,7 +64,7 @@ public abstract class AbstractWALObject<
@Override
public String getName()
{
- return null;
+ return btreeInfo.getName();
}
@@ -59,34 +79,42 @@ public abstract class AbstractWALObject<
/**
- * {@inheritDoc}
+ * @return the revision
*/
@Override
- public void setPageIOs( PageIO[] pageIOs )
+ public long getRevision()
{
- this.pageIOs = pageIOs;
- offset = pageIOs[0].getOffset();
+ return revision;
}
/**
- * @return the B-tree
+ * @param revision the revision to set
+ */
+ /* no qualifier */void setRevision( long revision )
+ {
+ this.revision = revision;
+ }
+
+
+ /**
+ * {@inheritDoc}
*/
@Override
- public BTree<K, V> getBtree()
+ public void setPageIOs( PageIO[] pageIOs )
{
- return btree;
+ this.pageIOs = pageIOs;
+ offset = pageIOs[0].getOffset();
}
/**
- * Associate a B-tree with this BTreeHeader instance
- *
- * @param btree the B-tree to set
+ * @return the B-tree
*/
- /* no qualifier */void setBtree( BTree<K, V> btree )
+ @Override
+ public BTreeInfo<K, V> getBtreeInfo()
{
- this.btree = btree;
+ return btreeInfo;
}
@@ -114,8 +142,18 @@ public abstract class AbstractWALObject<
*
* @param recordManagerHeader the RecordManagerHeader which contains the page ID counter
*/
- /* no qualifier*/ void initId( RecordManagerHeader recordManagerHeader )
+ protected void initId( RecordManagerHeader recordManagerHeader )
{
this.id = recordManagerHeader.idCounter++;
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isBTreeUser()
+ {
+ return btreeInfo.getType() != BTreeTypeEnum.BTREE_OF_BTREES && btreeInfo.getType() != BTreeTypeEnum.COPIED_PAGES_BTREE;
+ }
}
Copied: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java (from r1811601, directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java)
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java?p2=directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java&p1=directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java&r1=1811601&r2=1811602&rev=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeImpl.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTree.java Mon Oct 9 20:32:59 2017
@@ -26,7 +26,6 @@ import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Comparator;
-import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.collections.map.LRUMap;
import org.apache.directory.mavibot.btree.exception.BTreeCreationException;
@@ -45,65 +44,40 @@ import org.slf4j.LoggerFactory;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class BTreeImpl<K, V> implements BTree<K, V>, Closeable
+public class BTree<K, V> implements Closeable
{
/** The LoggerFactory used by this class */
- protected static final Logger LOG = LoggerFactory.getLogger( BTreeImpl.class );
+ protected static final Logger LOG = LoggerFactory.getLogger( BTree.class );
protected static final Logger LOG_PAGES = LoggerFactory.getLogger( "org.apache.directory.mavibot.LOG_PAGES" );
- /** The default number of pages to keep in memory */
- public static final int DEFAULT_CACHE_SIZE = 1000;
+ /** Default page size (number of entries per node) */
+ public static final int DEFAULT_PAGE_NBELEM = 16;
+
+ /** Default size of the buffer used to write data on disk. Around 1Mb */
+ public static final int DEFAULT_WRITE_BUFFER_SIZE = 4096 * 250;
+
+ /** Define a default delay for a read transaction. This is 10 seconds */
+ public static final long DEFAULT_READ_TIMEOUT = 10 * 1000L;
/** The size of the stack to use to manage tree searches */
private static final int MAX_STACK_DEPTH = 32;
/** The BtreeInfo */
private BTreeInfo<K, V> btreeInfo = null;
-
- /** The cache size, default to 1000 elements */
- private int cacheSize = DEFAULT_CACHE_SIZE;
- /** The current Header for a managed BTree */
+ /** The B-tree Header */
private BTreeHeader<K, V> currentBtreeHeader;
-
- /** The BTree type : either in-memory, disk backed or persisted */
- private BTreeTypeEnum btreeType;
-
- /** The cache associated with this B-tree */
- private LRUMap cache;
-
- /** The Key serializer used for this tree.*/
- private ElementSerializer<K> keySerializer;
-
- /** The FQCN of the Key serializer */
- private String keySerializerFQCN;
-
- /** The Value serializer used for this tree. */
- private ElementSerializer<V> valueSerializer;
-
- /** The FQCN of the Value serializer */
- private String valueSerializerFQCN;
-
- /** The BTree name */
- private String name;
-
- /** The number of elements in a page for this B-tree */
- private int pageNbElem;
/** The RecordManager */
private RecordManager recordManager;
-
- /** The RecordManagerHeader */
- private RecordManagerHeader recordManagerHeader;
/**
* Creates a new BTree, with no initialization.
*/
- /* No qualifier */BTreeImpl()
+ BTree()
{
- setType( BTreeTypeEnum.PERSISTED );
}
@@ -113,36 +87,49 @@ public class BTreeImpl<K, V> implements
*
* @param configuration The configuration to use
*/
- BTreeImpl( Transaction transaction, BTreeConfiguration<K, V> configuration )
+ BTree( Transaction transaction, BTreeConfiguration<K, V> configuration )
{
if ( configuration.getName() == null )
{
throw new IllegalArgumentException( "BTree name cannot be null" );
}
+ btreeInfo = new BTreeInfo<>();
+
setName( configuration.getName() );
setPageNbElem( configuration.getPageNbElem() );
setKeySerializer( configuration.getKeySerializer() );
setValueSerializer( configuration.getValueSerializer() );
setType( configuration.getBtreeType() );
recordManager = transaction.getRecordManager();
- recordManagerHeader = transaction.getRecordManagerHeader();
-
- cacheSize = configuration.getCacheSize();
-
- if ( keySerializer.getComparator() == null )
+ //recordManagerHeader = transaction.getRecordManagerHeader();
+
+ if ( btreeInfo.getKeySerializer().getComparator() == null )
{
throw new IllegalArgumentException( "Comparator should not be null" );
}
+ }
+
+
+ public BTree<K, V> copy()
+ {
+ BTree<K, V> copy = new BTree<>();
+
+ copy.btreeInfo = btreeInfo;
+ copy.currentBtreeHeader = currentBtreeHeader;
+ copy.recordManager = recordManager;
- initCache();
+ return copy;
}
/**
- * {@inheritDoc}
+ * Creates a cursor starting at the beginning of the tree
+ *
+ * @param transaction The Transaction we are running in
+ * @return A cursor on the B-tree
+ * @throws IOException
*/
- @Override
public TupleCursor<K, V> browse( Transaction transaction ) throws IOException, KeyNotFoundException, CursorException
{
if ( transaction == null )
@@ -164,9 +151,13 @@ public class BTreeImpl<K, V> implements
/**
- * {@inheritDoc}
+ * Creates a cursor starting on the given key
+ *
+ * @param key The key which is the starting point. If the key is not found,
+ * then the cursor will always return null.
+ * @return A cursor on the B-tree
+ * @throws IOException
*/
- @Override
public TupleCursor<K, V> browseFrom( Transaction transaction, K key ) throws IOException
{
// Check that we have a TransactionManager
@@ -187,15 +178,17 @@ public class BTreeImpl<K, V> implements
@Override
public void close() throws IOException
{
- // Clean the cache
- //cache.clear();
+ // Nothing to do
}
/**
- * {@inheritDoc}
+ * Checks if the B-tree contains the given key with the given value.
+ *
+ * @param key The key we are looking for
+ * @param value The value associated with the given key
+ * @return true if the key and value are associated with each other, false otherwise
*/
- @Override
public boolean contains( Transaction transaction, K key, V value ) throws IOException
{
if ( transaction == null )
@@ -204,18 +197,21 @@ public class BTreeImpl<K, V> implements
}
else
{
- return getRootPage().contains( key, value );
+ return getRootPage().contains( transaction, key, value );
}
}
/**
- * {@inheritDoc}
+ * Delete the entry which key is given as a parameter. If the entry exists, it will
+ * be removed from the tree, the old tuple will be returned. Otherwise, null is returned.
+ *
+ * @param key The key for the entry we try to remove
+ * @return A Tuple<K, V> containing the removed entry, or null if it's not found.
*/
- @Override
public Tuple<K, V> delete( WriteTransaction transaction, K key ) throws IOException
{
- // Check that we have a TransactionManager
+ // Check that we have a Transaction
if ( transaction == null )
{
throw new BTreeCreationException( "We don't have a transactionLManager" );
@@ -226,22 +222,34 @@ public class BTreeImpl<K, V> implements
throw new IllegalArgumentException( "Key must not be null" );
}
- try
- {
- return processDelete( transaction, key );
- }
- catch ( IOException ioe )
+ DeleteResult<K, V> result = processDelete( transaction, key );
+
+ // Check that we have found the element to delete
+ if ( result instanceof NotPresentResult )
{
- // We have had an exception, we must rollback the transaction
+ // We haven't found the element in the B-tree, just get out
+ // without updating the recordManager
+
return null;
}
+
+ // The element was found, and removed
+ AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
+
+ return deleteResult.getRemovedElement();
}
/**
- * {@inheritDoc}
+ * Find a value in the tree, given its key. If the key is not found,
+ * it will throw a KeyNotFoundException. <br/>
+ * Note that we can get a null value stored, or many values.
+ *
+ * @param key The key we are looking at
+ * @return The found value, or null if the key is not present in the tree
+ * @throws KeyNotFoundException If the key is not found in the B-tree
+ * @throws IOException TODO
*/
- @Override
public V get( Transaction transaction, K key ) throws IOException, KeyNotFoundException
{
if ( transaction == null )
@@ -250,34 +258,8 @@ public class BTreeImpl<K, V> implements
}
else
{
- return getRootPage().get( key );
- }
- }
-
-
- /**
- * Initialize the BTree.
- *
- * @throws IOException If we get some exception while initializing the BTree
- */
- public void initCache()
- {
- // This is not a subBtree, we have to initialize the cache
- if ( cacheSize < 1 )
- {
- cacheSize = DEFAULT_CACHE_SIZE;
+ return currentBtreeHeader.getRootPage().get( transaction, key );
}
-
- cache = new LRUMap( cacheSize );
- }
-
-
- /**
- * Return the cache we use in this BTree
- */
- /* No qualifier */LRUMap getCache()
- {
- return cache;
}
@@ -309,67 +291,22 @@ public class BTreeImpl<K, V> implements
/**
- *
- * Deletes the given <key,value> pair if both key and value match. If the given value is null
- * and there is no null value associated with the given key then the entry with the given key
- * will be removed.
- *
- * @param key The key to be removed
- * @param value The value to be removed (can be null, and when no null value exists the key will be removed irrespective of the value)
- * @param revision The revision to be associated with this operation
- * @return
- * @throws IOException
- */
- @Override
- public Tuple<K, V> delete( WriteTransaction transaction, K key, V value ) throws IOException
- {
- try
- {
- // Try to delete the entry starting from the root page. Here, the root
- // page may be either a Node or a Leaf
- DeleteResult<K, V> result = processDelete( transaction, key, value );
-
- // Check that we have found the element to delete
- if ( result instanceof NotPresentResult )
- {
- // We haven't found the element in the B-tree, just get out
- // without updating the recordManager
-
- return null;
- }
-
- // The element was found, and removed
- AbstractDeleteResult<K, V> deleteResult = ( AbstractDeleteResult<K, V> ) result;
-
- Tuple<K, V> tuple = deleteResult.getRemovedElement();
-
- // If the B-tree is managed, we have to update the rootPage on disk
- // Update the RecordManager header
-
- // Return the value we have found if it was modified
- return tuple;
- }
- catch ( IOException ioe )
- {
- // if we've got an error, we have to rollback
- throw ioe;
- }
- }
-
-
- /**
* Insert the tuple into the B-tree rootPage, get back the new rootPage
*/
private DeleteResult<K, V> processDelete( WriteTransaction transaction, K key ) throws IOException
{
- RecordManager recordManager = transaction.getRecordManager();
- RecordManagerHeader recordManagerheader = transaction.getRecordManagerHeader();
+ // Get the current B-tree header, check if it's in the transaction's pages
+ BTreeHeader<K, V> btreeHeader = currentBtreeHeader;
+
+ // Get the rootPage
+ Page<K, V> rootPage = btreeHeader.getRootPage();
+
+
// Get the current B-tree header, and delete the value from it
- BTreeHeader<K, V> btreeHeader = getBTreeHeader( getName() );
// Try to delete the entry starting from the root page. Here, the root
// page may be either a Node or a Leaf
- DeleteResult<K, V> result = btreeHeader.getRootPage().delete( transaction, key );
+ DeleteResult<K, V> result = rootPage.delete( transaction, key, null, -1 );
if ( result instanceof NotPresentResult )
{
@@ -377,93 +314,64 @@ public class BTreeImpl<K, V> implements
return result;
}
+ AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V> ) result;
+
// Create a new BTreeHeader
- BTreeHeader<K, V> newBtreeHeader = btreeHeader.copy();
+ BTreeHeader<K, V> newBtreeHeader;
+ long revision = transaction.getRevision();
- // Inject the old B-tree header into the pages to be freed
- // if we are deleting an element from a management BTree
- if ( ( btreeType == BTreeTypeEnum.BTREE_OF_BTREES ) || ( btreeType == BTreeTypeEnum.COPIED_PAGES_BTREE ) )
+ // Create a new BTreeHeader
+ // If the current b-tree header has been modified, it will be in the WalObject map.
+ // Fetch it, or create a new version of it.
+ long btreeHeaderId = btreeHeader.getId();
+
+ WALObject<?, ?> walObject = transaction.getWALObject( btreeHeaderId );
+
+ if ( walObject != null )
{
- PageIO[] pageIos = recordManager.readPageIOs( recordManagerheader, btreeHeader.getOffset(), -1L );
-
- for ( PageIO pageIo : pageIos )
- {
- recordManager.freedPages.add( pageIo );
- }
+ newBtreeHeader = (BTreeHeader<K, V>)transaction.removeWALObject( btreeHeaderId );
+ newBtreeHeader.initId( transaction.getRecordManagerHeader() );
}
-
- // The element was found, and removed
- AbstractDeleteResult<K, V> removeResult = ( AbstractDeleteResult<K, V> ) result;
-
- // This is a new root
- Page<K, V> newRootPage = removeResult.getModifiedPage();
-
- // Write the modified page on disk
- // Note that we don't use the holder, the new root page will
- // remain in memory.
- writePage( transaction, newRootPage );
-
- // Decrease the number of elements in the current tree
- newBtreeHeader.decrementNbElems();
- newBtreeHeader.setRootPage( newRootPage );
+ else
+ {
+ // Create a new BTreeHeader
+ newBtreeHeader = btreeHeader.copy( transaction.getRecordManagerHeader() );
+ }
+
+ // Update the new B-tree header
newBtreeHeader.setRevision( revision );
+ newBtreeHeader.setRootPage( removeResult.getModifiedPage() );
+ newBtreeHeader.decrementNbElems();
- // Write down the data on disk
- PageIO[] newBtreeHeaderPageIos = recordManager.writeBtreeHeader( this, newBtreeHeader, false );
- long newBtreeHeaderOffset = newBtreeHeaderPageIos[0].getOffset();
+ // Inject the new btreeHeader into the created pages
+ transaction.addWALObject( newBtreeHeader );
- // Update the B-tree of B-trees with this new offset, if we are not already doing so
- switch ( btreeType )
+ // Store the new B-tree header into the btreeMap
+ currentBtreeHeader = newBtreeHeader;
+
+ // And move the old B-tree header into the CopiedPages B-tree,
+ // if we are not processing the CopiedPages B-tree itself
+ if ( btreeHeader.isBTreeUser() )
{
- case PERSISTED:
- // We have a new B-tree header to inject into the B-tree of btrees
- recordManager.addInBtreeOfBtrees( transaction, getName(), revision, newBtreeHeaderOffset );
-
- recordManager.addInCopiedPagesBtree( getName(), revision, result.getCopiedPages() );
-
- // Store the new revision
- storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
-
- break;
-
- case BTREE_OF_BTREES:
- // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
- recordManager.updateRecordManagerHeader( newBtreeHeaderOffset, -1L );
-
- // We can free the copied pages
- recordManager.freePages( this, revision, result.getCopiedPages() );
-
- // Store the new revision
- storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
-
- break;
-
- case COPIED_PAGES_BTREE:
- // The B-tree of B-trees or the copiedPages B-tree has been updated, update the RMheader parameters
- recordManager.updateRecordManagerHeader( -1L, newBtreeHeaderOffset );
-
- // We can free the copied pages
- recordManager.freePages( this, revision, result.getCopiedPages() );
-
- // Store the new revision
- storeRevision( newBtreeHeader, recordManager.isKeepRevisions() );
-
- break;
-
- default:
- // Nothing to do for sub-btrees
- break;
+ transaction.addCopiedWALObject( btreeHeader );
+ }
+ else
+ {
+ // transaction.addFreePage( btreeHeader );
}
- // Return the value we have found if it was modified
- return result;
+ return removeResult;
}
/**
- * {@inheritDoc}
+ * Checks if the given key exists.
+ *
+ * @param key The key we are looking at
+ * @return true if the key is present, false otherwise
+ * @throws IOException If we have an error while trying to access the page
+ * @throws KeyNotFoundException If the key is not found in the B-tree
*/
- @Override
public boolean hasKey( Transaction transaction, K key ) throws IOException, KeyNotFoundException
{
if ( key == null )
@@ -477,7 +385,7 @@ public class BTreeImpl<K, V> implements
}
else
{
- return getRootPage().hasKey( key );
+ return getRootPage().hasKey( transaction, key );
}
}
@@ -495,9 +403,19 @@ public class BTreeImpl<K, V> implements
* @param revision The revision to use
* @return an instance of the InsertResult.
*/
- @Override
public InsertResult<K, V> insert( WriteTransaction transaction, K key, V value ) throws IOException
{
+ // Check that we have a Transaction
+ if ( transaction == null )
+ {
+ throw new BTreeCreationException( "We don't have a transactionLManager" );
+ }
+
+ if ( key == null )
+ {
+ throw new IllegalArgumentException( "Key must not be null" );
+ }
+
try
{
// Try to insert the new value in the tree at the right place,
@@ -532,15 +450,14 @@ public class BTreeImpl<K, V> implements
WALObject<?, ?> walObject = transaction.getWALObject( btreeHeaderId );
- if ( walObject != null )
+ if ( walObject == null )
{
- newBtreeHeader = (BTreeHeader<K, V>)transaction.removeWALObject( btreeHeaderId );
- newBtreeHeader.initId( transaction.getRecordManagerHeader() );
+ // Create a new BTreeHeader
+ newBtreeHeader = btreeHeader.copy( transaction.getRecordManagerHeader() );
}
else
{
- // Create a new BTreeHeader
- newBtreeHeader = btreeHeader.copy();
+ newBtreeHeader = ( BTreeHeader<K, V> ) walObject;
}
// Second case : the B-tree has been modified, and the old rootPage has not
@@ -552,24 +469,11 @@ public class BTreeImpl<K, V> implements
newRootPage = modifyResult.getModifiedPage();
- // Increment the counter if we have inserted a new value
+ // Increment the counter if we have inserted a new value, instead of replacing a value
if ( modifyResult.getModifiedValue() == null )
{
newBtreeHeader.incrementNbElems();
}
-
- // Add the the old rootPage in the transaction copied pages,
- // if we are not processing the CopiedPages B-tree
- // In this case, we have to move the copied page into
- // the free-pages list
- if ( getType() != BTreeTypeEnum.COPIED_PAGES_BTREE )
- {
- transaction.addCopiedWALObject( rootPage );
- }
- else
- {
- // transaction.addFreePage( rootPage );
- }
}
else
{
@@ -580,12 +484,22 @@ public class BTreeImpl<K, V> implements
K pivot = splitResult.getPivot();
- PageHolder<K, V> holderLeft = new PageHolder<>( this, splitResult.getLeftPage() );
- PageHolder<K, V> holderRight = new PageHolder<>( this, splitResult.getRightPage() );
+ long leftPage = splitResult.getLeftPage().getOffset();
+
+ if ( leftPage == BTreeConstants.NO_PAGE )
+ {
+ leftPage = -splitResult.getLeftPage().getId();
+ }
+
+ long rightPage = splitResult.getRightPage().getOffset();
+
+ if ( rightPage == BTreeConstants.NO_PAGE )
+ {
+ rightPage = -splitResult.getRightPage().getId();
+ }
- // Create the new rootPage if needed
- newRootPage = new Node<>( this, revision, pivot, holderLeft, holderRight );
- ( ( Node<K, V> ) newRootPage ).initId( transaction.getRecordManagerHeader() );
+ // Create the new rootPage with a new ID
+ newRootPage = transaction.newNode( btreeInfo, pivot, leftPage, rightPage );
if ( rootPage.getRevision() != revision )
{
@@ -596,23 +510,6 @@ public class BTreeImpl<K, V> implements
// Add the new root page in the transaction pages map
transaction.addWALObject( newRootPage );
- // We now have to remove the old root page from the list of new pages
- // and also remove the old btree-header, as we have a new rootPage
- transaction.removeWALObject( btreeHeaderId );
-
- // Add the the old rootPage in the transaction copied pages,
- // if we are not processing the CopiedPages B-tree
- // In this case, we have to move the copied page into
- // the free-pages list
- if ( getType() != BTreeTypeEnum.COPIED_PAGES_BTREE )
- {
- transaction.addCopiedWALObject( rootPage );
- }
- else
- {
- // transaction.addFreePage( rootPage );
- }
-
// Always increment the counter : we have added a new value
newBtreeHeader.incrementNbElems();
}
@@ -621,21 +518,11 @@ public class BTreeImpl<K, V> implements
newBtreeHeader.setRootPage( newRootPage );
newBtreeHeader.setRevision( revision );
- // Inject the new btreeHeader into the created pages
- transaction.addWALObject( newBtreeHeader );
-
- // And move the old B-tree header into the CopiedPages B-tree,
- // if we are not processing the CopiedPages B-tree itself
- if ( getType() != BTreeTypeEnum.COPIED_PAGES_BTREE )
- {
- transaction.addCopiedWALObject( btreeHeader );
- }
- else
- {
- // transaction.addFreePage( btreeHeader );
- }
+ // Inject the new btreeHeader into the created pages, and remove the previous one
+ transaction.removeWALObject( btreeHeaderId );
+ transaction.updateWAL( btreeHeaderId, btreeHeader, newBtreeHeader );
- // Get the new root page and make it the current root page
+ // Store the new B-tree header into the btreeMap
currentBtreeHeader = newBtreeHeader;
// Return the value we have found if it was modified
@@ -693,11 +580,11 @@ public class BTreeImpl<K, V> implements
* Write a page either in the pending pages if the transaction is started,
* or directly on disk.
*/
- private PageHolder<K, V> writePage( WriteTransaction transaction, Page<K, V> modifiedPage ) throws IOException
+ private long writePage( WriteTransaction transaction, Page<K, V> modifiedPage ) throws IOException
{
transaction.addWALObject( modifiedPage );
- return new PageHolder<>( this, modifiedPage );
+ return modifiedPage.getOffset();
}
@@ -722,6 +609,15 @@ public class BTreeImpl<K, V> implements
/**
* @return the btreeInfoOffset
*/
+ public BTreeInfo<K, V> getBtreeInfo()
+ {
+ return btreeInfo;
+ }
+
+
+ /**
+ * @return the btreeInfoOffset
+ */
public long getBtreeInfoOffset()
{
return btreeInfo.getOffset();
@@ -738,73 +634,66 @@ public class BTreeImpl<K, V> implements
/**
- * {@inheritDoc}
+ * @return the key comparator
*/
- @Override
public Comparator<K> getKeyComparator()
{
- return keySerializer.getComparator();
+ return btreeInfo.getKeySerializer().getComparator();
}
/**
- * {@inheritDoc}
+ * @return the keySerializer
*/
- @Override
public ElementSerializer<K> getKeySerializer()
{
- return keySerializer;
+ return btreeInfo.getKeySerializer();
}
/**
- * {@inheritDoc}
+ * @return the keySerializer FQCN
*/
- @Override
public String getKeySerializerFQCN()
{
- return keySerializerFQCN;
+ return btreeInfo.getKeySerializerFQCN();
}
/**
- * {@inheritDoc}
+ * @param keySerializer the Key serializer to set
*/
- @Override
public void setKeySerializer( ElementSerializer<K> keySerializer )
{
- this.keySerializer = keySerializer;
- keySerializerFQCN = keySerializer.getClass().getName();
+ btreeInfo.setKeySerializer( keySerializer );
+ btreeInfo.setKeySerializerFQCN( keySerializer.getClass().getName() );
}
/**
- * {@inheritDoc}
+ * @return the name
*/
- @Override
public String getName()
{
- return name;
+ return btreeInfo.getName();
}
/**
- * {@inheritDoc}
+ * @param name the name to set
*/
- @Override
public void setName( String name )
{
- this.name = name;
+ btreeInfo.setName( name );
}
/**
- * {@inheritDoc}
+ * @return The current number of elements in the B-tree
*/
- @Override
- public long getNbElems( RecordManagerHeader recordManagerHeader )
+ public long getNbElems()
{
- return 0L;
+ return currentBtreeHeader.getNbElems();
}
@@ -818,28 +707,33 @@ public class BTreeImpl<K, V> implements
/**
- * {@inheritDoc}
+ * @return the number of elements per page
*/
- @Override
public int getPageNbElem()
{
- return pageNbElem;
+ return btreeInfo.getPageNbElem();
}
/**
- * {@inheritDoc}
+ * Set the maximum number of elements we can store in a page. This must be a
+ * number greater than 1, and a power of 2. The default page size is 16.
+ * <br/>
+ * If the provided size is below 2, we will default to DEFAULT_PAGE_NB_ELEM.<br/>
+ * If the provided size is not a power of 2, we will select the closest power of 2
+ * higher than the given number<br/>
+ *
+ * @param pageNbElem The number of element per page
*/
- @Override
public void setPageNbElem( int pageNbElem )
{
if ( pageNbElem <= 2 )
{
- this.pageNbElem = DEFAULT_PAGE_NBELEM;
+ btreeInfo.setPageNbElem( DEFAULT_PAGE_NBELEM );
}
else
{
- this.pageNbElem = getPowerOf2( pageNbElem );
+ btreeInfo.setPageNbElem( getPowerOf2( pageNbElem ) );
}
}
@@ -871,15 +765,17 @@ public class BTreeImpl<K, V> implements
/**
- * {@inheritDoc}
+ * @return The RecordManager instance
*/
- @Override
public RecordManager getRecordManager()
{
return recordManager;
}
+ /**
+ * @param recordManager The RecordManager instance to set
+ */
/* No qualifier */ void setRecordManager( RecordManager recordManager )
{
this.recordManager = recordManager;
@@ -887,16 +783,15 @@ public class BTreeImpl<K, V> implements
/**
- * {@inheritDoc}
- */
- @Override
+ * @return The RecordManagerHeader instance
+ *
public RecordManagerHeader getRecordManagerHeader()
{
return recordManagerHeader;
}
- /* No qualifier */ void setRecordManagerHeader( RecordManagerHeader recordManagerHeader )
+ /* No qualifier * void setRecordManagerHeader( RecordManagerHeader recordManagerHeader )
{
this.recordManagerHeader = recordManagerHeader;
}
@@ -905,9 +800,8 @@ public class BTreeImpl<K, V> implements
/**
* Get the current rootPage
*
- * @return The rootPage
+ * @return The current rootPage
*/
- @Override
public Page<K, V> getRootPage()
{
return currentBtreeHeader.getRootPage();
@@ -926,12 +820,11 @@ public class BTreeImpl<K, V> implements
/**
- * {@inheritDoc}
+ * @return the type
*/
- @Override
public BTreeTypeEnum getType()
{
- return btreeType;
+ return btreeInfo.getType();
}
@@ -940,48 +833,55 @@ public class BTreeImpl<K, V> implements
*/
public void setType( BTreeTypeEnum type )
{
- this.btreeType = type;
+ btreeInfo.setType( type );
}
/**
- * {@inheritDoc}
+ * @return the value comparator
*/
- @Override
public Comparator<V> getValueComparator()
{
- return valueSerializer.getComparator();
+ return btreeInfo.getValueSerializer().getComparator();
}
/**
- * {@inheritDoc}
+ * @return the valueSerializer
*/
- @Override
public ElementSerializer<V> getValueSerializer()
{
- return valueSerializer;
+ return btreeInfo.getValueSerializer();
}
/**
- * {@inheritDoc}
+ * @return the valueSerializer FQCN
*/
- @Override
public String getValueSerializerFQCN()
{
- return valueSerializerFQCN;
+ return btreeInfo.getValueSerializerFQCN();
}
/**
- * {@inheritDoc}
+ * @param valueSerializer the Value serializer to set
*/
- @Override
public void setValueSerializer( ElementSerializer<V> valueSerializer )
{
- this.valueSerializer = valueSerializer;
- valueSerializerFQCN = valueSerializer.getClass().getName();
+ btreeInfo.setValueSerializer( valueSerializer );
+ btreeInfo.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @see java.lang.Object#hashCode()
+ *
+ @Override
+ public int hashCode()
+ {
+ return getName().hashCode();
}
@@ -997,18 +897,23 @@ public class BTreeImpl<K, V> implements
sb.append( "[" ).append( getName() ).append( "]" );
sb.append( "( pageNbElem:" ).append( getPageNbElem() );
- long nbElems = getBtreeHeader().getNbElems();
+ long nbElems = 0L;
+
+ if ( currentBtreeHeader != null )
+ {
+ nbElems = currentBtreeHeader.getNbElems();
+ }
sb.append( ", nbElements:" ).append( nbElems );
sb.append( ", comparator:" );
- if ( keySerializer.getComparator() == null )
+ if ( btreeInfo.getKeySerializer().getComparator() == null )
{
sb.append( "null" );
}
else
{
- sb.append( keySerializer.getComparator().getClass().getSimpleName() );
+ sb.append( btreeInfo.getKeySerializer().getComparator().getClass().getSimpleName() );
}
sb.append( ") : \n" );
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeBuilder.java Mon Oct 9 20:32:59 2017
@@ -109,12 +109,12 @@ public class BTreeBuilder<K, V>
// remove null keys and values from the last leaf and resize
Leaf<K, V> lastLeaf = ( Leaf<K, V> ) lstLeaves.get( lstLeaves.size() - 1 );
- for ( int i = 0; i < lastLeaf.getNbPageElems(); i++ )
+ for ( int i = 0; i < lastLeaf.getPageNbElems(); i++ )
{
if ( lastLeaf.getKey( i ) == null )
{
int n = i;
- lastLeaf.setNbPageElems( n );
+ lastLeaf.setPageNbElems( n );
KeyHolder<K>[] keys = lastLeaf.getKeys();
lastLeaf.setKeys( ( KeyHolder[] ) Array.newInstance( KeyHolder.class, n ) );
@@ -135,13 +135,13 @@ public class BTreeBuilder<K, V>
Page<K, V> rootPage = attachNodes( transaction, lstLeaves, btree );
//System.out.println("built rootpage : " + rootPage);
- ( ( BTreeImpl<K, V> ) btree ).setNbElems( totalTupleCount );
+ ( ( BTree<K, V> ) btree ).setNbElems( totalTupleCount );
//rm.updateBtreeHeader( btree, ( ( AbstractPage<K, V> ) rootPage ).getOffset() );
//rm.freePages( transaction, btree, btree.getRootPage( transaction ).getRevision(), Arrays.asList( btree.getRootPage( transaction ) ) );
- ( ( BTreeImpl<K, V> ) btree ).setRootPage( rootPage );
+ ( ( BTree<K, V> ) btree ).setRootPage( rootPage );
return btree;
}
@@ -190,12 +190,12 @@ public class BTreeBuilder<K, V>
// remove null keys and values from the last node and resize
AbstractPage<K, V> lastNode = ( AbstractPage<K, V> ) lstNodes.get( lstNodes.size() - 1 );
- for ( int j = 0; j < lastNode.getNbPageElems(); j++ )
+ for ( int j = 0; j < lastNode.getPageNbElems(); j++ )
{
if ( lastNode.getKey( j ) == null )
{
int n = j;
- lastNode.setNbPageElems( n );
+ lastNode.setPageNbElems( n );
KeyHolder<K>[] keys = lastNode.getKeys();
lastNode.setKeys( ( KeyHolder[] ) Array.newInstance( KeyHolder.class, n ) );
Added: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java?rev=1811602&view=auto
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java (added)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeConstants.java Mon Oct 9 20:32:59 2017
@@ -0,0 +1,49 @@
+package org.apache.directory.mavibot.btree;
+
+public class BTreeConstants
+{
+ /** A constant for an offset on a non existing page */
+ public static final long NO_PAGE = -1L;
+
+ /** A constant for a no limit page IO fetch */
+ public static final long NO_LIMIT = -1L;
+
+ /** The number of bytes used to store the size of a page */
+ /* no qualifier*/ static final int PAGE_SIZE = 4;
+
+ /** The size of the link to next page */
+ /* no qualifier*/ static final int LINK_SIZE = 8;
+
+ /** Some constants */
+ /* no qualifier*/ static final int BYTE_SIZE = 1;
+ /* no qualifier */static final int INT_SIZE = 4;
+ /* no qualifier */static final int LONG_SIZE = 8;
+
+ /** The default page size */
+ public static final int DEFAULT_PAGE_SIZE = 512;
+
+ /** The minimal page size. Can't be below 64, as we have to store many thing sin the RMHeader */
+ /* no qualifier*/ static final int MIN_PAGE_SIZE = 64;
+
+ /** The default file name */
+ /* no qualifier*/ static final String DEFAULT_FILE_NAME = "mavibot.db";
+
+ /** A flag used by internal btrees */
+ public static final boolean INTERNAL_BTREE = true;
+
+ /** A flag used by internal btrees */
+ public static final boolean NORMAL_BTREE = false;
+
+ /** The B-tree of B-trees management btree name */
+ /* no qualifier */static final String BTREE_OF_BTREES_NAME = "_btree_of_btrees_";
+
+ /** The CopiedPages management btree name */
+ /* no qualifier */static final String COPIED_PAGE_BTREE_NAME = "_copiedPageBtree_";
+
+ /** A value stored into the transaction context for rollbacked transactions */
+ /* no qualifier*/ static final int ROLLBACKED_TXN = 0;
+
+ /** Hex chars */
+ /* no qualifier*/ static final byte[] HEX_CHAR = new byte[]
+ { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+}
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java Mon Oct 9 20:32:59 2017
@@ -57,7 +57,7 @@ public class BTreeFactory<K, V>
*/
public static <K, V> BTree<K, V> createBTree()
{
- return new BTreeImpl<>();
+ return new BTree<>();
}
@@ -69,8 +69,9 @@ public class BTreeFactory<K, V>
*/
public static <K, V> BTree<K, V> createBTree( BTreeTypeEnum type )
{
- BTree<K, V> btree = new BTreeImpl<>();
- ( ( BTreeImpl<K, V> ) btree ).setType( type );
+ BTree<K, V> btree = new BTree<>( );
+ btree.setBtreeInfo( new BTreeInfo<>() );
+ btree.setType( type );
return btree;
}
@@ -85,7 +86,7 @@ public class BTreeFactory<K, V>
*/
public static <K, V> BTree<K, V> createBTree( Transaction transaction, BTreeConfiguration<K, V> configuration )
{
- return new BTreeImpl<>( transaction, configuration );
+ return new BTree<>( transaction, configuration );
}
@@ -106,10 +107,9 @@ public class BTreeFactory<K, V>
configuration.setKeySerializer( keySerializer );
configuration.setValueSerializer( valueSerializer );
configuration.setPageNbElem( BTree.DEFAULT_PAGE_NBELEM );
- configuration.setCacheSize( BTreeImpl.DEFAULT_CACHE_SIZE );
configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
- return new BTreeImpl<>( transaction, configuration );
+ return new BTree<>( transaction, configuration );
}
@@ -135,7 +135,7 @@ public class BTreeFactory<K, V>
configuration.setCacheSize( cacheSize );
configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
- return new BTreeImpl<>( transaction, configuration );
+ return new BTree<>( transaction, configuration );
}
@@ -157,10 +157,9 @@ public class BTreeFactory<K, V>
configuration.setKeySerializer( keySerializer );
configuration.setValueSerializer( valueSerializer );
configuration.setPageNbElem( pageNbElem );
- configuration.setCacheSize( BTreeImpl.DEFAULT_CACHE_SIZE );
configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
- return new BTreeImpl<>( transaction, configuration );
+ return new BTree<>( transaction, configuration );
}
@@ -186,7 +185,7 @@ public class BTreeFactory<K, V>
configuration.setCacheSize( cacheSize );
configuration.setWriteBufferSize( BTree.DEFAULT_WRITE_BUFFER_SIZE );
- return new BTreeImpl<>( transaction, configuration );
+ return new BTree<>( transaction, configuration );
}
@@ -196,7 +195,7 @@ public class BTreeFactory<K, V>
* @param btree The btree to update
* @param btreeHeaderOffset The offset
*/
- public static <K, V> void setBtreeHeaderOffset( BTreeImpl<K, V> btree, long btreeHeaderOffset )
+ public static <K, V> void setBtreeHeaderOffset( BTree<K, V> btree, long btreeHeaderOffset )
{
btree.setBtreeHeaderOffset( btreeHeaderOffset );
}
@@ -214,9 +213,9 @@ public class BTreeFactory<K, V>
*
* @return A Leaf instance
*/
- /* no qualifier*/static <K, V> Page<K, V> createLeaf( BTree<K, V> btree, long revision, int nbElems )
+ /* no qualifier*/static <K, V> Page<K, V> createLeaf( BTreeInfo<K, V> btreeInfo, long revision, int nbElems )
{
- return new Leaf<>( btree, revision, nbElems );
+ return new Leaf<>( btreeInfo, revision, nbElems );
}
@@ -228,10 +227,10 @@ public class BTreeFactory<K, V>
* @param nbElems The number or elements in this node
* @return A Node instance
*/
- /* no qualifier*/static <K, V> Page<K, V> createNode( BTree<K, V> btree, long revision, int nbElems )
+ /* no qualifier*/static <K, V> Page<K, V> createNode( BTreeInfo<K, V> btreeInfo, long revision, int nbElems )
{
//System.out.println( "Creating a node with nbElems : " + nbElems );
- return new Node<>( btree, revision, nbElems );
+ return new Node<>( btreeInfo, revision, nbElems );
}
@@ -246,9 +245,9 @@ public class BTreeFactory<K, V>
* @param pos The position in the keys array
* @param key The key to inject
*/
- /* no qualifier*/static <K, V> void setKey( BTree<K, V> btree, Page<K, V> page, int pos, K key )
+ /* no qualifier*/static <K, V> void setKey( BTreeInfo<K, V> btreeInfo, Page<K, V> page, int pos, K key )
{
- KeyHolder<K> keyHolder = new KeyHolder<>( btree.getKeySerializer(), key );
+ KeyHolder<K> keyHolder = new KeyHolder<>( btreeInfo.getKeySerializer(), key );
( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
}
@@ -262,7 +261,7 @@ public class BTreeFactory<K, V>
* @param pos The position in the values array
* @param value the value to inject
*/
- /* no qualifier*/static <K, V> void setValue( BTree<K, V> btree, Page<K, V> page, int pos, ValueHolder<V> value )
+ /* no qualifier*/static <K, V> void setValue( Page<K, V> page, int pos, ValueHolder<V> value )
{
( ( Leaf<K, V> ) page ).setValue( pos, value );
}
@@ -276,9 +275,9 @@ public class BTreeFactory<K, V>
* @param pos The position in the values array
* @param child the child page to inject
*/
- /* no qualifier*/static <K, V> void setPage( BTree<K, V> btree, Page<K, V> page, int pos, Page<K, V> child )
+ /* no qualifier*/static <K, V> void setPage( BTreeInfo<K, V> btreeInfo, Page<K, V> page, int pos, Page<K, V> child )
{
- ( ( Node<K, V> ) page ).setValue( pos, new PageHolder<K, V>( btree, child ) );
+ ( ( Node<K, V> ) page ).setValue( pos, child.getOffset() );
}
@@ -368,7 +367,7 @@ public class BTreeFactory<K, V>
*/
/* no qualifier*/static <K, V> void setRootPage( BTree<K, V> btree, Page<K, V> root )
{
- ( ( BTreeImpl<K, V> ) btree ).setRootPage( root );
+ ( ( BTree<K, V> ) btree ).setRootPage( root );
}
@@ -380,7 +379,7 @@ public class BTreeFactory<K, V>
*/
/* no qualifier */static <K, V> Page<K, V> getRootPage( BTree<K, V> btree )
{
- return (( BTreeImpl<K, V> ) btree ).getRootPage();
+ return (( BTree<K, V> ) btree ).getRootPage();
}
@@ -392,7 +391,7 @@ public class BTreeFactory<K, V>
*/
/* no qualifier */static <K, V> void setNbElems( BTree<K, V> btree, long nbElems )
{
- ( ( BTreeImpl<K, V> ) btree ).setNbElems( nbElems );
+ ( ( BTree<K, V> ) btree ).setNbElems( nbElems );
}
@@ -404,7 +403,7 @@ public class BTreeFactory<K, V>
*/
/* no qualifier*/static <K, V> void setRevision( BTree<K, V> btree, long revision )
{
- ( ( BTreeImpl<K, V> ) btree ).setRevision( revision );
+ ( ( BTree<K, V> ) btree ).setRevision( revision );
}
@@ -445,7 +444,7 @@ public class BTreeFactory<K, V>
{
LinkedList<ParentPos<K, V>> stack = new LinkedList<ParentPos<K, V>>();
- ParentPos<K, V> last = new ParentPos<K, V>( btree.getRootPage(), btree.getRootPage().getNbPageElems() );
+ ParentPos<K, V> last = new ParentPos<>( btree.getRootPage(), btree.getRootPage().getPageNbElems() );
stack.push( last );
if ( btree.getRootPage().isLeaf() )
@@ -459,9 +458,10 @@ public class BTreeFactory<K, V>
while ( true )
{
- Page<K, V> p = ( ( AbstractPage<K, V> ) node ).getPage( node.getNbPageElems() );
+ //Page<K, V> p = transaction.getPage( btreeInfo, ( ( AbstractPage )parentPos.page ).children[parentPos.pos] );
+ Page<K, V> p = ( ( AbstractPage<K, V> ) node ).getPage( node.getPageNbElems() );
- last = new ParentPos<>( p, p.getNbPageElems() );
+ last = new ParentPos<>( p, p.getPageNbElems() );
stack.push( last );
if ( p.isLeaf() )
@@ -488,9 +488,9 @@ public class BTreeFactory<K, V>
*/
/* no qualifier*/static <K, V> void setRootPageOffset( BTree<K, V> btree, long rootPageOffset )
{
- if ( btree instanceof BTreeImpl )
+ if ( btree instanceof BTree )
{
- ( ( BTreeImpl<K, V> ) btree ).getBtreeHeader().setRootPageOffset( rootPageOffset );
+ btree.getBtreeHeader().setRootPageOffset( rootPageOffset );
}
else
{
@@ -507,9 +507,9 @@ public class BTreeFactory<K, V>
*/
/* no qualifier*/static <K, V> void setRecordManager( BTree<K, V> btree, RecordManager recordManager )
{
- if ( btree instanceof BTreeImpl )
+ if ( btree instanceof BTree )
{
- ( ( BTreeImpl<K, V> ) btree ).setRecordManager( recordManager );
+ ( ( BTree<K, V> ) btree ).setRecordManager( recordManager );
}
else
{
@@ -526,17 +526,10 @@ public class BTreeFactory<K, V>
* @param pos The position of this key in the page
* @param buffer The byte[] containing the serialized key
*/
- /* no qualifier*/static <K, V> void setKey( BTree<K, V> btree, Page<K, V> page, int pos, byte[] buffer )
+ /* no qualifier*/static <K, V> void setKey( BTreeInfo<K, V> btreeInfo, Page<K, V> page, int pos, byte[] buffer )
{
- if ( btree instanceof BTreeImpl )
- {
- KeyHolder<K> keyHolder = new KeyHolder<K>( btree.getKeySerializer(), buffer );
- ( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
- }
- else
- {
- throw new IllegalArgumentException( "The b-tree must be a PersistedBTree" );
- }
+ KeyHolder<K> keyHolder = new KeyHolder<>( btreeInfo.getKeySerializer(), buffer );
+ ( ( AbstractPage<K, V> ) page ).setKey( pos, keyHolder );
}
@@ -548,7 +541,7 @@ public class BTreeFactory<K, V>
*/
/* no qualifier*/static <K, V> LinkedList<ParentPos<K, V>> getPathToLeftMostLeaf( BTree<K, V> btree )
{
- if ( btree instanceof BTreeImpl )
+ if ( btree instanceof BTree )
{
LinkedList<ParentPos<K, V>> stack = new LinkedList<ParentPos<K, V>>();
Modified: directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java?rev=1811602&r1=1811601&r2=1811602&view=diff
==============================================================================
--- directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java (original)
+++ directory/mavibot/branches/single-value/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java Mon Oct 9 20:32:59 2017
@@ -54,9 +54,6 @@ import java.util.concurrent.atomic.Atomi
*/
/* No qualifier*/class BTreeHeader<K, V> extends AbstractWALObject<K, V> implements Cloneable
{
- /** The current revision */
- private long revision = 0L;
-
/** The number of elements in this B-tree */
private long nbElems = 0L;
@@ -71,9 +68,9 @@ import java.util.concurrent.atomic.Atomi
/**
* Creates a BTreeHeader instance
*/
- public BTreeHeader()
+ public BTreeHeader( BTreeInfo<K, V> btreeInfo )
{
- super();
+ super( btreeInfo );
}
@@ -82,7 +79,7 @@ import java.util.concurrent.atomic.Atomi
*/
public long getBTreeInfoOffset()
{
- return ( ( BTreeImpl<K, V> ) btree ).getBtreeInfoOffset();
+ return btreeInfo.getOffset();
}
@@ -110,7 +107,7 @@ import java.util.concurrent.atomic.Atomi
* Copy the current B-tree header and return the copy
* @return The copied B-tree header
*/
- /* no qualifier */BTreeHeader<K, V> copy()
+ /* no qualifier */BTreeHeader<K, V> copy( RecordManagerHeader recordManagerHeader )
{
BTreeHeader<K, V> copy = clone();
@@ -119,7 +116,7 @@ import java.util.concurrent.atomic.Atomi
copy.offset = -1L;
copy.nbUsers.set( 0 );
copy.pageIOs = null;
- copy.id = id;
+ copy.id = recordManagerHeader.idCounter++;
return copy;
}
@@ -136,22 +133,12 @@ import java.util.concurrent.atomic.Atomi
}
else
{
- return RecordManager.NO_PAGE;
+ return BTreeConstants.NO_PAGE;
}
}
/**
- * @return the revision
- */
- @Override
- public long getRevision()
- {
- return revision;
- }
-
-
- /**
* Set the new revision
*
* @param revision the revision to set
@@ -245,30 +232,28 @@ import java.util.concurrent.atomic.Atomi
{
nbUsers.decrementAndGet();
}
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName()
- {
- return btree.getName();
- }
/**
+ * Serialize a BTreeHeader. It will contain the following data :<br/>
+ * <ul>
+ * <li>the Page ID : a long</li>
+ * <li>the revision : a long</li>
+ * <li>the number of elements in the B-tree : a long</li>
+ * <li>the root page offset : a long</li>
+ * <li>the B-tree info page offset : a long</li>
+ * </ul>
* {@inheritDoc}
*/
@Override
public PageIO[] serialize( WriteTransaction transaction ) throws IOException
{
int bufferSize =
- RecordManager.LONG_SIZE + // The page ID
- RecordManager.LONG_SIZE + // The revision
- RecordManager.LONG_SIZE + // the number of element
- RecordManager.LONG_SIZE + // The root page offset
- RecordManager.LONG_SIZE; // The B-tree info page offset
+ BTreeConstants.LONG_SIZE + // The page ID
+ BTreeConstants.LONG_SIZE + // The revision
+ BTreeConstants.LONG_SIZE + // the number of element
+ BTreeConstants.LONG_SIZE + // The root page offset
+ BTreeConstants.LONG_SIZE; // The B-tree info page offset
RecordManager recordManager = transaction.getRecordManager();
RecordManagerHeader recordManagerHeader = transaction.getRecordManagerHeader();
@@ -302,33 +287,29 @@ import java.util.concurrent.atomic.Atomi
position = recordManager.store( recordManagerHeader, position, getRootPageOffset(), pageIOs );
// The B-tree info page offset
- recordManager.store( recordManagerHeader, position, ( ( BTreeImpl<K, V> ) btree ).getBtreeInfoOffset(), pageIOs );
+ recordManager.store( recordManagerHeader, position, btreeInfo.getOffset(), pageIOs );
+
+ offset = pageIOs[0].getOffset();
- // And flush the pages to disk now
/*
- LOG.debug( "Flushing the newly managed '{}' btree header", btree.getName() );
+ LOG.debug( "Serializing the new '{}' btree header", btree.getName() );
if ( LOG_PAGES.isDebugEnabled() )
{
LOG_PAGES.debug( "Writing BTreeHeader revision {} for {}", btreeHeader.getRevision(), btree.getName() );
StringBuilder sb = new StringBuilder();
- sb.append( "Offset : " ).append( Long.toHexString( btreeHeaderOffset ) ).append( "\n" );
- sb.append( " Revision : " ).append( btreeHeader.getRevision() ).append( "\n" );
- sb.append( " NbElems : " ).append( btreeHeader.getNbElems() ).append( "\n" );
- sb.append( " RootPage : 0x" ).append( Long.toHexString( btreeHeader.getRootPageOffset() ) )
- .append( "\n" );
- sb.append( " Info : 0x" )
- .append( Long.toHexString( ( ( PersistedBTree<K, V> ) btree ).getBtreeInfoOffset() ) ).append( "\n" );
+ sb.append( "Offset : " ).append( Long.toHexString( btreeInfo.getOffset() ) ).append( "\n" );
+ sb.append( " ID : " ).append( id ).append( "\n" );
+ sb.append( " Revision : " ).append( getRevision() ).append( "\n" );
+ sb.append( " NbElems : " ).append( getNbElems() ).append( "\n" );
+ sb.append( " RootPage : 0x" ).append( Long.toHexString( getRootPageOffset() ) ).append( "\n" );
+ sb.append( " Info : 0x" ).append( Long.toHexString( btreeInfo.getOffset() ) ).append( "\n" );
- LOG_PAGES.debug( "Btree Header[{}]\n{}", btreeHeader.getRevision(), sb.toString() );
+ LOG_PAGES.debug( "Btree Header[{}]\n{}", getRevision(), sb.toString() );
}
*/
- //recordManager.storePages( btreeHeaderPageIos );
-
- offset = pageIOs[0].getOffset();
-
return pageIOs;
}
@@ -343,7 +324,7 @@ import java.util.concurrent.atomic.Atomi
sb.append( "{Header(" ).append( id ).append( ")@" );
- if ( offset == RecordManager.NO_PAGE )
+ if ( offset == BTreeConstants.NO_PAGE )
{
sb.append( "---" );
}
@@ -371,13 +352,13 @@ import java.util.concurrent.atomic.Atomi
sb.append( "B-treeHeader " );
sb.append( ", offset[0x" ).append( Long.toHexString( offset ) ).append( "]" );
sb.append( ", name[" );
- sb.append( btree.getName() );
+ sb.append( getName() );
sb.append( ':' );
sb.append( revision );
sb.append( "]" );
sb.append( ", revision[" ).append( revision ).append( "]" );
sb.append( ", btreeInfoOffset[0x" )
- .append( Long.toHexString( ( ( BTreeImpl<K, V> ) btree ).getBtreeInfoOffset() ) ).append( "]" );
+ .append( Long.toHexString( btreeInfo.getOffset() ) ).append( "]" );
sb.append( ", rootPageOffset[0x" ).append( Long.toHexString( getRootPageOffset() ) ).append( "]" );
sb.append( ", nbElems[" ).append( nbElems ).append( "]" );
sb.append( ", ID[" ).append( id ).append( "]" );