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 2014/02/10 16:35:20 UTC
svn commit: r1566659 [2/6] - in
/directory/mavibot/branches/with-txns/mavibot: img/
src/main/java/org/apache/directory/mavibot/btree/
src/main/java/org/apache/directory/mavibot/btree/comparator/
src/main/java/org/apache/directory/mavibot/btree/exceptio...
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeFactory.java Mon Feb 10 15:35:18 2014
@@ -20,22 +20,21 @@
package org.apache.directory.mavibot.btree;
-import java.io.IOException;
import java.util.LinkedList;
import org.apache.directory.mavibot.btree.serializer.ElementSerializer;
/**
- * This class construct a BTree from a serialized version of a BTree. We need it
- * to avoid exposing all the methods of the BTree class.<br>
- *
+ * This class construct a B-tree from a serialized version of a B-tree. We need it
+ * to avoid exposing all the methods of the B-tree class.<br>
+ *
* All its methods are static.
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*
- * @param <K> The BTree key type
- * @param <V> The BTree valye type
+ * @param <K> The B-tree key type
+ * @param <V> The B-tree value type
*/
public class BTreeFactory<K, V>
{
@@ -44,7 +43,9 @@ public class BTreeFactory<K, V>
//--------------------------------------------------------------------------------------------
/**
- * Creates a new persisted BTree, with no initialization.
+ * Creates a new persisted B-tree, with no initialization.
+ *
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree()
{
@@ -55,10 +56,11 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the BTreeConfiguration to initialize the
- * BTree
- *
+ * Creates a new persisted B-tree using the BTreeConfiguration to initialize the
+ * B-tree
+ *
* @param configuration The configuration to use
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( PersistedBTreeConfiguration<K, V> configuration )
{
@@ -69,14 +71,13 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new persisted B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @throws IOException
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer )
@@ -98,14 +99,14 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new persisted B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @throws IOException
+ * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, boolean allowDuplicates )
@@ -127,15 +128,15 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new persisted B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @param cacheSize The size to be used for this BTree cache
- * @throws IOException
+ * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+ * @param cacheSize The size to be used for this B-tree cache
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, boolean allowDuplicates, int cacheSize )
@@ -157,14 +158,14 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new persisted B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
* @param pageSize Size of the page
- * @throws IOException
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, int pageSize )
@@ -186,15 +187,15 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new persisted B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
* @param pageSize Size of the page
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @throws IOException
+ * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, int pageSize, boolean allowDuplicates )
@@ -216,16 +217,16 @@ public class BTreeFactory<K, V>
/**
- * Creates a new persisted BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new persisted B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
* @param pageSize Size of the page
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @param cacheSize The size to be used for this BTree cache
- * @throws IOException
+ * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+ * @param cacheSize The size to be used for this B-tree cache
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createPersistedBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, int pageSize, boolean allowDuplicates, int cacheSize )
@@ -247,10 +248,12 @@ public class BTreeFactory<K, V>
//--------------------------------------------------------------------------------------------
- // Create in-memory btrees
+ // Create in-memory B-trees
//--------------------------------------------------------------------------------------------
/**
- * Creates a new in-memory BTree, with no initialization.
+ * Creates a new in-memory B-tree, with no initialization.
+ *
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree()
{
@@ -261,10 +264,11 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the BTreeConfiguration to initialize the
- * BTree
- *
+ * Creates a new in-memory B-tree using the BTreeConfiguration to initialize the
+ * B-tree
+ *
* @param configuration The configuration to use
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( InMemoryBTreeConfiguration<K, V> configuration )
{
@@ -275,12 +279,13 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new in-memory B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer )
@@ -301,14 +306,14 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new in-memory B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @throws IOException
+ * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, boolean allowDuplicates )
@@ -329,14 +334,14 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new in-memory B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
* @param pageSize Size of the page
- * @throws IOException
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( String name, ElementSerializer<K> keySerializer,
ElementSerializer<V> valueSerializer, int pageSize )
@@ -357,14 +362,14 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new in-memory B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param filePath The name of the data directory with absolute path
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
- * @throws IOException
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
ElementSerializer<K> keySerializer,
@@ -387,19 +392,18 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new in-memory B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param filePath The name of the data directory with absolute path
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
* @param pageSize Size of the page
- * @throws IOException
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
- ElementSerializer<K> keySerializer,
- ElementSerializer<V> valueSerializer, int pageSize )
+ ElementSerializer<K> keySerializer, ElementSerializer<V> valueSerializer, int pageSize )
{
InMemoryBTreeConfiguration<K, V> configuration = new InMemoryBTreeConfiguration<K, V>();
@@ -418,16 +422,16 @@ public class BTreeFactory<K, V>
/**
- * Creates a new in-memory BTree using the parameters to initialize the
- * BTree
- *
- * @param name The BTree's name
+ * Creates a new in-memory B-tree using the parameters to initialize the
+ * B-tree
+ *
+ * @param name The B-tree's name
* @param filePath The name of the data directory with absolute path
* @param keySerializer Key serializer
* @param valueSerializer Value serializer
* @param pageSize Size of the page
- * @param allowDuplicates Tells if the BTree allows multiple value for a given key
- * @throws IOException
+ * @param allowDuplicates Tells if the B-tree allows multiple value for a given key
+ * @return a new B-tree instance
*/
public static <K, V> BTree<K, V> createInMemoryBTree( String name, String filePath,
ElementSerializer<K> keySerializer,
@@ -453,12 +457,12 @@ public class BTreeFactory<K, V>
// Create Pages
//--------------------------------------------------------------------------------------------
/**
- * Create a new Leaf for the given BTree.
- *
- * @param btree The BTree which will contain this leaf
+ * Create a new Leaf for the given B-tree.
+ *
+ * @param btree The B-tree which will contain this leaf
* @param revision The Leaf's revision
* @param nbElems The number or elements in this leaf
- *
+ *
* @return A Leaf instance
*/
/* no qualifier*/static <K, V> Page<K, V> createLeaf( BTree<K, V> btree, long revision, int nbElems )
@@ -475,9 +479,9 @@ public class BTreeFactory<K, V>
/**
- * Create a new Node for the given BTree.
- *
- * @param btree The BTree which will contain this node
+ * Create a new Node for the given B-tree.
+ *
+ * @param btree The B-tree which will contain this node
* @param revision The Node's revision
* @param nbElems The number or elements in this node
* @return A Node instance
@@ -500,8 +504,8 @@ public class BTreeFactory<K, V>
//--------------------------------------------------------------------------------------------
/**
* Set the key at a give position
- *
- * @param btree The BTree to update
+ *
+ * @param btree The B-tree to update
* @param page The page to update
* @param pos The position in the keys array
* @param key The key to inject
@@ -525,6 +529,9 @@ public class BTreeFactory<K, V>
/**
* Set the value at a give position
+ *
+ * @param btree The B-tree to update
+ * @param page The page to update
* @param pos The position in the values array
* @param value the value to inject
*/
@@ -543,11 +550,11 @@ public class BTreeFactory<K, V>
/**
* Set the page at a give position
- *
- * @param btree The BTree to update
+ *
+ * @param btree The B-tree to update
* @param page The page to update
* @param pos The position in the values array
- * @param value the value to inject
+ * @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 )
{
@@ -563,42 +570,48 @@ public class BTreeFactory<K, V>
//--------------------------------------------------------------------------------------------
- // Update BTree
+ // Update B-tree
//--------------------------------------------------------------------------------------------
/**
- * Sets the KeySerializer into the BTree
- *
- * @param btree The BTree to update
+ * Sets the KeySerializer into the B-tree
+ *
+ * @param btree The B-tree to update
* @param keySerializerFqcn the Key serializer FQCN to set
- * @throws ClassNotFoundException
- * @throws InstantiationException
- * @throws IllegalAccessException
+ * @throws ClassNotFoundException If the key serializer class cannot be found
+ * @throws InstantiationException If the key serializer class cannot be instanciated
+ * @throws IllegalAccessException If the key serializer class cannot be accessed
+ * @throws NoSuchFieldException
+ * @throws SecurityException
+ * @throws IllegalArgumentException
*/
/* no qualifier*/static <K, V> void setKeySerializer( BTree<K, V> btree, String keySerializerFqcn )
- throws ClassNotFoundException, IllegalAccessException, InstantiationException
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException
{
Class<?> keySerializer = Class.forName( keySerializerFqcn );
@SuppressWarnings("unchecked")
- ElementSerializer<K> instance = ( ElementSerializer<K> ) keySerializer.newInstance();
+ ElementSerializer<K> instance = ( ElementSerializer<K> ) keySerializer.getDeclaredField( "INSTANCE" ).get( null );
btree.setKeySerializer( instance );
}
/**
- * Sets the ValueSerializer into the BTree
- *
- * @param btree The BTree to update
+ * Sets the ValueSerializer into the B-tree
+ *
+ * @param btree The B-tree to update
* @param valueSerializerFqcn the Value serializer FQCN to set
- * @throws ClassNotFoundException
- * @throws InstantiationException
- * @throws IllegalAccessException
+ * @throws ClassNotFoundException If the value serializer class cannot be found
+ * @throws InstantiationException If the value serializer class cannot be instanciated
+ * @throws IllegalAccessException If the value serializer class cannot be accessed
+ * @throws NoSuchFieldException
+ * @throws SecurityException
+ * @throws IllegalArgumentException
*/
/* no qualifier*/static <K, V> void setValueSerializer( BTree<K, V> btree, String valueSerializerFqcn )
- throws ClassNotFoundException, IllegalAccessException, InstantiationException
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException, IllegalArgumentException, SecurityException, NoSuchFieldException
{
Class<?> valueSerializer = Class.forName( valueSerializerFqcn );
@SuppressWarnings("unchecked")
- ElementSerializer<V> instance = ( ElementSerializer<V> ) valueSerializer.newInstance();
+ ElementSerializer<V> instance = ( ElementSerializer<V> ) valueSerializer.getDeclaredField( "INSTANCE" ).get( null );
btree.setValueSerializer( instance );
}
@@ -606,8 +619,8 @@ public class BTreeFactory<K, V>
/**
* Set the new root page for this tree. Used for debug purpose only. The revision
* will always be 0;
- *
- * @param btree The BTree to update
+ *
+ * @param btree The B-tree to update
* @param root the new root page.
*/
/* no qualifier*/static <K, V> void setRootPage( BTree<K, V> btree, Page<K, V> root )
@@ -617,9 +630,9 @@ public class BTreeFactory<K, V>
/**
- * Return the BTree root page
- *
- * @param btree The Btree we want to root page from
+ * Return the B-tree root page
+ *
+ * @param btree The B-tree we want to root page from
* @return The root page
*/
/* no qualifier */static <K, V> Page<K, V> getRootPage( BTree<K, V> btree )
@@ -629,9 +642,9 @@ public class BTreeFactory<K, V>
/**
- * update the BTree number of elements
- *
- * @param btree The BTree to update
+ * Update the B-tree number of elements
+ *
+ * @param btree The B-tree to update
* @param nbElems the nbElems to set
*/
/* no qualifier */static <K, V> void setNbElems( BTree<K, V> btree, long nbElems )
@@ -641,9 +654,9 @@ public class BTreeFactory<K, V>
/**
- * Update the btree revision
- *
- * @param btree The BTree to update
+ * Update the B-tree revision
+ *
+ * @param btree The B-tree to update
* @param revision the revision to set
*/
/* no qualifier*/static <K, V> void setRevision( BTree<K, V> btree, long revision )
@@ -653,9 +666,9 @@ public class BTreeFactory<K, V>
/**
- * Set the BTree name
- *
- * @param btree The BTree to update
+ * Set the B-tree name
+ *
+ * @param btree The B-tree to update
* @param name the name to set
*/
/* no qualifier */static <K, V> void setName( BTree<K, V> btree, String name )
@@ -666,8 +679,8 @@ public class BTreeFactory<K, V>
/**
* Set the maximum number of elements we can store in a page.
- *
- * @param btree The BTree to update
+ *
+ * @param btree The B-tree to update
* @param pageSize The requested page size
*/
/* no qualifier */static <K, V> void setPageSize( BTree<K, V> btree, int pageSize )
@@ -681,8 +694,8 @@ public class BTreeFactory<K, V>
//--------------------------------------------------------------------------------------------
/**
* Includes the intermediate nodes in the path up to and including the right most leaf of the tree
- *
- * @param btree the btree
+ *
+ * @param btree the B-tree
* @return a LinkedList of all the nodes and the final leaf
*/
/* no qualifier*/static <K, V> LinkedList<ParentPos<K, V>> getPathToRightMostLeaf( BTree<K, V> btree )
@@ -724,12 +737,12 @@ public class BTreeFactory<K, V>
//--------------------------------------------------------------------------------------------
- // Persisted BTree methods
+ // Persisted B-tree methods
//--------------------------------------------------------------------------------------------
/**
- * Set the rootPage offset of the BTree
- *
- * @param btree The btree to update
+ * Set the rootPage offset of the B-tree
+ *
+ * @param btree The B-tree to update
* @param rootPageOffset The rootPageOffset to set
*/
/* no qualifier*/static <K, V> void setRootPageOffset( BTree<K, V> btree, long rootPageOffset )
@@ -740,34 +753,15 @@ public class BTreeFactory<K, V>
}
else
{
- throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
- }
- }
-
-
- /**
- * Set the nextBTree offset
- *
- * @param btree The btree to update
- * @param nextBTreeOffset The nextBTreeOffset to set
- */
- /* no qualifier*/static <K, V> void setNextBTreeOffset( BTree<K, V> btree, long nextBTreeOffset )
- {
- if ( btree instanceof PersistedBTree )
- {
- ( ( PersistedBTree<K, V> ) btree ).setNextBTreeOffset( nextBTreeOffset );
- }
- else
- {
- throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+ throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
}
}
/**
* Set the RecordManager
- *
- * @param btree The btree to update
+ *
+ * @param btree The B-tree to update
* @param recordManager The injected RecordManager
*/
/* no qualifier*/static <K, V> void setRecordManager( BTree<K, V> btree, RecordManager recordManager )
@@ -778,15 +772,15 @@ public class BTreeFactory<K, V>
}
else
{
- throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+ throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
}
}
/**
* Set the key at a give position
- *
- * @param btree The btree to update
+ *
+ * @param btree The B-tree to update
* @param page The page to update
* @param pos The position of this key in the page
* @param buffer The byte[] containing the serialized key
@@ -800,15 +794,15 @@ public class BTreeFactory<K, V>
}
else
{
- throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+ throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
}
}
/**
* Includes the intermediate nodes in the path up to and including the left most leaf of the tree
- *
- * @param btree The btree to process
+ *
+ * @param btree The B-tree to process
* @return a LinkedList of all the nodes and the final leaf
*/
/* no qualifier*/static <K, V> LinkedList<ParentPos<K, V>> getPathToLeftMostLeaf( BTree<K, V> btree )
@@ -850,7 +844,7 @@ public class BTreeFactory<K, V>
}
else
{
- throw new IllegalArgumentException( "The BTree must be a PersistedBTree" );
+ throw new IllegalArgumentException( "The B-tree must be a PersistedBTree" );
}
}
}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeHeader.java Mon Feb 10 15:35:18 2014
@@ -19,13 +19,14 @@
*/
package org.apache.directory.mavibot.btree;
+import java.util.concurrent.atomic.AtomicInteger;
+
-import java.util.concurrent.atomic.AtomicLong;
/**
- * Store in memory the information associated with a BTree. <br>
- * A BTree Header on disk contains the following elements :
+ * Store in memory the information associated with a B-tree. <br>
+ * A B-tree Header on disk contains the following elements :
* <pre>
* +--------------------+-------------+
* | revision | 8 bytes |
@@ -49,40 +50,26 @@ import java.util.concurrent.atomic.Atomi
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-/* No qualifier*/class BTreeHeader
+/* No qualifier*/class BTreeHeader<K, V>
{
/** The current revision */
- private AtomicLong revision = new AtomicLong( 0L );
+ private long revision = 0L;
- /** The number of elements in this BTree */
- private AtomicLong nbElems = new AtomicLong( 0L );
+ /** The number of elements in this B-tree */
+ private Long nbElems = 0L;
- /** The offset of the BTree RootPage */
+ /** The offset of the B-tree RootPage */
private long rootPageOffset;
- /** The offset of the next BTree */
- private long nextBTreeOffset;
-
- /** The number of elements in a page for this BTree */
- private int pageSize;
-
- /** The BTree name */
- private String name;
-
- /** The FQCN of the Key serializer */
- private String keySerializerFQCN;
-
- /** The FQCN of the Value serializer */
- private String valueSerializerFQCN;
-
// Those are data which aren't serialized : they are in memory only */
/** The position in the file */
private long btreeOffset;
- /** The existing versions */
- private long[] versions;
+ /** A Map containing the rootPage for this tree */
+ private Page<K, V> rootPage;
- private int allowDuplicates = 0;
+ /** The number of users for this BtreeHeader */
+ private AtomicInteger nbUsers = new AtomicInteger( 0 );
/**
@@ -94,42 +81,6 @@ import java.util.concurrent.atomic.Atomi
/**
- * @return the name
- */
- public String getName()
- {
- return name;
- }
-
-
- /**
- * @param name the name to set
- */
- /* no qualifier */void setName( String name )
- {
- this.name = name;
- }
-
-
- /**
- * @return the versions
- */
- public long[] getVersions()
- {
- return versions;
- }
-
-
- /**
- * @param versions the versions to set
- */
- /* no qualifier */void setVersions( long[] versions )
- {
- this.versions = versions;
- }
-
-
- /**
* @return the btreeOffset
*/
public long getBTreeOffset()
@@ -170,7 +121,7 @@ import java.util.concurrent.atomic.Atomi
*/
public long getRevision()
{
- return revision.get();
+ return revision;
}
@@ -179,18 +130,7 @@ import java.util.concurrent.atomic.Atomi
*/
/* no qualifier */void setRevision( long revision )
{
- this.revision.set( revision );
- }
-
-
- /**
- * Increment the revision
- *
- * @return the new revision
- */
- /* no qualifier */long incrementRevision()
- {
- return revision.incrementAndGet();
+ this.revision = revision;
}
@@ -199,25 +139,7 @@ import java.util.concurrent.atomic.Atomi
*/
public long getNbElems()
{
- return nbElems.get();
- }
-
-
- /**
- * Increment the number of elements
- */
- /* no qualifier */void incrementNbElems()
- {
- nbElems.incrementAndGet();
- }
-
-
- /**
- * Decrement the number of elements
- */
- public void decrementNbElems()
- {
- nbElems.decrementAndGet();
+ return nbElems;
}
@@ -226,91 +148,70 @@ import java.util.concurrent.atomic.Atomi
*/
/* no qualifier */void setNbElems( long nbElems )
{
- this.nbElems.set( nbElems );
+ this.nbElems = nbElems;
}
/**
- * @return the nextBTreeOffset
- */
- public long getNextBTreeOffset()
- {
- return nextBTreeOffset;
- }
-
-
- /**
- * @param nextBtreeOffset the nextBtreeOffset to set
+ * Increment the number of elements
*/
- /* no qualifier */void setNextBTreeOffset( long nextBTreeOffset )
+ /* no qualifier */void incrementNbElems()
{
- this.nextBTreeOffset = nextBTreeOffset;
+ nbElems++;
}
/**
- * @return the pageSize
+ * Decrement the number of elements
*/
- public int getPageSize()
+ /* no qualifier */void decrementNbElems()
{
- return pageSize;
+ nbElems--;
}
/**
- * @param pageSize the pageSize to set
+ * @return the rootPage
*/
- /* no qualifier */void setPageSize( int pageSize )
+ /* no qualifier */ Page<K, V> getRootPage()
{
- this.pageSize = pageSize;
+ return rootPage;
}
/**
- * @return the keySerializerFQCN
+ * @param rootPage the rootPage to set
*/
- public String getKeySerializerFQCN()
+ /* no qualifier */ void setRootPage( Page<K, V> rootPage )
{
- return keySerializerFQCN;
+ this.rootPage = rootPage;
}
/**
- * @param keySerializerFQCN the keySerializerFQCN to set
+ * @return the nbUsers
*/
- /* no qualifier */void setKeySerializerFQCN( String keySerializerFQCN )
+ /* no qualifier */ int getNbUsers()
{
- this.keySerializerFQCN = keySerializerFQCN;
+ return nbUsers.get();
}
/**
- * @return the valueSerializerFQCN
+ * Increment the number of users
*/
- public String getValueSerializerFQCN()
+ /* no qualifier */ void incrementNbUsers()
{
- return valueSerializerFQCN;
+ nbUsers.incrementAndGet();
}
/**
- * @param valueSerializerFQCN the valueSerializerFQCN to set
+ * Decrement the number of users
*/
- /* no qualifier */void setValueSerializerFQCN( String valueSerializerFQCN )
+ /* no qualifier */ void decrementNbUsers()
{
- this.valueSerializerFQCN = valueSerializerFQCN;
- }
-
-
- public boolean isAllowDuplicates()
- {
- return ( allowDuplicates == 1 );
- }
-
-
- /* no qualifier */void setAllowDuplicates( boolean allowDuplicates )
- {
- this.allowDuplicates = ( allowDuplicates ? 1 : 0 );
+ nbUsers.decrementAndGet();
}
@@ -321,42 +222,12 @@ import java.util.concurrent.atomic.Atomi
{
StringBuilder sb = new StringBuilder();
- sb.append( "Btree '" ).append( name ).append( "'" );
+ sb.append( "B-treeHeader " );
sb.append( ", revision[" ).append( revision ).append( "]" );
sb.append( ", btreeOffset[" ).append( btreeOffset ).append( "]" );
sb.append( ", rootPageOffset[" ).append( rootPageOffset ).append( "]" );
- sb.append( ", nextBTree[" ).append( nextBTreeOffset ).append( "]" );
sb.append( ", nbElems[" ).append( nbElems ).append( "]" );
- sb.append( ", pageSize[" ).append( pageSize ).append( "]" );
- sb.append( ", hasDuplicates[" ).append( isAllowDuplicates() ).append( "]" );
- sb.append( "{\n" );
- sb.append( " Key serializer : " ).append( keySerializerFQCN ).append( "\n" );
- sb.append( " Value serializer : " ).append( valueSerializerFQCN ).append( "\n" );
- sb.append( "}\n" );
-
- if ( ( versions != null ) && ( versions.length != 0 ) )
- {
- sb.append( "Versions : \n" );
- sb.append( "{\n" );
-
- boolean isFirst = true;
-
- for ( long version : versions )
- {
- if ( isFirst )
- {
- isFirst = false;
- }
- else
- {
- sb.append( ",\n" );
- }
-
- sb.append( " " ).append( version );
- }
-
- sb.append( "}\n" );
- }
+ sb.append( ", nbUsers[" ).append( nbUsers.get() ).append( "]" );
return sb.toString();
}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/BTreeTypeEnum.java Mon Feb 10 15:35:18 2014
@@ -21,24 +21,32 @@ package org.apache.directory.mavibot.btr
/**
- * An enum to describe the BTree type. We have three possible type :
+ * An enum to describe the B-tree type. We have three possible type :
* <ul>
- * <li>IN_MEMORY : the BTree will remain in memory, and won't be persisted on disk</li>
- * <li>PERSISTENT : the BTree is in memory, but will be persisted on disk</li>
- * <li>MANAGED : the BTree is managed by a RecordManager, and some pages may
+ * <li>IN_MEMORY : the B-tree will remain in memory, and won't be persisted on disk</li>
+ * <li>BACKED_ON_DISK : the B-tree is in memory, but will be persisted on disk</li>
+ * <li>PERSISTED : the B-tree is managed by a RecordManager, and some pages may
* be swapped out from memory on demand</li>
+ * <li>PERSISTED_SUB : The B-tree is a Persisted B-tree, but a Sub B-tree one</li>
+ * <li>PERSISTED_MANAGEMENT : This is a Persisted B-tree used to manage the other B-trees</li>
* </ul>
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public enum BTreeTypeEnum
{
- /** Pure in-memory BTree, not persisted on disk */
+ /** Pure in-memory B-tree, not persisted on disk */
IN_MEMORY,
- /** Persisted BTree */
+ /** Persisted B-tree */
PERSISTED,
- /** In-memory BTree but saved on disk */
+ /** Persisted sub B-tree */
+ PERSISTED_SUB,
+
+ /** Persisted Management B-tree */
+ PERSISTED_MANAGEMENT,
+
+ /** In-memory B-tree but saved on disk */
BACKED_ON_DISK
}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryBTree.java Mon Feb 10 15:35:18 2014
@@ -29,6 +29,7 @@ import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.directory.mavibot.btree.exception.InitializationException;
@@ -48,7 +49,7 @@ import org.slf4j.LoggerFactory;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-/* No qualifier */class InMemoryBTree<K, V> extends AbstractBTree<K, V> implements Closeable
+/* No qualifier */class InMemoryBTree<K, V> extends AbstractBTree<K, V> implements TransactionManager, Closeable
{
/** The LoggerFactory used by this class */
protected static final Logger LOG = LoggerFactory.getLogger( InMemoryBTree.class );
@@ -72,10 +73,20 @@ import org.slf4j.LoggerFactory;
/** The associated journal. If null, this is an in-memory btree */
private File journal;
+ /** The directory where the journal will be stored */
private File envDir;
+ /** The Journal channel */
private FileChannel journalChannel = null;
+ /** The current transaction */
+ private WriteTransaction writeTransaction;
+
+ /** A lock to protect the creation of the transaction */
+ private ReentrantLock createTransaction = new ReentrantLock();
+
+ /** A flag set when we initiate an automatic transaction */
+ private AtomicBoolean automaticTransaction = new AtomicBoolean( true );
/**
* Creates a new BTree, with no initialization.
@@ -83,7 +94,6 @@ import org.slf4j.LoggerFactory;
/* no qualifier */InMemoryBTree()
{
super();
- btreeHeader = new BTreeHeader();
setType( BTreeTypeEnum.IN_MEMORY );
}
@@ -97,9 +107,9 @@ import org.slf4j.LoggerFactory;
/* no qualifier */InMemoryBTree( InMemoryBTreeConfiguration<K, V> configuration )
{
super();
- String name = configuration.getName();
+ String btreeName = configuration.getName();
- if ( name == null )
+ if ( btreeName == null )
{
throw new IllegalArgumentException( "BTree name cannot be null" );
}
@@ -111,29 +121,34 @@ import org.slf4j.LoggerFactory;
envDir = new File( filePath );
}
- btreeHeader = new BTreeHeader();
- btreeHeader.setName( name );
- btreeHeader.setPageSize( configuration.getPageSize() );
-
- keySerializer = configuration.getKeySerializer();
- btreeHeader.setKeySerializerFQCN( keySerializer.getClass().getName() );
-
- valueSerializer = configuration.getValueSerializer();
- btreeHeader.setValueSerializerFQCN( valueSerializer.getClass().getName() );
+ // Store the configuration in the B-tree
+ setName( btreeName );
+ setPageSize( configuration.getPageSize() );
+ setKeySerializer( configuration.getKeySerializer() );
+ setValueSerializer( configuration.getValueSerializer() );
+ setAllowDuplicates( configuration.isAllowDuplicates() );
+ setType( configuration.getType() );
readTimeOut = configuration.getReadTimeOut();
writeBufferSize = configuration.getWriteBufferSize();
- btreeHeader.setAllowDuplicates( configuration.isAllowDuplicates() );
- setType( configuration.getType() );
if ( keySerializer.getComparator() == null )
{
throw new IllegalArgumentException( "Comparator should not be null" );
}
+ // Create the B-tree header
+ BTreeHeader<K, V> newBtreeHeader = new BTreeHeader<K, V>();
+
// Create the first root page, with revision 0L. It will be empty
// and increment the revision at the same time
- rootPage = new InMemoryLeaf<K, V>( this );
+ newBtreeHeader.setBTreeOffset( 0L );
+ newBtreeHeader.setRevision( 0L );
+ newBtreeHeader.setNbElems( 0L );
+ newBtreeHeader.setRootPage( new InMemoryLeaf<K, V>( this ) );
+ newBtreeHeader.setRootPageOffset( 0L );
+
+ btreeRevisions.put( 0L, newBtreeHeader );
// Now, initialize the BTree
try
@@ -152,7 +167,7 @@ import org.slf4j.LoggerFactory;
*
* @throws IOException If we get some exception while initializing the BTree
*/
- public void init() throws IOException
+ private void init() throws IOException
{
// if not in-memory then default to persist mode instead of managed
if ( envDir != null )
@@ -160,13 +175,14 @@ import org.slf4j.LoggerFactory;
if ( !envDir.exists() )
{
boolean created = envDir.mkdirs();
+
if ( !created )
{
throw new IllegalStateException( "Could not create the directory " + envDir + " for storing data" );
}
}
- this.file = new File( envDir, btreeHeader.getName() + DATA_SUFFIX );
+ this.file = new File( envDir, getName() + DATA_SUFFIX );
this.journal = new File( envDir, file.getName() + JOURNAL_SUFFIX );
setType( BTreeTypeEnum.BACKED_ON_DISK );
@@ -175,8 +191,6 @@ import org.slf4j.LoggerFactory;
// Create the queue containing the pending read transactions
readTransactions = new ConcurrentLinkedQueue<ReadTransaction<K, V>>();
- writeLock = new ReentrantLock();
-
// Check the files and create them if missing
// Create the queue containing the modifications, if it's not a in-memory btree
if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
@@ -202,6 +216,11 @@ import org.slf4j.LoggerFactory;
else
{
setType( BTreeTypeEnum.IN_MEMORY );
+
+ // This is a new Btree, we have to store the BtreeHeader
+ BTreeHeader<K, V> btreeHeader = new BTreeHeader<K, V>();
+ btreeHeader.setRootPage( new InMemoryLeaf<K, V>( this ) );
+ storeRevision( btreeHeader );
}
// Initialize the txnManager thread
@@ -225,8 +244,6 @@ import org.slf4j.LoggerFactory;
flush();
journalChannel.close();
}
-
- rootPage = null;
}
@@ -244,59 +261,78 @@ import org.slf4j.LoggerFactory;
*/
protected Tuple<K, V> delete( K key, V value, long revision ) throws IOException
{
- writeLock.lock();
+ boolean inTransaction = beginTransaction( revision );
- try
+ if ( revision == -1L )
{
- // If the key exists, the existing value will be replaced. We store it
- // to return it to the caller.
- Tuple<K, V> tuple = null;
+ revision = currentRevision.get() + 1;
+ }
+
+ BTreeHeader<K, V> oldBtreeHeader = getBtreeHeader();
+ BTreeHeader<K, V> newBtreeHeader = createNewBtreeHeader( oldBtreeHeader, revision );
+
+ // If the key exists, the existing value will be replaced. We store it
+ // to return it to the caller.
+ Tuple<K, V> tuple = null;
- // 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 = rootPage.delete( revision, key, value, null, -1 );
+ // 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 = getRootPage().delete( key, value, revision );
- if ( result instanceof NotPresentResult )
+ if ( result instanceof NotPresentResult )
+ {
+ // Key not found.
+ if ( !inTransaction )
{
- // Key not found.
- return null;
+ commit();
}
- // Keep the oldRootPage so that we can later access it
- Page<K, V> oldRootPage = rootPage;
+ return null;
+ }
- if ( result instanceof RemoveResult )
- {
- // The element was found, and removed
- RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
+ // Keep the oldRootPage so that we can later access it
+ //Page<K, V> oldRootPage = rootPage;
- Page<K, V> modifiedPage = removeResult.getModifiedPage();
+ if ( result instanceof RemoveResult )
+ {
+ // The element was found, and removed
+ RemoveResult<K, V> removeResult = ( RemoveResult<K, V> ) result;
- // This is a new root
- rootPage = modifiedPage;
- tuple = removeResult.getRemovedElement();
- }
+ Page<K, V> modifiedPage = removeResult.getModifiedPage();
- if ( withJournal )
- {
- // Inject the modification into the modification queue
- writeToJournal( new Deletion<K, V>( key ) );
- }
+ // This is a new root
+ newBtreeHeader.setRootPage( modifiedPage );
+ tuple = removeResult.getRemovedElement();
+ }
- // Decrease the number of elements in the current tree if the deletion is successful
- if ( tuple != null )
- {
- btreeHeader.decrementNbElems();
- }
+ if ( withJournal )
+ {
+ // Inject the modification into the modification queue
+ writeToJournal( new Deletion<K, V>( key ) );
+ }
- // Return the value we have found if it was modified
- return tuple;
+ // Decrease the number of elements in the current tree if the deletion is successful
+ if ( tuple != null )
+ {
+ newBtreeHeader.decrementNbElems();
}
- finally
+
+ // Return the value we have found if it was modified
+ if ( !inTransaction )
+ {
+ storeRevision( newBtreeHeader );
+ commit();
+ }
+
+ if ( oldBtreeHeader.getNbUsers() == 0 )
{
- // See above
- writeLock.unlock();
+ synchronized ( btreeRevisions )
+ {
+ btreeRevisions.remove( oldBtreeHeader.getRevision() );
+ }
}
+
+ return tuple;
}
@@ -320,6 +356,18 @@ import org.slf4j.LoggerFactory;
throw new IllegalArgumentException( "Key must not be null" );
}
+ // We have to start a new transaction, which will be committed or rollbacked
+ // locally. This will duplicate the current BtreeHeader during this phase.
+ boolean inTransaction = beginTransaction( revision );
+
+ if ( revision == -1L )
+ {
+ revision = currentRevision.get() + 1;
+ }
+
+ BTreeHeader<K, V> oldBtreeHeader = getBtreeHeader();
+ BTreeHeader<K, V> newBtreeHeader = createNewBtreeHeader( oldBtreeHeader, revision );
+
// If the key exists, the existing value will be replaced. We store it
// to return it to the caller.
V modifiedValue = null;
@@ -327,7 +375,7 @@ import org.slf4j.LoggerFactory;
// Try to insert the new value in the tree at the right place,
// starting from the root page. Here, the root page may be either
// a Node or a Leaf
- InsertResult<K, V> result = rootPage.insert( revision, key, value );
+ InsertResult<K, V> result = newBtreeHeader.getRootPage().insert( key, value, revision );
if ( result instanceof ModifyResult )
{
@@ -337,7 +385,7 @@ import org.slf4j.LoggerFactory;
// The root has just been modified, we haven't split it
// Get it and make it the current root page
- rootPage = modifiedPage;
+ newBtreeHeader.setRootPage( modifiedPage );
modifiedValue = modifyResult.getModifiedValue();
}
@@ -350,12 +398,9 @@ import org.slf4j.LoggerFactory;
K pivot = splitResult.getPivot();
Page<K, V> leftPage = splitResult.getLeftPage();
Page<K, V> rightPage = splitResult.getRightPage();
- Page<K, V> newRootPage = null;
// Create the new rootPage
- newRootPage = new InMemoryNode<K, V>( this, revision, pivot, leftPage, rightPage );
-
- rootPage = newRootPage;
+ newBtreeHeader.setRootPage( new InMemoryNode<K, V>( this, revision, pivot, leftPage, rightPage ) );
}
// Inject the modification into the modification queue
@@ -368,7 +413,27 @@ import org.slf4j.LoggerFactory;
// and does not replace an element
if ( modifiedValue == null )
{
- btreeHeader.incrementNbElems();
+ newBtreeHeader.incrementNbElems();
+ }
+
+ if ( !inTransaction )
+ {
+ storeRevision( newBtreeHeader );
+
+ commit();
+ }
+
+ if ( oldBtreeHeader.getNbUsers() == 0 )
+ {
+ synchronized ( btreeRevisions )
+ {
+ long oldRevision = oldBtreeHeader.getRevision();
+
+ if ( oldRevision < newBtreeHeader.getRevision() )
+ {
+ btreeRevisions.remove( oldBtreeHeader.getRevision() );
+ }
+ }
}
// Return the value we have found if it was modified
@@ -456,7 +521,7 @@ import org.slf4j.LoggerFactory;
}
// Write the number of elements first
- bb.putLong( btreeHeader.getNbElems() );
+ bb.putLong( getBtreeHeader().getNbElems() );
while ( cursor.hasNext() )
{
@@ -501,8 +566,6 @@ import org.slf4j.LoggerFactory;
*/
private void applyJournal() throws IOException
{
- long revision = generateRevision();
-
if ( !journal.exists() )
{
throw new IOException( "The journal does not exist" );
@@ -535,7 +598,7 @@ import org.slf4j.LoggerFactory;
//values.add( value );
// Inject the data in the tree. (to be replaced by a bulk load)
- insert( key, value, revision );
+ insert( key, value, getBtreeHeader().getRevision() );
}
else
{
@@ -543,7 +606,7 @@ import org.slf4j.LoggerFactory;
K key = keySerializer.deserialize( bufferHandler );
// Remove the key from the tree
- delete( key, revision );
+ delete( key, getBtreeHeader().getRevision() );
}
}
}
@@ -565,8 +628,6 @@ import org.slf4j.LoggerFactory;
*/
public void load( File file ) throws IOException
{
- long revision = generateRevision();
-
if ( !file.exists() )
{
throw new IOException( "The file does not exist" );
@@ -579,11 +640,6 @@ import org.slf4j.LoggerFactory;
BufferHandler bufferHandler = new BufferHandler( channel, buffer );
long nbElems = LongSerializer.deserialize( bufferHandler.read( 8 ) );
- btreeHeader.setNbElems( nbElems );
-
- // Prepare a list of keys and values read from the disk
- //List<K> keys = new ArrayList<K>();
- //List<V> values = new ArrayList<V>();
// desactivate the journal while we load the file
boolean isJournalActivated = withJournal;
@@ -596,15 +652,11 @@ import org.slf4j.LoggerFactory;
// Read the key
K key = keySerializer.deserialize( bufferHandler );
- //keys.add( key );
-
// Read the value
V value = valueSerializer.deserialize( bufferHandler );
- //values.add( value );
-
// Inject the data in the tree. (to be replaced by a bulk load)
- insert( key, value, revision );
+ insert( key, value, getBtreeHeader().getRevision() );
}
// Restore the withJournal value
@@ -616,7 +668,7 @@ import org.slf4j.LoggerFactory;
/**
- * Get the rootPzge associated to a give revision.
+ * Get the rootPage associated to a give revision.
*
* @param revision The revision we are looking for
* @return The rootPage associated to this revision
@@ -626,7 +678,24 @@ import org.slf4j.LoggerFactory;
public Page<K, V> getRootPage( long revision ) throws IOException, KeyNotFoundException
{
// Atm, the in-memory BTree does not support searches in many revisions
- return rootPage;
+ return getBtreeHeader().getRootPage();
+ }
+
+
+ /**
+ * Get the current rootPage
+ *
+ * @return The rootPage
+ */
+ public Page<K, V> getRootPage()
+ {
+ return getBtreeHeader().getRootPage();
+ }
+
+
+ /* no qualifier */void setRootPage( Page<K, V> root )
+ {
+ getBtreeHeader().setRootPage( root );
}
@@ -722,7 +791,53 @@ import org.slf4j.LoggerFactory;
*/
public void beginTransaction()
{
- // Does nothing...
+ automaticTransaction.set( false );
+ beginTransaction( getRevision() + 1 );
+ }
+
+
+ /**
+ * Starts a transaction
+ */
+ private boolean beginTransaction( long revision )
+ {
+ createTransaction.lock();
+
+ if ( writeTransaction == null )
+ {
+ writeTransaction = new WriteTransaction();
+ }
+
+ if ( isTransactionStarted() && !automaticTransaction.get() )
+ {
+ createTransaction.unlock();
+
+ return true;
+ }
+
+ createTransaction.unlock();
+
+ writeTransaction.start();
+
+ return false;
+ }
+
+
+ /**
+ * Create a new B-tree header to be used for update operations
+ * @param revision The reclaimed revision
+ */
+ private BTreeHeader<K, V> createNewBtreeHeader( BTreeHeader<K, V> btreeHeader, long revision )
+ {
+ BTreeHeader<K, V> newBtreeHeader = new BTreeHeader<K, V>();
+
+ newBtreeHeader.setBTreeOffset( btreeHeader.getBTreeOffset() );
+ newBtreeHeader.setRevision( revision );
+ newBtreeHeader.setNbElems( btreeHeader.getNbElems() );
+ newBtreeHeader.setRootPage( btreeHeader.getRootPage() );
+ newBtreeHeader.setRootPageOffset( btreeHeader.getRootPageOffset() );
+
+ return newBtreeHeader;
}
@@ -731,7 +846,41 @@ import org.slf4j.LoggerFactory;
*/
public void commit()
{
- // Does nothing...
+ createTransaction.lock();
+
+ if ( writeTransaction == null )
+ {
+ throw new RuntimeException( "Cannot commit a transaction which hasn't been started");
+ }
+
+ createTransaction.unlock();
+
+ writeTransaction.commit();
+ automaticTransaction.set( true );
+ }
+
+
+ /**
+ * Tells if a transaction has been started or not
+ */
+ private boolean isTransactionStarted()
+ {
+ createTransaction.lock();
+
+ if ( writeTransaction == null )
+ {
+
+ }
+ boolean started = ( writeTransaction != null ) && ( writeTransaction.isStarted() );
+
+ if ( !started )
+ {
+
+ }
+
+ createTransaction.unlock();
+
+ return started;
}
@@ -740,7 +889,16 @@ import org.slf4j.LoggerFactory;
*/
public void rollback()
{
- // Does nothing...
+ createTransaction.lock();
+
+ if ( writeTransaction == null )
+ {
+ throw new RuntimeException( "Cannot rollback a transaction which hasn't been started");
+ }
+
+ createTransaction.unlock();
+
+ writeTransaction.rollback();
}
@@ -760,16 +918,15 @@ import org.slf4j.LoggerFactory;
case BACKED_ON_DISK:
sb.append( "Persistent " );
break;
-
}
sb.append( "BTree" );
- sb.append( "[" ).append( btreeHeader.getName() ).append( "]" );
- sb.append( "( pageSize:" ).append( btreeHeader.getPageSize() );
+ sb.append( "[" ).append( getName() ).append( "]" );
+ sb.append( "( pageSize:" ).append( getPageSize() );
- if ( rootPage != null )
+ if ( getBtreeHeader().getRootPage() != null )
{
- sb.append( ", nbEntries:" ).append( btreeHeader.getNbElems() );
+ sb.append( ", nbEntries:" ).append( getBtreeHeader().getNbElems() );
}
else
{
@@ -787,7 +944,7 @@ import org.slf4j.LoggerFactory;
sb.append( keySerializer.getComparator().getClass().getSimpleName() );
}
- sb.append( ", DuplicatesAllowed: " ).append( btreeHeader.isAllowDuplicates() );
+ sb.append( ", DuplicatesAllowed: " ).append( isAllowDuplicates() );
if ( getType() == BTreeTypeEnum.BACKED_ON_DISK )
{
@@ -822,7 +979,7 @@ import org.slf4j.LoggerFactory;
}
sb.append( ") : \n" );
- sb.append( rootPage.dumpPage( "" ) );
+ sb.append( getRootPage().dumpPage( "" ) );
return sb.toString();
}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryLeaf.java Mon Feb 10 15:35:18 2014
@@ -72,7 +72,7 @@ import org.apache.directory.mavibot.btre
/**
* {@inheritDoc}
*/
- public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+ public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
{
// Find the key into this leaf
int pos = findPos( key );
@@ -117,7 +117,7 @@ import org.apache.directory.mavibot.btre
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
- public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos )
+ /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
throws IOException
{
// Check that the leaf is not empty
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryNode.java Mon Feb 10 15:35:18 2014
@@ -28,7 +28,7 @@ import java.util.List;
/**
* A MVCC Node. It stores the keys and references to its children page. It does not
* contain any value.
- *
+ *
* @param <K> The type for the Key
* @param <V> The type for the stored value
*
@@ -40,7 +40,7 @@ import java.util.List;
* Creates a new Node which will contain only one key, with references to
* a left and right page. This is a specific constructor used by the btree
* when the root was full when we added a new value.
- *
+ *
* @param btree the parent BTree
* @param revision the Node revision
* @param nbElems The number of elements in this Node
@@ -59,7 +59,7 @@ import java.util.List;
* Creates a new Node which will contain only one key, with references to
* a left and right page. This is a specific constructor used by the btree
* when the root was full when we added a new value.
- *
+ *
* @param btree the parent BTree
* @param revision the Node revision
* @param key The new key
@@ -89,7 +89,7 @@ import java.util.List;
/**
* {@inheritDoc}
*/
- public InsertResult<K, V> insert( long revision, K key, V value ) throws IOException
+ public InsertResult<K, V> insert( K key, V value, long revision ) throws IOException
{
// Find the key into this leaf
int pos = findPos( key );
@@ -105,7 +105,7 @@ import java.util.List;
Page<K, V> child = children[pos].getValue();
// and insert the <K, V> into this child
- InsertResult<K, V> result = child.insert( revision, key, value );
+ InsertResult<K, V> result = child.insert( key, value, revision );
// Ok, now, we have injected the <K, V> tuple down the tree. Let's check
// the result to see if we have to split the current page
@@ -145,7 +145,7 @@ import java.util.List;
/**
* Modifies the current node after a remove has been done in one of its children.
* The node won't be merged with another node.
- *
+ *
* @param removeResult The result of a remove operation
* @param index the position of the key, not transformed
* @param pos The position of the key, as a positive value
@@ -188,7 +188,7 @@ import java.util.List;
/**
* Handles the removal of an element from the root page, when two of its children
* have been merged.
- *
+ *
* @param mergedResult The merge result
* @param pos The position in the current root
* @param found Tells if the removed key is present in the root page
@@ -223,7 +223,7 @@ import java.util.List;
* Borrows an element from the right sibling, creating a new sibling with one
* less element and creating a new page where the element to remove has been
* deleted and the borrowed element added on the right.
- *
+ *
* @param revision The new revision for all the pages
* @param sibling The right sibling
* @param pos The position of the element to remove
@@ -308,7 +308,7 @@ import java.util.List;
* Borrows an element from the left sibling, creating a new sibling with one
* less element and creating a new page where the element to remove has been
* deleted and the borrowed element added on the left.
- *
+ *
* @param revision The new revision for all the pages
* @param sibling The left sibling
* @param pos The position of the element to remove
@@ -392,7 +392,7 @@ import java.util.List;
/**
* We have to merge the node with its sibling, both have N/2 elements before the element
* removal.
- *
+ *
* @param revision The revision
* @param mergedResult The result of the merge
* @param sibling The Page we will merge the current page with
@@ -523,7 +523,7 @@ import java.util.List;
/**
* {@inheritDoc}
*/
- public DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos )
+ /* no qualifier */ DeleteResult<K, V> delete( K key, V value, long revision, Page<K, V> parent, int parentPos )
throws IOException
{
// We first try to delete the element from the child it belongs to
@@ -538,12 +538,12 @@ import java.util.List;
{
index = -( pos + 1 );
child = children[-pos].getValue();
- deleteResult = child.delete( revision, key, value, this, -pos );
+ deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, -pos );
}
else
{
child = children[pos].getValue();
- deleteResult = child.delete( revision, key, value, this, pos );
+ deleteResult = ((AbstractPage<K, V>)child).delete( key, value, revision, this, pos );
}
// If the key is not present in the tree, we simply return
@@ -604,7 +604,7 @@ import java.util.List;
// We will remove one element from a page that will have less than N/2 elements,
// which will lead to some reorganization : either we can borrow an element from
// a sibling, or we will have to merge two pages
- int siblingPos = selectSibling( ( InMemoryNode<K, V> ) parent, parentPos );
+ int siblingPos = selectSibling( parent, parentPos );
InMemoryNode<K, V> sibling = ( InMemoryNode<K, V> ) ( ( ( InMemoryNode<K, V> ) parent ).children[siblingPos]
.getValue() );
@@ -717,7 +717,7 @@ import java.util.List;
/**
* Remove the key at a given position.
- *
+ *
* @param mergedResult The page we will remove a key from
* @param revision The revision of the modified page
* @param pos The position into the page of the element to remove
@@ -780,7 +780,7 @@ import java.util.List;
/**
* Set the value at a give position
- *
+ *
* @param pos The position in the values array
* @param value the value to inject
*/
@@ -794,7 +794,7 @@ import java.util.List;
* This method is used when we have to replace a child in a page when we have
* found the key in the tree (the value will be changed, so we have made
* copies of the existing pages).
- *
+ *
* @param revision The current revision
* @param result The modified page
* @param pos The position of the found key
@@ -825,7 +825,7 @@ import java.util.List;
/**
* Adds a new key into a copy of the current page at a given position. We return the
* modified page. The new page will have one more key than the current page.
- *
+ *
* @param copiedPages the list of copied pages
* @param revision The revision of the modified page
* @param key The key to insert
@@ -880,7 +880,7 @@ import java.util.List;
* If the newly added element is in the middle, we will use it
* as a pivot. Otherwise, we will use either the last element in the left page if the element is added
* on the left, or the first element in the right page if it's added on the right.
- *
+ *
* @param copiedPages the list of copied pages
* @param revision The new revision for all the created pages
* @param pivot The key that will be move up after the split
@@ -978,7 +978,7 @@ import java.util.List;
/**
* Copies the current page and all its keys, with a new revision.
- *
+ *
* @param revision The new revision
* @return The copied page
*/
Added: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java?rev=1566659&view=auto
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java (added)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/InMemoryTransactionManager.java Mon Feb 10 15:35:18 2014
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.mavibot.btree;
+
+/**
+ * An implementation of a TransactionManager for in-memory B-trees
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class InMemoryTransactionManager implements TransactionManager
+{
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void beginTransaction()
+ {
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void commit()
+ {
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void rollback()
+ {
+ }
+}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionComparator.java Mon Feb 10 15:35:18 2014
@@ -30,6 +30,17 @@ import java.util.Comparator;
*/
/* no qualifier*/class NameRevisionComparator implements Comparator<NameRevision>
{
+ /** A static instance of a NameRevisionComparator */
+ public static final NameRevisionComparator INSTANCE = new NameRevisionComparator();
+
+ /**
+ * A private constructor of the NameRevisionComparator class
+ */
+ private NameRevisionComparator()
+ {
+ }
+
+
/**
* {@inheritDoc}
*/
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/NameRevisionSerializer.java Mon Feb 10 15:35:18 2014
@@ -41,12 +41,15 @@ import org.apache.directory.mavibot.btre
*/
/* no qualifier*/class NameRevisionSerializer extends AbstractElementSerializer<NameRevision>
{
+ /** A static instance of a NameRevisionSerializer */
+ /*No qualifier*/ final static NameRevisionSerializer INSTANCE = new NameRevisionSerializer();
+
/**
* Create a new instance of a NameRevisionSerializer
*/
- /* no qualifier*/NameRevisionSerializer()
+ private NameRevisionSerializer()
{
- super( new NameRevisionComparator() );
+ super( NameRevisionComparator.INSTANCE );
}
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/Page.java Mon Feb 10 15:35:18 2014
@@ -31,7 +31,7 @@ import org.apache.directory.mavibot.btre
* (containing keys and references to child pages).<br/>
* A Page can be stored on disk. If so, we store the serialized value of this Page into
* one or more {@link PageIO} (they will be linked)
- *
+ *
* @param <K> The type for the Key
* @param <V> The type for the stored value
*
@@ -56,22 +56,22 @@ import org.apache.directory.mavibot.btre
* the Page is full, we split it and propagate the new pivot up into the tree</li>
* </ul>
* <p>
- *
- * @param revision The new revision for the modified pages
+ *
* @param key Inserted key
* @param value Inserted value
+ * @param revision The new revision for the modified pages
* @return Either a modified Page or an Overflow element if the Page was full
* @throws IOException If we have an error while trying to access the page
*/
- InsertResult<K, V> insert( long revision, K key, V value ) throws IOException;
+ InsertResult<K, V> insert( K key, V value, long revision ) throws IOException;
/**
- * Deletes the value from an entry associated with the given key in this page. We first find
+ * Deletes the value from an entry associated with the given key in this page. We first find
* the place were to remove the <K,V> into the tree, by recursively browsing the pages.
- * If the value is present, it will be deleted first, later if there are no other values associated with
+ * If the value is present, it will be deleted first, later if there are no other values associated with
* this key(which can happen when duplicates are enabled), we will remove the key from the tree.
- *
+ *
* @param revision The new revision for the modified pages
* @param key The key to delete
* @param value The value to delete (can be null)
@@ -80,15 +80,15 @@ import org.apache.directory.mavibot.btre
* @return Either a modified Page if the key has been removed from the page, or a NotPresentResult.
* @throws IOException If we have an error while trying to access the page
*/
- DeleteResult<K, V> delete( long revision, K key, V value, Page<K, V> parent, int parentPos ) throws IOException;
+ DeleteResult<K, V> delete( K key, V value, long revision /*, Page<K, V> parent, int parentPos*/ ) throws IOException;
/**
- * Gets the value associated with the given key, if any. If we don't have
+ * Gets the value associated with the given key, if any. If we don't have
* one, this method will throw a KeyNotFoundException.<br/>
- * Note that we may get back null if a null value has been associated
+ * Note that we may get back null if a null value has been associated
* with the key.
- *
+ *
* @param key The key we are looking for
* @return The associated value, which can be null
* @throws KeyNotFoundException If no entry with the given key can be found
@@ -98,23 +98,23 @@ import org.apache.directory.mavibot.btre
/**
- * Gets the values associated with the given key, if any. If we don't have
+ * Gets the values associated with the given key, if any. If we don't have
* the key, this method will throw a KeyNotFoundException.<br/>
- * Note that we may get back null if a null value has been associated
+ * Note that we may get back null if a null value has been associated
* with the key.
- *
+ *
* @param key The key we are looking for
* @return The associated value, which can be null
* @throws KeyNotFoundException If no entry with the given key can be found
* @throws IOException If we have an error while trying to access the page
- * @throws IllegalArgumentException If duplicates are not enabled
+ * @throws IllegalArgumentException If duplicates are not enabled
*/
ValueCursor<V> getValues( K key ) throws KeyNotFoundException, IOException, IllegalArgumentException;
/**
* Checks if the page 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
@@ -125,7 +125,7 @@ import org.apache.directory.mavibot.btre
/**
* Browses the tree, looking for the given key, and creates a Cursor on top
* of the found result.
- *
+ *
* @param key The key we are looking for.
* @param transaction The started transaction for this operation
* @param stack The stack of parents we go through to get to this page
@@ -138,7 +138,7 @@ import org.apache.directory.mavibot.btre
/**
* Browses the whole tree, and creates a Cursor on top of it.
- *
+ *
* @param transaction The started transaction for this operation
* @param stack The stack of parents we go through to get to this page
* @return A Cursor to browse the next elements
@@ -156,7 +156,7 @@ import org.apache.directory.mavibot.btre
/**
* 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
*/
@@ -166,7 +166,7 @@ import org.apache.directory.mavibot.btre
/**
* Finds the leftmost key in this page. If the page is a node, it will go
* down in the leftmost children to recursively find the leftmost key.
- *
+ *
* @return The leftmost key in the tree
*/
K getLeftMostKey();
@@ -175,7 +175,7 @@ import org.apache.directory.mavibot.btre
/**
* Finds the rightmost key in this page. If the page is a node, it will go
* down in the rightmost children to recursively find the rightmost key.
- *
+ *
* @return The rightmost key in the tree
*/
K getRightMostKey();
@@ -184,7 +184,7 @@ import org.apache.directory.mavibot.btre
/**
* Finds the leftmost element in this page. If the page is a node, it will go
* down in the leftmost children to recursively find the leftmost element.
- *
+ *
* @return The leftmost element in the tree
* @throws IOException If we have an error while trying to access the page
*/
@@ -194,7 +194,7 @@ import org.apache.directory.mavibot.btre
/**
* Finds the rightmost element in this page. If the page is a node, it will go
* down in the rightmost children to recursively find the rightmost element.
- *
+ *
* @return The rightmost element in the tree
* @throws IOException If we have an error while trying to access the page
*/
@@ -240,8 +240,8 @@ import org.apache.directory.mavibot.btre
* <li>'h' will return -4</li>
* <li>'i' will return 4</li>
* </ul>
- *
- *
+ *
+ *
* @param key The key to find
* @return The position in the page.
*/
@@ -250,7 +250,7 @@ import org.apache.directory.mavibot.btre
/**
* 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
Modified: directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java
URL: http://svn.apache.org/viewvc/directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java?rev=1566659&r1=1566658&r2=1566659&view=diff
==============================================================================
--- directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java (original)
+++ directory/mavibot/branches/with-txns/mavibot/src/main/java/org/apache/directory/mavibot/btree/PageIO.java Mon Feb 10 15:35:18 2014
@@ -34,25 +34,25 @@ import org.apache.directory.mavibot.btre
* Here is the logical structure of a PageIO :
* <pre>
* For a first page :
- *
+ *
* +----------+------+----------------------+
* | nextPage | size | XXXXXXXXXXXXXXXXXXXX |
* +----------+------+----------------------+
- *
+ *
* for any page but the first :
- *
+ *
* +----------+-----------------------------+
* | nextPage | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
* +----------+-----------------------------+
- *
+ *
* for the last page :
* +----------+-----------------------------+
* | -1 | XXXXXXXXXXXXXXXXXXXXXXXXXXX |
* +----------+-----------------------------+
- *
+ *
* In any case, the page length is always PageSize.
* </pre>
- *
+ *
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
/* No qualifier*/class PageIO
@@ -70,7 +70,7 @@ import org.apache.directory.mavibot.btre
private long offset;
- /**
+ /**
* A default constructor for a PageIO
*/
/* no qualifier */PageIO()
@@ -81,7 +81,7 @@ import org.apache.directory.mavibot.btre
}
- /**
+ /**
* A constructor for a PageIO when we know the offset of this page on disk
*/
/* no qualifier */PageIO( long offset )
@@ -179,6 +179,45 @@ import org.apache.directory.mavibot.btre
}
+ /* no qualifier */PageIO copy( PageIO copy )
+ {
+ // The data
+ if ( data.isDirect() )
+ {
+ copy.data = ByteBuffer.allocateDirect( data.capacity() );
+ }
+ else
+ {
+ copy.data = ByteBuffer.allocate( data.capacity() );
+ }
+
+ // Save the original buffer position and limit
+ int start = data.position();
+ int limit = data.limit();
+
+ // The data is extended to get all the bytes in it
+ data.position( 0 );
+ data.limit( data.capacity() );
+
+ // Copy the data
+ copy.data.put( data );
+
+ // Restore the original buffer to the initial position and limit
+ data.position( start );
+ data.limit( limit );
+
+ // Set those position and limit in the copied buffer
+ copy.data.position( start );
+ copy.data.limit( limit );
+
+ // The size
+ copy.size = size;
+
+ // The offset and next page pointers are not copied.
+ return copy;
+ }
+
+
/**
* @see Object#toString()
*/
@@ -186,7 +225,7 @@ import org.apache.directory.mavibot.btre
{
StringBuilder sb = new StringBuilder();
- sb.append( "PageIO[offset:" ).append( offset );
+ sb.append( "PageIO[offset:" ).append( Long.toHexString( offset ) );
if ( size != -1 )
{