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 2013/09/30 08:32:28 UTC
svn commit: r1527458 [7/14] - in /directory/mavibot/trunk/mavibot: img/
src/main/java/org/apache/directory/mavibot/btree/
src/main/java/org/apache/directory/mavibot/btree/managed/
src/main/java/org/apache/directory/mavibot/btree/memory/ src/main/java/o...
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/ReferenceHolder.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/ReferenceHolder.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/ReferenceHolder.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/ReferenceHolder.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,147 @@
+/*
+ * 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.managed;
+
+
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+
+import org.apache.directory.mavibot.btree.exception.EndOfFileExceededException;
+
+
+/**
+ * A Value holder. As we may not store all the values in memory (except for an in-memory
+ * BTree), we will use a SoftReference to keep a reference to a Value, and if it's null,
+ * then we will load the Value from the underlying physical support, using the offset.
+ *
+ * @param <E> The type for the stored element (either a value or a page)
+ * @param <K> The type of the BTree key
+ * @param <V> The type of the BTree value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ReferenceHolder<E, K, V> implements ElementHolder<E, K, V>
+{
+ /** The BTree */
+ private BTree<K, V> btree;
+
+ /** The offset of the first {@link PageIO} storing the page on disk */
+ private long offset;
+
+ /** The offset of the last {@link PageIO} storing the page on disk */
+ private long lastOffset;
+
+ /** The reference to the element instance, or null if it's not present */
+ private SoftReference<E> reference;
+
+
+ /**
+ * Create a new holder storing an offset and a SoftReference containing the element.
+ *
+ * @param offset The offset in disk for this value
+ * @param element The element to store into a SoftReference
+ */
+ public ReferenceHolder( BTree<K, V> btree, E element, long offset, long lastOffset )
+ {
+ this.btree = btree;
+ this.offset = offset;
+ this.lastOffset = lastOffset;
+ this.reference = new SoftReference<E>( element );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ * @throws IOException
+ * @throws EndOfFileExceededException
+ */
+ @Override
+ public E getValue( BTree<K, V> btree ) throws EndOfFileExceededException, IOException
+ {
+ E element = reference.get();
+
+ if ( element == null )
+ {
+ // We have to fetch the element from disk, using the offset now
+ Page<K, V> page = fetchElement( btree );
+ reference = ( SoftReference<E> ) new SoftReference<Page<K, V>>( page );
+
+ return ( E ) page;
+ }
+ else
+ {
+ return element;
+ }
+ }
+
+
+ /**
+ * Retrieve the value from the disk, using the BTree and offset
+ * @return The deserialized element (
+ * @throws IOException
+ * @throws EndOfFileExceededException
+ */
+ private Page<K, V> fetchElement( BTree<K, V> btree ) throws EndOfFileExceededException, IOException
+ {
+ Page<K, V> element = btree.getRecordManager().deserialize( btree, offset );
+
+ return element;
+ }
+
+
+ /**
+ * @return The offset of the first {@link PageIO} storing the data on disk
+ */
+ /* No qualifier */long getOffset()
+ {
+ return offset;
+ }
+
+
+ /**
+ * @return The offset of the last {@link PageIO} storing the data on disk
+ */
+ /* No qualifier */long getLastOffset()
+ {
+ return lastOffset;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ E element = reference.get();
+
+ if ( element != null )
+ {
+ sb.append( btree.getName() ).append( "[" ).append( offset ).append( "]:" ).append( element );
+ }
+ else
+ {
+ sb.append( btree.getName() ).append( "[" ).append( offset ).append( "]" );
+ }
+
+ return sb.toString();
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RemoveResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RemoveResult.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RemoveResult.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RemoveResult.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.managed;
+
+
+import java.util.List;
+
+import org.apache.directory.mavibot.btree.Tuple;
+
+
+/**
+ * The result of a delete operation, when the child has not been merged. It contains the
+ * reference to the modified page, and the removed element.
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+/* No qualifier */class RemoveResult<K, V> extends AbstractDeleteResult<K, V>
+{
+ /**
+ * The default constructor for RemoveResult.
+ *
+ * @param modifiedPage The modified page
+ * @param removedElement The removed element (can be null if the key wasn't present in the tree)
+ */
+ /* No qualifier */RemoveResult( Page<K, V> modifiedPage, Tuple<K, V> removedElement )
+ {
+ super( modifiedPage, removedElement );
+ }
+
+
+ /**
+ * A constructor for RemoveResult which takes a list of copied pages.
+ *
+ * @param copiedPages the list of copied pages
+ * @param modifiedPage The modified page
+ * @param removedElement The removed element (can be null if the key wasn't present in the tree)
+ */
+ /* No qualifier */RemoveResult( List<Page<K, V>> copiedPages, Page<K, V> modifiedPage, Tuple<K, V> removedElement )
+ {
+ super( copiedPages, modifiedPage, removedElement );
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "RemoveResult :" );
+ sb.append( "\n removed element = " ).append( getRemovedElement() );
+ sb.append( "\n modifiedPage = " ).append( getModifiedPage() );
+
+ return sb.toString();
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionName.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionName.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionName.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionName.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,136 @@
+/*
+ * 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.managed;
+
+
+/**
+ * A data structure that stores a revision associated to a BTree name. We use
+ * it to allow the access to old revisions.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class RevisionName
+{
+ /** The revision number on the BTree */
+ private long revision;
+
+ /** The BTree name */
+ private String name;
+
+
+ /**
+ * A constructor for the RevisionName class
+ * @param revision The revision
+ * @param name The BTree name
+ */
+ public RevisionName( long revision, String name )
+ {
+ this.revision = revision;
+ this.name = name;
+ }
+
+
+ /**
+ * @return the revision
+ */
+ public long getRevision()
+ {
+ return revision;
+ }
+
+
+ /**
+ * @param revision the revision to set
+ */
+ public void setRevision( long revision )
+ {
+ this.revision = revision;
+ }
+
+
+ /**
+ * @return the btree name
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+
+ /**
+ * @param name the btree name to set
+ */
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+
+ /**
+ * @see Object#equals(Object)
+ */
+ public boolean equals( Object that )
+ {
+ if ( this == that )
+ {
+ return true;
+ }
+
+ if ( !( that instanceof RevisionName ) )
+ {
+ return false;
+ }
+
+ RevisionName revisionName = ( RevisionName ) that;
+
+ if ( revision != revisionName.revision )
+ {
+ return false;
+ }
+
+ if ( name == null )
+ {
+ return revisionName.name == null;
+ }
+
+ return ( name.equals( revisionName.name ) );
+
+ }
+
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
+ result = prime * result + ( int ) ( revision ^ ( revision >>> 32 ) );
+ return result;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return "[" + name + ":" + revision + "]";
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameComparator.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameComparator.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameComparator.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameComparator.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,56 @@
+/*
+ * 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.managed;
+
+
+import java.util.Comparator;
+
+
+/**
+ * A comparator for the RevisionName class
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class RevisionNameComparator implements Comparator<RevisionName>
+{
+ /**
+ * {@inheritDoc}
+ */
+ public int compare( RevisionName rn1, RevisionName rn2 )
+ {
+ if ( rn1 == rn2 )
+ {
+ return 0;
+ }
+
+ // First compare the revisions
+ if ( rn1.getRevision() < rn2.getRevision() )
+ {
+ return -1;
+ }
+ else if ( rn1.getRevision() > rn2.getRevision() )
+ {
+ return 1;
+ }
+
+ // The revision are equal : check the name
+ return rn1.getName().compareTo( rn2.getName() );
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameSerializer.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameSerializer.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameSerializer.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/RevisionNameSerializer.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,208 @@
+/*
+ * 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.managed;
+
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.directory.mavibot.btree.serializer.AbstractElementSerializer;
+import org.apache.directory.mavibot.btree.serializer.BufferHandler;
+import org.apache.directory.mavibot.btree.serializer.ByteArraySerializer;
+import org.apache.directory.mavibot.btree.serializer.IntSerializer;
+import org.apache.directory.mavibot.btree.serializer.LongSerializer;
+import org.apache.directory.mavibot.btree.serializer.StringSerializer;
+import org.apache.directory.mavibot.btree.util.Strings;
+
+
+/**
+ * A serializer for the RevisionName object. The RevisionName will be serialized
+ * as a long (the revision), followed by the String.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class RevisionNameSerializer extends AbstractElementSerializer<RevisionName>
+{
+ /**
+ * Create a new instance of a RevisionNameSerializer
+ */
+ public RevisionNameSerializer()
+ {
+ super( new RevisionNameComparator() );
+ }
+
+
+ /**
+ * A static method used to deserialize a RevisionName from a byte array.
+ *
+ * @param in The byte array containing the RevisionName
+ * @return A RevisionName instance
+ */
+ public static RevisionName deserialize( byte[] in )
+ {
+ return deserialize( in, 0 );
+ }
+
+
+ /**
+ * A static method used to deserialize a RevisionName from a byte array.
+ *
+ * @param in The byte array containing the RevisionName
+ * @param start the position in the byte[] we will deserialize the RevisionName from
+ * @return A RevisionName instance
+ */
+ public static RevisionName deserialize( byte[] in, int start )
+ {
+ // The buffer must be 8 bytes plus 4 bytes long (the revision is a long, and the name is a String
+ if ( ( in == null ) || ( in.length < 12 + start ) )
+ {
+ throw new RuntimeException( "Cannot extract a RevisionName from a buffer with not enough bytes" );
+ }
+
+ long revision = LongSerializer.deserialize( in, start );
+ String name = StringSerializer.deserialize( in, 8 + start );
+
+ RevisionName revisionName = new RevisionName( revision, name );
+
+ return revisionName;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte[] serialize( RevisionName revisionName )
+ {
+ if ( revisionName == null )
+ {
+ throw new RuntimeException( "The revisionName instance should not be null " );
+ }
+
+ byte[] result = null;
+
+ if ( revisionName.getName() != null )
+ {
+ byte[] stringBytes = Strings.getBytesUtf8( revisionName.getName() );
+ int stringLen = stringBytes.length;
+ result = new byte[8 + 4 + stringBytes.length];
+ LongSerializer.serialize( result, 0, revisionName.getRevision() );
+
+ if ( stringLen > 0 )
+ {
+ ByteArraySerializer.serialize( result, 8, stringBytes );
+ }
+ }
+ else
+ {
+ result = new byte[8 + 4];
+ LongSerializer.serialize( result, 0, revisionName.getRevision() );
+ StringSerializer.serialize( result, 8, null );
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Serialize a RevisionName
+ *
+ * @param buffer the Buffer that will contain the serialized value
+ * @param start the position in the buffer we will store the serialized RevisionName
+ * @param value the value to serialize
+ * @return The byte[] containing the serialized RevisionName
+ */
+ public static byte[] serialize( byte[] buffer, int start, RevisionName revisionName )
+ {
+ if ( revisionName.getName() != null )
+ {
+ byte[] stringBytes = Strings.getBytesUtf8( revisionName.getName() );
+ int stringLen = stringBytes.length;
+ LongSerializer.serialize( buffer, start, revisionName.getRevision() );
+ IntSerializer.serialize( buffer, 8 + start, stringLen );
+ ByteArraySerializer.serialize( buffer, 12 + start, stringBytes );
+ }
+ else
+ {
+ LongSerializer.serialize( buffer, start, revisionName.getRevision() );
+ StringSerializer.serialize( buffer, 8, null );
+ }
+
+ return buffer;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public RevisionName deserialize( BufferHandler bufferHandler ) throws IOException
+ {
+ byte[] revisionBytes = bufferHandler.read( 8 );
+ long revision = LongSerializer.deserialize( revisionBytes );
+
+ byte[] lengthBytes = bufferHandler.read( 4 );
+
+ int len = IntSerializer.deserialize( lengthBytes );
+
+ switch ( len )
+ {
+ case 0:
+ return new RevisionName( revision, "" );
+
+ case -1:
+ return new RevisionName( revision, null );
+
+ default:
+ byte[] nameBytes = bufferHandler.read( len );
+
+ return new RevisionName( revision, Strings.utf8ToString( nameBytes ) );
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public RevisionName deserialize( ByteBuffer buffer ) throws IOException
+ {
+ // The revision
+ long revision = buffer.getLong();
+
+ // The name's length
+ int len = buffer.getInt();
+
+ switch ( len )
+ {
+ case 0:
+ return new RevisionName( revision, "" );
+
+ case -1:
+ return new RevisionName( revision, null );
+
+ default:
+ byte[] nameBytes = new byte[len];
+ buffer.get( nameBytes );
+
+ return new RevisionName( revision, Strings.utf8ToString( nameBytes ) );
+ }
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/SplitResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/SplitResult.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/SplitResult.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/SplitResult.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,120 @@
+/*
+ * 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.managed;
+
+
+import java.util.List;
+
+
+/**
+ * The result of an insert operation, when the page has been split. It contains
+ * the new pivotal value, plus the reference on the two new pages.
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+/* No qualifier */class SplitResult<K, V> extends AbstractResult<K, V> implements InsertResult<K, V>
+{
+ /** The left child */
+ protected Page<K, V> leftPage;
+
+ /** The right child */
+ protected Page<K, V> rightPage;
+
+ /** The key pivot */
+ protected K pivot;
+
+
+ /**
+ * The default constructor for SplitResult.
+ * @param pivot The new key to insert into the parent
+ * @param leftPage The new left page
+ * @param rightPage The new right page
+ */
+ /* No qualifier */SplitResult( K pivot, Page<K, V> leftPage, Page<K, V> rightPage )
+ {
+ super();
+ this.pivot = pivot;
+ this.leftPage = leftPage;
+ this.rightPage = rightPage;
+ }
+
+
+ /**
+ * A constructor for SplitResult with copied pages.
+ *
+ * @param copiedPages the list of copied pages
+ * @param pivot The new key to insert into the parent
+ * @param leftPage The new left page
+ * @param rightPage The new right page
+ */
+ /* No qualifier */SplitResult( List<Page<K, V>> copiedPages, K pivot, Page<K, V> leftPage, Page<K, V> rightPage )
+ {
+ super( copiedPages );
+ this.pivot = pivot;
+ this.leftPage = leftPage;
+ this.rightPage = rightPage;
+ }
+
+
+ /**
+ * @return the leftPage
+ */
+ /* No qualifier */Page<K, V> getLeftPage()
+ {
+ return leftPage;
+ }
+
+
+ /**
+ * @return the rightPage
+ */
+ /* No qualifier */Page<K, V> getRightPage()
+ {
+ return rightPage;
+ }
+
+
+ /**
+ * @return the pivot
+ */
+ /* No qualifier */K getPivot()
+ {
+ return pivot;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "SplitResult, new pivot = " ).append( pivot );
+ sb.append( "\n leftPage = " ).append( leftPage );
+ sb.append( "\n rightPage = " ).append( rightPage );
+ sb.append( super.toString() );
+
+ return sb.toString();
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/Transaction.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/Transaction.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/Transaction.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/managed/Transaction.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,128 @@
+/*
+ * 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.managed;
+
+
+import java.util.Date;
+
+
+/**
+ * The Transaction is used to protect the BTree against concurrent modifcation,
+ * and insure that a read is always done against one single revision. It's also
+ * used to gather many modifications under one single revision, if needed.
+ * <p/>
+ * A Transaction should be closed when the user is done with it, otherwise the
+ * pages associated with the given revision, and all the referenced pages, will
+ * remain on the storage.
+ * <p/>
+ * A Transaction can be hold for quite a long time, for instance while doing
+ * a browse against a big BTree. At some point, transactions which are pending
+ * for too long will be closed by the transaction manager.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ */
+public class Transaction<K, V>
+{
+ /** The associated revision */
+ private long revision;
+
+ /** The date of creation */
+ private long creationDate;
+
+ /** The revision on which we are having a transaction */
+ private volatile Page<K, V> root;
+
+ /** A flag used to tell if a transaction is closed ot not */
+ private volatile boolean closed;
+
+
+ /**
+ * Creates a new transaction instance
+ *
+ * @param root The associated root
+ * @param revision The revision this transaction is using
+ * @param creationDate The creation date for this transaction
+ */
+ public Transaction( Page<K, V> root, long revision, long creationDate )
+ {
+ this.revision = revision;
+ this.creationDate = creationDate;
+ this.root = root;
+ closed = false;
+ }
+
+
+ /**
+ * @return the associated revision
+ */
+ public long getRevision()
+ {
+ return revision;
+ }
+
+
+ /**
+ * @return the associated root
+ */
+ public Page<K, V> getRoot()
+ {
+ return root;
+ }
+
+
+ /**
+ * @return the creationDate
+ */
+ public long getCreationDate()
+ {
+ return creationDate;
+ }
+
+
+ /**
+ * Close the transaction, releasing the revision it was using.
+ */
+ public void close()
+ {
+ root = null;
+ closed = true;
+ }
+
+
+ /**
+ * @return true if this transaction has been closed
+ */
+ public boolean isClosed()
+ {
+ return closed;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return "Transaction[" + revision + ":" + new Date( creationDate ) + ", closed :" + closed + "]";
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractBorrowedFromSiblingResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractBorrowedFromSiblingResult.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractBorrowedFromSiblingResult.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractBorrowedFromSiblingResult.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,129 @@
+/*
+ * 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.memory;
+
+
+import java.util.List;
+
+import org.apache.directory.mavibot.btree.Tuple;
+
+
+/**
+ * The result of a delete operation, when the child has not been merged, and when
+ * we have borrowed an element from the left sibling. It contains the
+ * reference to the modified page, and the removed element.
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+/* No qualifier */abstract class AbstractBorrowedFromSiblingResult<K, V> extends AbstractDeleteResult<K, V> implements
+ BorrowedFromSiblingResult<K, V>
+{
+ /** The modified sibling reference */
+ private Page<K, V> modifiedSibling;
+
+ /** Tells if the sibling is the left or right one */
+ protected SiblingPosition position;
+
+ /** The two possible position for the sibling */
+ protected enum SiblingPosition
+ {
+ LEFT,
+ RIGHT
+ }
+
+
+ /**
+ * The default constructor for RemoveResult.
+ *
+ * @param modifiedPage The modified page
+ * @param modifiedSibling The modified sibling
+ * @param removedElement The removed element (can be null if the key wasn't present in the tree)
+ */
+ /* No qualifier */AbstractBorrowedFromSiblingResult( Page<K, V> modifiedPage, Page<K, V> modifiedSibling,
+ Tuple<K, V> removedElement, SiblingPosition position )
+ {
+ super( modifiedPage, removedElement );
+ this.modifiedSibling = modifiedSibling;
+ this.position = position;
+ }
+
+
+ /**
+ * A constructor for RemoveResult with a list of copied pages.
+ *
+ * @param copiedPages the list of copied pages
+ * @param modifiedPage The modified page
+ * @param modifiedSibling The modified sibling
+ * @param removedElement The removed element (can be null if the key wasn't present in the tree)
+ */
+ /* No qualifier */AbstractBorrowedFromSiblingResult( List<Page<K, V>> copiedPages, Page<K, V> modifiedPage,
+ Page<K, V> modifiedSibling,
+ Tuple<K, V> removedElement, SiblingPosition position )
+ {
+ super( copiedPages, modifiedPage, removedElement );
+ this.modifiedSibling = modifiedSibling;
+ this.position = position;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Page<K, V> getModifiedSibling()
+ {
+ return modifiedSibling;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isFromLeft()
+ {
+ return position == SiblingPosition.LEFT;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isFromRight()
+ {
+ return position == SiblingPosition.RIGHT;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "\n removed element : " ).append( getRemovedElement() );
+ sb.append( "\n modifiedPage : " ).append( getModifiedPage() );
+ sb.append( "\n modifiedSibling : " ).append( getModifiedSibling() );
+
+ return sb.toString();
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractDeleteResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractDeleteResult.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractDeleteResult.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractDeleteResult.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,101 @@
+/*
+ * 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.memory;
+
+
+import java.util.List;
+
+import org.apache.directory.mavibot.btree.Tuple;
+
+
+/**
+ * An abstract class to gather common elements of the DeleteResult
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @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>
+{
+ /** 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 default constructor for AbstractDeleteResult.
+ *
+ * @param modifiedPage The modified page
+ * @param removedElement The removed element (can be null if the key wasn't present in the tree)
+ */
+ /* No qualifier */AbstractDeleteResult( Page<K, V> modifiedPage, Tuple<K, V> removedElement )
+ {
+ super();
+ this.modifiedPage = modifiedPage;
+ this.removedElement = removedElement;
+ }
+
+
+ /**
+ * The default constructor for AbstractDeleteResult.
+ *
+ * @param copiedPages the list of copied pages
+ * @param modifiedPage The modified page
+ * @param removedElement The removed element (can be null if the key wasn't present in the tree)
+ */
+ /* No qualifier */AbstractDeleteResult( List<Page<K, V>> copiedPages, Page<K, V> modifiedPage,
+ Tuple<K, V> removedElement )
+ {
+ super( copiedPages );
+ this.modifiedPage = modifiedPage;
+ this.removedElement = removedElement;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Page<K, V> getModifiedPage()
+ {
+ return modifiedPage;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Tuple<K, V> getRemovedElement()
+ {
+ return removedElement;
+ }
+
+
+ /**
+ * @param modifiedPage the modifiedPage to set
+ */
+ /* No qualifier */void setModifiedPage( Page<K, V> modifiedPage )
+ {
+ this.modifiedPage = modifiedPage;
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractPage.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractPage.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractPage.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractPage.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,357 @@
+/*
+ * 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.memory;
+
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+
+
+/**
+ * A MVCC abstract Page. It stores the field and the methods shared by the Node and Leaf
+ * classes.
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+/* No qualifier */abstract class AbstractPage<K, V> implements Page<K, V>
+{
+ /** Parent B+Tree. */
+ protected transient BTree<K, V> btree;
+
+ /** This BPage's revision */
+ protected long revision;
+
+ /** Keys of children nodes */
+ protected K[] keys;
+
+ /** The number of current values in the Page */
+ protected int nbElems;
+
+ /** The first {@link PageIO} storing the serialized Page on disk */
+ private long offset = -1L;
+
+ /** The last {@link PageIO} storing the serialized Page on disk */
+ private long lastOffset = -1L;
+
+
+ /**
+ * Creates a default empty AbstractPage
+ *
+ * @param btree The associated BTree
+ */
+ protected AbstractPage( BTree<K, V> btree )
+ {
+ this.btree = btree;
+ }
+
+
+ /**
+ * Internal constructor used to create Page instance used when a page is being copied or overflow
+ */
+ @SuppressWarnings("unchecked")
+ // Cannot create an array of generic objects
+ protected AbstractPage( BTree<K, V> btree, long revision, int nbElems )
+ {
+ this.btree = btree;
+ this.revision = revision;
+ this.nbElems = nbElems;
+
+ // We get the type of array to create from the btree
+ // Yes, this is an hack...
+ Class<?> keyType = btree.getKeyType();
+ this.keys = ( K[] ) Array.newInstance( keyType, nbElems );
+ }
+
+
+ /**
+ * Selects the sibling (the previous or next page with the same parent) which has
+ * the more element assuming it's above N/2
+ *
+ * @param parent The parent of the current page
+ * @param 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( Node<K, V> parent, int parentPos ) throws IOException
+ {
+ if ( parentPos == 0 )
+ {
+ // The current page is referenced on the left of its parent's page :
+ // we will not have a previous page with the same parent
+ return 1;
+ }
+
+ if ( parentPos == parent.getNbElems() )
+ {
+ // 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 = parent.children[parentPos - 1].getValue( btree );
+ Page<K, V> nextPage = parent.children[parentPos + 1].getValue( btree );
+
+ int prevPageSize = prevPage.getNbElems();
+ int nextPageSize = nextPage.getNbElems();
+
+ if ( prevPageSize >= nextPageSize )
+ {
+ return parentPos - 1;
+ }
+ else
+ {
+ return parentPos + 1;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getNbElems()
+ {
+ return nbElems;
+ }
+
+
+ /**
+ * Finds the position of the given key in the page. If we have found the key,
+ * we will return its position as a negative value.
+ * <p/>
+ * Assuming that the array is zero-indexed, the returned value will be : <br/>
+ * position = - ( position + 1)
+ * <br/>
+ * So for the following table of keys : <br/>
+ * <pre>
+ * +---+---+---+---+
+ * | b | d | f | h |
+ * +---+---+---+---+
+ * 0 1 2 3
+ * </pre>
+ * looking for 'b' will return -1 (-(0+1)) and looking for 'f' will return -3 (-(2+1)).<br/>
+ * Computing the real position is just a matter to get -(position++).
+ * <p/>
+ * If we don't find the key in the table, we will return the position of the key
+ * immediately above the key we are looking for. <br/>
+ * For instance, looking for :
+ * <ul>
+ * <li>'a' will return 0</li>
+ * <li>'b' will return -1</li>
+ * <li>'c' will return 1</li>
+ * <li>'d' will return -2</li>
+ * <li>'e' will return 2</li>
+ * <li>'f' will return -3</li>
+ * <li>'g' will return 3</li>
+ * <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.
+ */
+ public int findPos( K key )
+ {
+ // Deal with the special key where we have an empty page
+ if ( nbElems == 0 )
+ {
+ return 0;
+ }
+
+ int min = 0;
+ int max = nbElems - 1;
+
+ // binary search
+ while ( min < max )
+ {
+ int middle = ( min + max + 1 ) >> 1;
+
+ int comp = compare( keys[middle], key );
+
+ if ( comp < 0 )
+ {
+ min = middle + 1;
+ }
+ else if ( comp > 0 )
+ {
+ max = middle - 1;
+ }
+ else
+ {
+ // Special case : the key already exists,
+ // we can return immediately. The value will be
+ // negative, and as the index may be 0, we subtract 1
+ return -( middle + 1 );
+ }
+ }
+
+ // Special case : we don't know if the key is present
+ int comp = compare( keys[max], key );
+
+ if ( comp == 0 )
+ {
+ return -( max + 1 );
+ }
+ else
+ {
+ if ( comp < 0 )
+ {
+ return max + 1;
+ }
+ else
+ {
+ return max;
+ }
+ }
+ }
+
+
+ /**
+ * Compares two keys
+ *
+ * @param key1 The first key
+ * @param key2 The second key
+ * @return -1 if the first key is above the second one, 1 if it's below, and 0
+ * if the two keys are equal
+ */
+ private final int compare( K key1, K key2 )
+ {
+ if ( key1 == key2 )
+ {
+ return 0;
+ }
+
+ if ( key1 == null )
+ {
+ return 1;
+ }
+
+ if ( key2 == null )
+ {
+ return -1;
+ }
+
+ return btree.getComparator().compare( key1, key2 );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getRevision()
+ {
+ return revision;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public K getKey( int pos )
+ {
+ if ( pos < nbElems )
+ {
+ return keys[pos];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * Sets the key at a give position
+ *
+ * @param pos The position in the keys array
+ * @param key the key to inject
+ */
+ /* No qualifier*/void setKey( int pos, K key )
+ {
+ keys[pos] = key;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getOffset()
+ {
+ return offset;
+ }
+
+
+ /**
+ * @param offset the offset to set
+ */
+ /* No qualifier */void setOffset( long offset )
+ {
+ this.offset = offset;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getLastOffset()
+ {
+ return lastOffset;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ /* No qualifier */void setLastOffset( long lastOffset )
+ {
+ this.lastOffset = lastOffset;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "r" ).append( revision );
+ sb.append( ", nbElems:" ).append( nbElems );
+
+ if ( offset > 0 )
+ {
+ sb.append( ", offset:" ).append( offset );
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public String dumpPage( String tabs )
+ {
+ return "";
+ }
+}
Added: directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractResult.java
URL: http://svn.apache.org/viewvc/directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractResult.java?rev=1527458&view=auto
==============================================================================
--- directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractResult.java (added)
+++ directory/mavibot/trunk/mavibot/src/main/java/org/apache/directory/mavibot/btree/memory/AbstractResult.java Mon Sep 30 06:32:25 2013
@@ -0,0 +1,108 @@
+/*
+ * 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.memory;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.mavibot.btree.Result;
+
+
+/**
+ * An abstract class to gather common elements of the Result classes
+ *
+ * @param <K> The type for the Key
+ * @param <V> The type for the stored value
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+/* No qualifier */abstract class AbstractResult<K, V> implements Result<Page<K, V>>
+{
+ /** The list of copied page reference */
+ private List<Page<K, V>> copiedPage;
+
+
+ /**
+ * The default constructor for AbstractResult.
+ *
+ */
+ /* No qualifier */AbstractResult()
+ {
+ copiedPage = new ArrayList<Page<K, V>>();
+ }
+
+
+ /**
+ * Creates an instance of AbstractResult with an initialized list of copied pages.
+ *
+ * @param copiedPages The list of copied pages to store in this result
+ */
+ /* No qualifier */AbstractResult( List<Page<K, V>> copiedPages )
+ {
+ this.copiedPage = copiedPages;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<Page<K, V>> getCopiedPages()
+ {
+ return copiedPage;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addCopiedPage( Page<K, V> page )
+ {
+ copiedPage.add( page );
+ }
+
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "\n copiedPage = <" );
+
+ boolean isFirst = true;
+
+ for ( Page<K, V> copiedPage : getCopiedPages() )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( ", " );
+ }
+
+ sb.append( copiedPage.getOffset() );
+ }
+
+ sb.append( ">" );
+
+ return sb.toString();
+ }
+}