You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sa...@apache.org on 2011/10/31 08:11:22 UTC
svn commit: r1195359 - in
/directory/apacheds/branches/apacheds-txns/core/src:
main/java/org/apache/directory/server/core/txn/
test/java/org/apache/directory/server/core/txn/
Author: saya
Date: Mon Oct 31 07:11:22 2011
New Revision: 1195359
URL: http://svn.apache.org/viewvc?rev=1195359&view=rev
Log:
a test for TxnIndexCursor and some formatting and documentation.
Added:
directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/
directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongComparator.java
directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongSerializer.java
directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/TxnIndexCursorTest.java
Modified:
directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java
directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java
directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java
directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java
Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java?rev=1195359&r1=1195358&r2=1195359&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java Mon Oct 31 07:11:22 2011
@@ -50,13 +50,14 @@ public class DefaultTxnLogManager<ID> im
/**
- * TODO : doco
- * @param logger
- * @param txnManager
+ * Inits the the txn log manager
+ *
+ * @param logger write ahead logger
+ * @param txnManager txn Manager
*/
public void init( Log logger, TxnManagerInternal<ID> txnManager )
{
- this.wal = logger;
+ wal = logger;
this.txnManager = txnManager;
}
Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java?rev=1195359&r1=1195358&r2=1195359&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java Mon Oct 31 07:11:22 2011
@@ -316,7 +316,7 @@ public class IndexCursorWrapper<ID> exte
if ( positioned == false )
{
- afterLast();
+ beforeFirst();
}
if (( movingNext == false ) || ( getIndex < 0 ) )
Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java?rev=1195359&r1=1195358&r2=1195359&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java Mon Oct 31 07:11:22 2011
@@ -19,6 +19,7 @@
*/
package org.apache.directory.server.core.txn;
+
import org.apache.directory.server.core.api.partition.index.AbstractIndexCursor;
import org.apache.directory.server.core.api.partition.index.IndexComparator;
import org.apache.directory.server.core.api.partition.index.IndexEntry;
@@ -31,74 +32,79 @@ import org.apache.directory.shared.ldap.
import java.util.Iterator;
import java.util.NavigableSet;
+
/**
+ * Provides a cursor over the index entries added by a transaction
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class TxnIndexCursor <ID> extends AbstractIndexCursor<Object, Entry, ID>
+public class TxnIndexCursor<ID> extends AbstractIndexCursor<Object, Entry, ID>
{
/** list of changed index entries */
- private NavigableSet<IndexEntry<Object,ID>> changedEntries;
-
+ private NavigableSet<IndexEntry<Object, ID>> changedEntries;
+
/** forward or reverse index */
private boolean forwardIndex;
-
+
/** whether cursor is explicitly positioned */
private boolean positioned;
-
+
/** whether the moving direction is next */
private boolean movingNext = true;
-
+
/** Iterator to move over the set */
- private Iterator<IndexEntry<Object,ID>> it;
-
+ private Iterator<IndexEntry<Object, ID>> it;
+
/** currently available value */
- private IndexEntry<Object,ID> availableValue;
-
+ private IndexEntry<Object, ID> availableValue;
+
/** unsupported operation message */
private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_722 );
-
+
/** true if the index is locked down for a key */
private boolean onlyKey;
-
+
+ /** True if past the only key */
+ private boolean pastOnlyKey;
+
/** Lock down key in case of forward index */
private Object onlyValueKey;
-
+
/** Lock down key in case of reverse index */
private ID onlyIDKey;
-
+
/** index entry comparator */
- private IndexComparator<Object,ID> comparator;
-
-
- public TxnIndexCursor( NavigableSet<IndexEntry<Object,ID>> changedEntries, boolean forwardIndex, Object onlyValueKey, ID onlyIDKey, IndexComparator<Object,ID> comparator )
+ private IndexComparator<Object, ID> comparator;
+
+
+ public TxnIndexCursor( NavigableSet<IndexEntry<Object, ID>> changedEntries, boolean forwardIndex,
+ Object onlyValueKey, ID onlyIDKey, IndexComparator<?, ID> comparator )
{
this.changedEntries = changedEntries;
this.forwardIndex = forwardIndex;
- this.comparator = comparator;
-
+ this.comparator = ( IndexComparator<Object, ID> ) comparator;
+
if ( onlyValueKey != null )
{
this.onlyValueKey = onlyValueKey;
onlyKey = true;
}
-
- if ( changedEntries.size() < 1 )
+
+ if ( changedEntries.size() < 1 )
{
- throw new IllegalArgumentException("TxnIndexCursor should not be constructed with no index changes");
+ throw new IllegalArgumentException( "TxnIndexCursor should not be constructed with no index changes" );
}
}
-
-
+
+
/**
* {@inheritDoc}
*/
public void after( IndexEntry<Object, ID> element ) throws Exception
{
- positioned = true;
availableValue = null;
- movingNext = true;
-
+
+ // If the cursor is locked down by a key, check if the key is equal to the only key we have.
if ( onlyKey )
{
if ( forwardIndex )
@@ -116,10 +122,18 @@ public class TxnIndexCursor <ID> extends
}
}
}
-
+
+ positioned = true;
+ movingNext = true;
+ pastOnlyKey = false;
+
+ /*
+ * If (key, null) is given as the element to position after, then skip all
+ * the index elements with the given key.
+ */
boolean skipKey = false;
-
- if ( forwardIndex )
+
+ if ( forwardIndex )
{
if ( element.getId() == null )
{
@@ -133,21 +147,25 @@ public class TxnIndexCursor <ID> extends
skipKey = true;
}
}
-
+
if ( skipKey )
- {
+ {
+ /*
+ * After this call, the iterator will be position on the first value for the given key if a value for the key exists. Otherwise it
+ * is positioned at the key past the given key.
+ */
it = changedEntries.tailSet( element, false ).iterator();
-
+
boolean useLastEntry = false;
- IndexEntry<Object,ID> indexEntry = null;
-
+ IndexEntry<Object, ID> indexEntry = null;
+
while ( it.hasNext() )
{
indexEntry = it.next();
-
+
if ( forwardIndex )
{
- if ( comparator.getValueComparator().compare( indexEntry.getValue(), element.getValue() ) != 0 )
+ if ( comparator.getValueComparator().compare( indexEntry.getValue(), element.getValue() ) != 0 )
{
useLastEntry = true;
break;
@@ -155,45 +173,47 @@ public class TxnIndexCursor <ID> extends
}
else
{
- if ( comparator.getIDComparator().compare( indexEntry.getId(), element.getId() ) != 0 )
+ if ( comparator.getIDComparator().compare( indexEntry.getId(), element.getId() ) != 0 )
{
useLastEntry = true;
break;
}
}
}
-
+
if ( useLastEntry )
{
+ // Position the iterator on the first element past the given key.
it = changedEntries.tailSet( indexEntry, true ).iterator();
}
else
{
+ // There is no more elements after the given key, change the iterator direction
movingNext = false;
it = changedEntries.descendingIterator();
}
}
else
{
+ // Simply position the iterator past the given element.
it = changedEntries.tailSet( element, false ).iterator();
}
}
-
-
+
+
/**
* {@inheritDoc}
*/
public void before( IndexEntry<Object, ID> element ) throws Exception
{
- positioned = true;
availableValue = null;
- movingNext = true;
-
+
+ // If the cursor is locked down by a key, check if the key is equal to the only key we have.
if ( onlyKey )
{
if ( forwardIndex )
{
- if ( comparator.getValueComparator().compare(element.getValue(), onlyValueKey ) != 0 )
+ if ( comparator.getValueComparator().compare( element.getValue(), onlyValueKey ) != 0 )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
}
@@ -206,17 +226,26 @@ public class TxnIndexCursor <ID> extends
}
}
}
-
+
+ positioned = true;
+ movingNext = true;
+ pastOnlyKey = false;
+
+ /*
+ * Position the iterator on the given element. A call to next will return this element if it exists. If
+ * (key,null) is supplied as the element, then this will position the iterator on the first value for the
+ * given key if any value for the given key exists.
+ */
it = changedEntries.tailSet( element, true ).iterator();
}
-
-
+
+
/**
* {@inheritDoc}
*/
public void afterValue( ID id, Object value ) throws Exception
{
- ForwardIndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
+ ForwardIndexEntry<Object, ID> indexEntry = new ForwardIndexEntry<Object, ID>();
indexEntry.setId( id );
indexEntry.setValue( value );
after( indexEntry );
@@ -228,13 +257,13 @@ public class TxnIndexCursor <ID> extends
*/
public void beforeValue( ID id, Object value ) throws Exception
{
- ForwardIndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
+ ForwardIndexEntry<Object, ID> indexEntry = new ForwardIndexEntry<Object, ID>();
indexEntry.setId( id );
indexEntry.setValue( value );
before( indexEntry );
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -243,11 +272,13 @@ public class TxnIndexCursor <ID> extends
positioned = true;
availableValue = null;
movingNext = true;
-
+ pastOnlyKey = false;
+
if ( onlyKey )
{
- ForwardIndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
-
+ // If locked down by a key, position the iterator on the first value for the given key.
+ ForwardIndexEntry<Object, ID> indexEntry = new ForwardIndexEntry<Object, ID>();
+
if ( forwardIndex )
{
indexEntry.setValue( onlyValueKey );
@@ -256,7 +287,7 @@ public class TxnIndexCursor <ID> extends
{
indexEntry.setId( onlyIDKey );
}
-
+
it = changedEntries.tailSet( indexEntry, false ).iterator();
}
else
@@ -274,11 +305,17 @@ public class TxnIndexCursor <ID> extends
positioned = true;
availableValue = null;
movingNext = false;
-
+ pastOnlyKey = false;
+
if ( onlyKey )
{
- IndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
-
+
+ /*
+ * If we are locked down by only key, then position the iterator right past the key.
+ */
+
+ IndexEntry<Object, ID> indexEntry = new ForwardIndexEntry<Object, ID>();
+
if ( forwardIndex )
{
indexEntry.setValue( onlyValueKey );
@@ -287,19 +324,18 @@ public class TxnIndexCursor <ID> extends
{
indexEntry.setId( onlyIDKey );
}
-
+
it = changedEntries.tailSet( indexEntry, false ).iterator();
-
-
+
boolean useLastEntry = false;
-
+
while ( it.hasNext() )
{
indexEntry = it.next();
-
+
if ( forwardIndex )
{
- if ( comparator.getValueComparator().compare( indexEntry.getValue(), onlyValueKey ) != 0 )
+ if ( comparator.getValueComparator().compare( indexEntry.getValue(), onlyValueKey ) != 0 )
{
useLastEntry = true;
break;
@@ -307,14 +343,14 @@ public class TxnIndexCursor <ID> extends
}
else
{
- if ( comparator.getIDComparator().compare( indexEntry.getId(), onlyIDKey ) != 0 )
+ if ( comparator.getIDComparator().compare( indexEntry.getId(), onlyIDKey ) != 0 )
{
useLastEntry = true;
break;
}
}
}
-
+
if ( useLastEntry )
{
it = changedEntries.headSet( indexEntry, false ).descendingIterator();
@@ -329,7 +365,7 @@ public class TxnIndexCursor <ID> extends
it = changedEntries.descendingIterator();
}
}
-
+
/**
* {@inheritDoc}
@@ -337,10 +373,10 @@ public class TxnIndexCursor <ID> extends
public boolean first() throws Exception
{
beforeFirst();
-
+
return next();
}
-
+
/**
* {@inheritDoc}
@@ -348,11 +384,11 @@ public class TxnIndexCursor <ID> extends
public boolean last() throws Exception
{
afterLast();
-
+
return previous();
}
-
-
+
+
/**
* {@inheritDoc}
*/
@@ -362,7 +398,8 @@ public class TxnIndexCursor <ID> extends
{
afterLast();
}
-
+
+ // If currently moving in the next() direction, then get a descending iterator using the last availableValue
if ( movingNext == true )
{
if ( availableValue == null )
@@ -372,7 +409,7 @@ public class TxnIndexCursor <ID> extends
availableValue = it.next();
}
}
-
+
if ( availableValue == null )
{
it = changedEntries.descendingIterator();
@@ -381,23 +418,35 @@ public class TxnIndexCursor <ID> extends
{
it = changedEntries.headSet( availableValue, false ).descendingIterator();
}
-
+
availableValue = null;
movingNext = false;
+ pastOnlyKey = false;
+ }
+
+ if ( pastOnlyKey )
+ {
+ return false;
}
if ( it.hasNext() )
{
availableValue = it.next();
-
+
+ /*
+ * If only key and past the only key, do not make the available value null.
+ * Repeated calls the previous will not advance iterator either. If the user
+ * calls next after this point, the available value will be used to
+ * reverse the iterator.
+ */
if ( onlyKey )
{
if ( forwardIndex )
{
if ( comparator.getValueComparator().compare( availableValue.getValue(), onlyValueKey ) != 0 )
{
- availableValue = null;
-
+ pastOnlyKey = true;
+
return false;
}
}
@@ -405,23 +454,23 @@ public class TxnIndexCursor <ID> extends
{
if ( comparator.getIDComparator().compare( availableValue.getId(), onlyIDKey ) != 0 )
{
- availableValue = null;
-
+ pastOnlyKey = true;
+
return false;
}
}
}
-
+
return true;
}
else
{
availableValue = null;
-
+
return false;
}
}
-
+
/**
* {@inheritDoc}
@@ -430,9 +479,10 @@ public class TxnIndexCursor <ID> extends
{
if ( positioned == false )
{
- afterLast();
+ beforeFirst();
}
-
+
+ // If currently moving in the previous() direction, then get a increasing iterator using the last availableValue
if ( movingNext == false )
{
if ( availableValue == null )
@@ -442,33 +492,44 @@ public class TxnIndexCursor <ID> extends
availableValue = it.next();
}
}
-
+
if ( availableValue == null )
{
it = changedEntries.iterator();
}
else
{
- it = changedEntries.tailSet( availableValue, false ).descendingIterator();
+ it = changedEntries.tailSet( availableValue, false ).iterator();
}
-
+
availableValue = null;
movingNext = true;
+ pastOnlyKey = false;
+ }
+
+ if ( pastOnlyKey )
+ {
+ return false;
}
if ( it.hasNext() )
{
availableValue = it.next();
-
+ /*
+ * If only key and past the only key, do not make the available value null.
+ * Repeated calls the next will not advance iterator either. If the user
+ * calls previous after this point, the available value will be used to
+ * reverse the iterator.
+ */
if ( onlyKey )
{
if ( forwardIndex )
{
if ( comparator.getValueComparator().compare( availableValue.getValue(), onlyValueKey ) != 0 )
{
- availableValue = null;
-
+ pastOnlyKey = true;
+
return false;
}
}
@@ -476,38 +537,38 @@ public class TxnIndexCursor <ID> extends
{
if ( comparator.getIDComparator().compare( availableValue.getId(), onlyIDKey ) != 0 )
{
- availableValue = null;
-
+ pastOnlyKey = true;
+
return false;
}
}
}
-
+
return true;
}
else
{
availableValue = null;
-
+
return false;
}
}
-
-
+
+
/**
* {@inheritDoc}
*/
public IndexEntry<Object, ID> get() throws Exception
{
- if ( availableValue != null )
+ if ( availableValue != null && !pastOnlyKey )
{
return availableValue;
}
throw new InvalidCursorPositionException();
}
-
-
+
+
/**
* {@inheritDoc}
*/
Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java?rev=1195359&r1=1195358&r2=1195359&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java Mon Oct 31 07:11:22 2011
@@ -19,8 +19,15 @@
*/
package org.apache.directory.server.core.txn;
+
import java.util.Comparator;
import org.apache.directory.server.core.api.partition.index.Serializer;
+import org.apache.directory.server.core.log.DefaultLog;
+import org.apache.directory.server.core.log.Log;
+import org.apache.directory.server.core.log.InvalidLogException;
+
+import java.io.IOException;
+
/**
*
@@ -28,40 +35,73 @@ import org.apache.directory.server.core.
*/
public class TxnManagerFactory
{
+ /** The only txn manager */
private static TxnManagerInternal<?> txnManager;
-
+
+ /** The only txn log manager */
private static TxnLogManager<?> txnLogManager;
-
- public static <ID> void init(Comparator<ID> idComparator, Serializer idSerializer)
+
+ /** log suffix */
+ private static String LOG_SUFFIX = "log";
+
+
+ /**
+ *
+ * Initializes the txn managemenet layer. It creates the only instances of txn manager and txn log manager.
+ *
+ * @param idComparator comparator for the ID type.
+ * @param idSerializer seriazlier for the ID type.
+ * @param logFolderPath log folder path for the log manager.
+ * @param logBufferSize in memory buffer size for the log manager.
+ * @param logFileSize max targer log file size for the log manager.
+ * @throws IOException thrown if initialization fails.
+ */
+ @SuppressWarnings("unchecked")
+ public static <ID> void init( Comparator<ID> idComparator, Serializer idSerializer, String logFolderPath,
+ int logBufferSize, int logFileSize ) throws IOException
{
+ Log log = new DefaultLog();
+
+ try
+ {
+ log.init( logFolderPath, LOG_SUFFIX, logBufferSize, logFileSize );
+ }
+ catch ( InvalidLogException e )
+ {
+ throw new IOException( e );
+ }
+
DefaultTxnManager<ID> dTxnManager;
dTxnManager = new DefaultTxnManager<ID>();
txnManager = dTxnManager;
-
+
DefaultTxnLogManager<ID> dTxnLogManager;
dTxnLogManager = new DefaultTxnLogManager<ID>();
txnLogManager = dTxnLogManager;
-
- // TODO init txn manager and log manager
-
+ dTxnLogManager.init( log, ( TxnManagerInternal<ID> ) txnManager );
+
dTxnManager.init( dTxnLogManager, idComparator, idSerializer );
+
}
-
-
+
+
+ @SuppressWarnings("unchecked")
public static <ID> TxnManager<ID> txnManagerInstance()
{
- return ( (TxnManager<ID>) txnManager );
+ return ( ( TxnManager<ID> ) txnManager );
}
-
-
+
+
+ @SuppressWarnings("unchecked")
public static <ID> TxnLogManager<ID> txnLogManagerInstance()
{
- return ( (TxnLogManager<ID>) txnLogManager );
+ return ( ( TxnLogManager<ID> ) txnLogManager );
}
-
-
+
+
+ @SuppressWarnings("unchecked")
static <ID> TxnManagerInternal<ID> txnManagerInternalInstance()
{
- return ( (TxnManagerInternal<ID>) txnManager );
+ return ( ( TxnManagerInternal<ID> ) txnManager );
}
}
Added: directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongComparator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongComparator.java?rev=1195359&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongComparator.java (added)
+++ directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongComparator.java Mon Oct 31 07:11:22 2011
@@ -0,0 +1,38 @@
+
+/*
+ * 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.server.core.txn;
+
+
+import java.util.Comparator;
+
+
+public class LongComparator implements Comparator<Long>
+{
+ public static final LongComparator INSTANCE = new LongComparator();
+
+
+ public int compare( Long l1, Long l2 )
+ {
+ return ( l1 < l2 ? -1 : ( l1.equals( l2 ) ? 0 : 1 ) );
+ }
+
+}
Added: directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongSerializer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongSerializer.java?rev=1195359&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongSerializer.java (added)
+++ directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/LongSerializer.java Mon Oct 31 07:11:22 2011
@@ -0,0 +1,70 @@
+/*
+ * 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.server.core.txn;
+
+
+import java.io.IOException;
+import org.apache.directory.server.core.api.partition.index.Serializer;
+
+
+public class LongSerializer implements Serializer
+{
+ public static final LongSerializer INSTANCE = new LongSerializer();
+
+
+ public byte[] serialize( Object o ) throws IOException
+ {
+ long id = ( Long ) o;
+ byte[] bites = new byte[8];
+
+ bites[0] = ( byte ) ( id >> 56 );
+ bites[1] = ( byte ) ( id >> 48 );
+ bites[2] = ( byte ) ( id >> 40 );
+ bites[3] = ( byte ) ( id >> 32 );
+ bites[4] = ( byte ) ( id >> 24 );
+ bites[5] = ( byte ) ( id >> 16 );
+ bites[6] = ( byte ) ( id >> 8 );
+ bites[7] = ( byte ) id;
+
+ return bites;
+ }
+
+
+ public Object deserialize( byte[] bites ) throws IOException
+ {
+ long id;
+ id = bites[0] + ( ( bites[0] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[1] + ( ( bites[1] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[2] + ( ( bites[2] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[3] + ( ( bites[3] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[4] + ( ( bites[4] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[5] + ( ( bites[5] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[6] + ( ( bites[6] < 0 ) ? 256 : 0 );
+ id <<= 8;
+ id += bites[7] + ( ( bites[7] < 0 ) ? 256 : 0 );
+ return id;
+ }
+}
Added: directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/TxnIndexCursorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/TxnIndexCursorTest.java?rev=1195359&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/TxnIndexCursorTest.java (added)
+++ directory/apacheds/branches/apacheds-txns/core/src/test/java/org/apache/directory/server/core/txn/TxnIndexCursorTest.java Mon Oct 31 07:11:22 2011
@@ -0,0 +1,286 @@
+/*
+ * 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.server.core.txn;
+
+
+import java.util.TreeSet;
+
+import org.apache.directory.server.core.api.partition.index.IndexEntry;
+import org.apache.directory.server.core.api.partition.index.ForwardIndexEntry;
+import org.apache.directory.server.core.api.partition.index.ForwardIndexComparator;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class TxnIndexCursorTest
+{
+ /** index entry comparator */
+ ForwardIndexComparator<?, Long> comparator = new ForwardIndexComparator<Long, Long>( LongComparator.INSTANCE,
+ LongComparator.INSTANCE );
+
+ /** sorted change set for the cursor */
+ private TreeSet<IndexEntry<Object, Long>> changedSet;
+
+ /** Cursor */
+ TxnIndexCursor<Long> cursor;
+
+ /** Only Key Cursor */
+ TxnIndexCursor<Long> onlyKeyCursor;
+
+
+ @Before
+ public void setup()
+ {
+ ForwardIndexEntry<Object, Long> idxEntry;
+ changedSet = new TreeSet<IndexEntry<Object, Long>>( ( ForwardIndexComparator<Object, Long> ) comparator );
+
+ for ( int idx = 0; idx < 10; idx++ )
+ {
+ if ( idx != 5 )
+ {
+ idxEntry = new ForwardIndexEntry<Object, Long>();
+ idxEntry.setValue( new Long( idx ) );
+ idxEntry.setId( new Long( idx ) );
+ changedSet.add( idxEntry );
+ }
+
+ if ( idx != 5 && idx != 0 )
+ {
+ idxEntry = new ForwardIndexEntry<Object, Long>();
+ idxEntry.setValue( new Long( idx ) );
+ idxEntry.setId( new Long( idx + 1 ) );
+ changedSet.add( idxEntry );
+ }
+ }
+
+ cursor = new TxnIndexCursor<Long>( changedSet, true, null, null, comparator );
+
+ }
+
+
+ @After
+ public void teardown()
+ {
+ try
+ {
+ cursor.close();
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+
+ }
+
+
+ @Test
+ public void testAfter()
+ {
+ try
+ {
+ cursor.afterValue( new Long( 0 ), new Long( 0 ) );
+ assertTrue( cursor.next() );
+
+ IndexEntry<?, Long> next = cursor.get();
+ assertTrue( next.getValue().equals( new Long( 1 ) ) );
+ assertTrue( next.getId().equals( new Long( 1 ) ) );
+
+ cursor.afterValue( new Long( 5 ), new Long( 5 ) );
+ assertTrue( cursor.previous() );
+
+ IndexEntry<?, Long> prev = cursor.get();
+ assertTrue( prev.getValue().equals( new Long( 4 ) ) );
+ assertTrue( prev.getId().equals( new Long( 5 ) ) );
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void testBefore()
+ {
+ try
+ {
+ cursor.beforeValue( new Long( 0 ), new Long( 0 ) );
+ assertTrue( cursor.next() );
+
+ IndexEntry<?, Long> next = cursor.get();
+ assertTrue( next.getValue().equals( new Long( 0 ) ) );
+ assertTrue( next.getId().equals( new Long( 0 ) ) );
+
+ cursor.beforeValue( new Long( 5 ), new Long( 4 ) );
+ assertTrue( cursor.previous() );
+
+ IndexEntry<?, Long> prev = cursor.get();
+ assertTrue( prev.getValue().equals( new Long( 4 ) ) );
+ assertTrue( prev.getId().equals( new Long( 4 ) ) );
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void testAfterLast()
+ {
+ try
+ {
+ cursor.afterLast();
+ assertTrue( cursor.previous() );
+
+ IndexEntry<?, Long> prev = cursor.get();
+ assertTrue( prev.getValue().equals( new Long( 9 ) ) );
+ assertTrue( prev.getId().equals( new Long( 10 ) ) );
+
+ assertTrue( cursor.next() == false );
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void testBeforeFirst()
+ {
+ try
+ {
+ cursor.beforeFirst();
+ assertTrue( cursor.next() );
+
+ IndexEntry<?, Long> next = cursor.get();
+ assertTrue( next.getValue().equals( new Long( 0 ) ) );
+ assertTrue( next.getId().equals( new Long( 0 ) ) );
+
+ assertTrue( cursor.previous() == false );
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void testSkipKey()
+ {
+ try
+ {
+ cursor.afterValue( null, new Long( 4 ) );
+ assertTrue( cursor.next() );
+
+ IndexEntry<?, Long> next = cursor.get();
+ assertTrue( next.getValue().equals( new Long( 6 ) ) );
+ assertTrue( next.getId().equals( new Long( 6 ) ) );
+
+ cursor.beforeValue( null, new Long( 4 ) );
+ assertTrue( cursor.next() );
+
+ next = cursor.get();
+ assertTrue( next.getValue().equals( new Long( 4 ) ) );
+ assertTrue( next.getId().equals( new Long( 4 ) ) );
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void testLockDownByExistingKey()
+ {
+ onlyKeyCursor = new TxnIndexCursor<Long>( changedSet, true, new Long( 7 ), null, comparator );
+ try
+ {
+ onlyKeyCursor.beforeFirst();
+
+ assertTrue( onlyKeyCursor.next() );
+ IndexEntry<?, Long> next = onlyKeyCursor.get();
+ assertTrue( next.getValue().equals( new Long( 7 ) ) );
+ assertTrue( next.getId().equals( new Long( 7 ) ) );
+
+ assertTrue( onlyKeyCursor.next() );
+ next = onlyKeyCursor.get();
+ assertTrue( next.getValue().equals( new Long( 7 ) ) );
+ assertTrue( next.getId().equals( new Long( 8 ) ) );
+
+ assertTrue( onlyKeyCursor.next() == false );
+ assertTrue( onlyKeyCursor.previous() );
+ IndexEntry<?, Long> prev = onlyKeyCursor.get();
+ assertTrue( prev.getValue().equals( new Long( 7 ) ) );
+ assertTrue( prev.getId().equals( new Long( 8 ) ) );
+
+ assertTrue( onlyKeyCursor.previous() );
+ prev = onlyKeyCursor.get();
+ assertTrue( prev.getValue().equals( new Long( 7 ) ) );
+ assertTrue( prev.getId().equals( new Long( 7 ) ) );
+
+ assertTrue( onlyKeyCursor.previous() == false );
+ assertTrue( onlyKeyCursor.previous() == false );
+ assertTrue( onlyKeyCursor.next() == true );
+ next = onlyKeyCursor.get();
+ assertTrue( next.getValue().equals( new Long( 7 ) ) );
+ assertTrue( next.getId().equals( new Long( 7 ) ) );
+
+ onlyKeyCursor.afterValue( null, new Long( 7 ) );
+
+ assertTrue( onlyKeyCursor.next() == false );
+ assertTrue( onlyKeyCursor.previous() );
+ prev = onlyKeyCursor.get();
+ assertTrue( prev.getValue().equals( new Long( 7 ) ) );
+ assertTrue( prev.getId().equals( new Long( 8 ) ) );
+
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+
+
+ @Test
+ public void testLockDownByNonExistingKey()
+ {
+ onlyKeyCursor = new TxnIndexCursor<Long>( changedSet, true, new Long( 5 ), null, comparator );
+ try
+ {
+ onlyKeyCursor.beforeFirst();
+ assertTrue( onlyKeyCursor.next() == false );
+ assertTrue( onlyKeyCursor.previous() == false );
+
+ }
+ catch ( Exception e )
+ {
+ fail();
+ }
+ }
+}