Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4D2C41087C for ; Mon, 30 Sep 2013 06:34:01 +0000 (UTC) Received: (qmail 87513 invoked by uid 500); 30 Sep 2013 06:33:24 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 87457 invoked by uid 500); 30 Sep 2013 06:33:23 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 87414 invoked by uid 99); 30 Sep 2013 06:33:18 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Sep 2013 06:33:18 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 30 Sep 2013 06:33:15 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 8DD742388BA6; Mon, 30 Sep 2013 06:32:32 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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... Date: Mon, 30 Sep 2013 06:32:28 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130930063232.8DD742388BA6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 The type for the stored element (either a value or a page) + * @param The type of the BTree key + * @param The type of the BTree value + * + * @author Apache Directory Project + */ +public class ReferenceHolder implements ElementHolder +{ + /** The BTree */ + private BTree 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 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 btree, E element, long offset, long lastOffset ) + { + this.btree = btree; + this.offset = offset; + this.lastOffset = lastOffset; + this.reference = new SoftReference( element ); + } + + + /** + * {@inheritDoc} + * @throws IOException + * @throws EndOfFileExceededException + */ + @Override + public E getValue( BTree btree ) throws EndOfFileExceededException, IOException + { + E element = reference.get(); + + if ( element == null ) + { + // We have to fetch the element from disk, using the offset now + Page page = fetchElement( btree ); + reference = ( SoftReference ) new SoftReference>( 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 fetchElement( BTree btree ) throws EndOfFileExceededException, IOException + { + Page 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 The type for the Key + * @param The type for the stored value + + * @author Apache Directory Project + */ +/* No qualifier */class RemoveResult extends AbstractDeleteResult +{ + /** + * 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 modifiedPage, Tuple 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> copiedPages, Page modifiedPage, Tuple 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 Apache Directory Project + */ +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 Apache Directory Project + */ +public class RevisionNameComparator implements Comparator +{ + /** + * {@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 Apache Directory Project + */ +public class RevisionNameSerializer extends AbstractElementSerializer +{ + /** + * 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 The type for the Key + * @param The type for the stored value + * + * @author Apache Directory Project + */ +/* No qualifier */class SplitResult extends AbstractResult implements InsertResult +{ + /** The left child */ + protected Page leftPage; + + /** The right child */ + protected Page 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 leftPage, Page 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> copiedPages, K pivot, Page leftPage, Page rightPage ) + { + super( copiedPages ); + this.pivot = pivot; + this.leftPage = leftPage; + this.rightPage = rightPage; + } + + + /** + * @return the leftPage + */ + /* No qualifier */Page getLeftPage() + { + return leftPage; + } + + + /** + * @return the rightPage + */ + /* No qualifier */Page 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. + *

+ * 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. + *

+ * 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 Apache Directory Project + * + * @param The type for the Key + * @param The type for the stored value + */ +public class Transaction +{ + /** 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 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 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 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 The type for the Key + * @param The type for the stored value + * + * @author Apache Directory Project + */ +/* No qualifier */abstract class AbstractBorrowedFromSiblingResult extends AbstractDeleteResult implements + BorrowedFromSiblingResult +{ + /** The modified sibling reference */ + private Page 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 modifiedPage, Page modifiedSibling, + Tuple 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> copiedPages, Page modifiedPage, + Page modifiedSibling, + Tuple removedElement, SiblingPosition position ) + { + super( copiedPages, modifiedPage, removedElement ); + this.modifiedSibling = modifiedSibling; + this.position = position; + } + + + /** + * {@inheritDoc} + */ + public Page 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 The type for the Key + * @param The type for the stored value + * + * @author Apache Directory Project + */ +/* No qualifier */abstract class AbstractDeleteResult extends AbstractResult implements + DeleteResult +{ + /** The modified page reference */ + private Page modifiedPage; + + /** The removed element if the key was found in the tree*/ + private Tuple 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 modifiedPage, Tuple 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> copiedPages, Page modifiedPage, + Tuple removedElement ) + { + super( copiedPages ); + this.modifiedPage = modifiedPage; + this.removedElement = removedElement; + } + + + /** + * {@inheritDoc} + */ + public Page getModifiedPage() + { + return modifiedPage; + } + + + /** + * {@inheritDoc} + */ + public Tuple getRemovedElement() + { + return removedElement; + } + + + /** + * @param modifiedPage the modifiedPage to set + */ + /* No qualifier */void setModifiedPage( Page 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 The type for the Key + * @param The type for the stored value + * + * @author Apache Directory Project + */ +/* No qualifier */abstract class AbstractPage implements Page +{ + /** Parent B+Tree. */ + protected transient BTree 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 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 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 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 prevPage = parent.children[parentPos - 1].getValue( btree ); + Page 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. + *

+ * Assuming that the array is zero-indexed, the returned value will be :
+ * position = - ( position + 1) + *
+ * So for the following table of keys :
+ *

+     * +---+---+---+---+
+     * | b | d | f | h |
+     * +---+---+---+---+
+     *   0   1   2   3
+     * 
+ * looking for 'b' will return -1 (-(0+1)) and looking for 'f' will return -3 (-(2+1)).
+ * Computing the real position is just a matter to get -(position++). + *

+ * 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.
+ * For instance, looking for : + *

    + *
  • 'a' will return 0
  • + *
  • 'b' will return -1
  • + *
  • 'c' will return 1
  • + *
  • 'd' will return -2
  • + *
  • 'e' will return 2
  • + *
  • 'f' will return -3
  • + *
  • 'g' will return 3
  • + *
  • 'h' will return -4
  • + *
  • 'i' will return 4
  • + *
+ * + * + * @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 The type for the Key + * @param The type for the stored value + * + * @author Apache Directory Project + */ +/* No qualifier */abstract class AbstractResult implements Result> +{ + /** The list of copied page reference */ + private List> copiedPage; + + + /** + * The default constructor for AbstractResult. + * + */ + /* No qualifier */AbstractResult() + { + copiedPage = new ArrayList>(); + } + + + /** + * 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> copiedPages ) + { + this.copiedPage = copiedPages; + } + + + /** + * {@inheritDoc} + */ + public List> getCopiedPages() + { + return copiedPage; + } + + + /** + * {@inheritDoc} + */ + public void addCopiedPage( Page page ) + { + copiedPage.add( page ); + } + + + public String toString() + { + StringBuilder sb = new StringBuilder(); + + sb.append( "\n copiedPage = <" ); + + boolean isFirst = true; + + for ( Page copiedPage : getCopiedPages() ) + { + if ( isFirst ) + { + isFirst = false; + } + else + { + sb.append( ", " ); + } + + sb.append( copiedPage.getOffset() ); + } + + sb.append( ">" ); + + return sb.toString(); + } +}