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 2009/08/05 19:55:16 UTC
svn commit: r801340 [10/13] - in /directory/apacheds/trunk:
core-entry/src/main/java/org/apache/directory/server/core/entry/
core-entry/src/test/java/org/apache/directory/server/core/entry/
core-integ/src/main/java/org/apache/directory/server/core/inte...
Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java (original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java Wed Aug 5 17:55:15 2009
@@ -1,466 +1,466 @@
-/*
- * 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.partition.impl.btree.jdbm;
-
-
-import jdbm.btree.BTree;
-
-import org.apache.directory.server.core.avltree.ArrayTree;
-import org.apache.directory.server.core.avltree.ArrayTreeCursor;
-import org.apache.directory.server.xdbm.Tuple;
-import org.apache.directory.server.xdbm.AbstractTupleCursor;
-import org.apache.directory.shared.ldap.cursor.Cursor;
-import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/**
- * A Cursor over a BTree which manages duplicate keys.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$
- */
-class DupsCursor<K,V> extends AbstractTupleCursor<K,V>
-{
- private static final Logger LOG = LoggerFactory.getLogger( DupsCursor.class.getSimpleName() );
-
- /**
- * The JDBM backed table this Cursor traverses over.
- */
- private final JdbmTable<K,V> table;
-
- /**
- * An wrappedCursor Cursor which returns Tuples whose values are
- * DupsContainer objects representing either AvlTrees or BTreeRedirect
- * objects used to store the values of duplicate keys. It does not return
- * different values for the same key.
- */
- private final DupsContainerCursor<K,V> containerCursor;
-
- /**
- * The current Tuple returned from the wrappedCursor DupsContainerCursor.
- */
- private final Tuple<K,DupsContainer<V>> containerTuple = new Tuple<K, DupsContainer<V>>();
-
- /**
- * A Cursor over a set of value objects for the current key held in the
- * containerTuple. A new Cursor will be set for each new key as we
- * traverse. The Cursor traverses over either a AvlTree object full
- * of values in a multi-valued key or it traverses over a BTree which
- * contains the values in the key field of it's Tuples.
- */
- private Cursor<V> dupsCursor;
-
- /**
- * The Tuple that is used to return values via the get() method. This
- * same Tuple instance will be returned every time. At different
- * positions it may return different values for the same key.
- */
- private final Tuple<K,V> returnedTuple = new Tuple<K,V>();
-
- /**
- * Whether or not a value is available when get() is called.
- */
- private boolean valueAvailable;
-
-
- public DupsCursor( JdbmTable<K,V> table ) throws Exception
- {
- this.table = table;
- this.containerCursor = new DupsContainerCursor<K,V>( table );
- LOG.debug( "Created on table {}", table );
- }
-
-
- public boolean available()
- {
- return valueAvailable;
- }
-
-
- public void beforeKey( K key ) throws Exception
- {
- beforeValue( key, null );
- }
-
-
- public void beforeValue( K key, V value ) throws Exception
- {
- checkNotClosed( "beforeValue()" );
- containerCursor.before( new Tuple<K,DupsContainer<V>>( key, null ) );
-
- if ( containerCursor.next() )
- {
- containerTuple.setBoth( containerCursor.get() );
- DupsContainer<V> values = containerTuple.getValue();
-
- if ( values.isArrayTree() )
- {
- ArrayTree<V> set = values.getArrayTree();
- dupsCursor = new ArrayTreeCursor<V>( set );
- }
- else
- {
- BTree tree = table.getBTree( values.getBTreeRedirect() );
- dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
- }
-
- if ( value == null )
- {
- return;
- }
-
- // advance the dupsCursor only if we're on same key
- if ( table.getKeyComparator().compare( containerTuple.getKey(), key ) == 0 )
- {
- dupsCursor.before( value );
- }
-
- return;
- }
-
- clearValue();
- containerTuple.setKey( null );
- containerTuple.setValue( null );
- }
-
-
- public void afterKey( K key ) throws Exception
- {
- afterValue( key, null );
- }
-
-
- public void afterValue( K key, V value ) throws Exception
- {
- checkNotClosed( "afterValue()" );
- /*
- * There is a subtle difference between after and before handling
- * with duplicate key values. Say we have the following tuples:
- *
- * (0, 0)
- * (1, 1)
- * (1, 2)
- * (1, 3)
- * (2, 2)
- *
- * If we request an after cursor on (1, 2). We must make sure that
- * the container cursor does not advance after the entry with key 1
- * since this would result in us skip returning (1. 3) on the call to
- * next which will incorrectly return (2, 2) instead.
- *
- * So if the value is null in the element then we don't care about
- * this obviously since we just want to advance past the duplicate key
- * values all together. But when it is not null, then we want to
- * go right before this key instead of after it.
- */
-
- if ( value == null )
- {
- containerCursor.after( new Tuple<K,DupsContainer<V>>( key, null ) );
- }
- else
- {
- containerCursor.before( new Tuple<K,DupsContainer<V>>( key, null ) );
- }
-
- if ( containerCursor.next() )
- {
- containerTuple.setBoth( containerCursor.get() );
- DupsContainer<V> values = containerTuple.getValue();
-
- if ( values.isArrayTree() )
- {
- ArrayTree<V> set = values.getArrayTree();
- dupsCursor = new ArrayTreeCursor<V>( set );
- }
- else
- {
- BTree tree = table.getBTree( values.getBTreeRedirect() );
- dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
- }
-
- if ( value == null )
- {
- return;
- }
-
- // only advance the dupsCursor if we're on same key
- if ( table.getKeyComparator().compare( containerTuple.getKey(), key ) == 0 )
- {
- dupsCursor.after( value );
- }
-
- return;
- }
-
- clearValue();
- containerTuple.setKey( null );
- containerTuple.setValue( null );
- }
-
-
- public void before( Tuple<K,V> element ) throws Exception
- {
- beforeValue( element.getKey(), element.getValue() );
- }
-
-
- public void after( Tuple<K,V> element ) throws Exception
- {
- afterValue( element.getKey(), element.getValue() );
- }
-
-
- public void beforeFirst() throws Exception
- {
- checkNotClosed( "beforeFirst()" );
- clearValue();
- containerCursor.beforeFirst();
- containerTuple.setKey( null );
- containerTuple.setValue( null );
- dupsCursor = null;
- }
-
-
- public void afterLast() throws Exception
- {
- checkNotClosed( "afterLast()" );
- clearValue();
- containerCursor.afterLast();
- containerTuple.setKey( null );
- containerTuple.setValue( null );
- dupsCursor = null;
- }
-
-
- public boolean first() throws Exception
- {
- checkNotClosed( "first()" );
- clearValue();
- dupsCursor = null;
-
- if ( containerCursor.first() )
- {
- containerTuple.setBoth( containerCursor.get() );
- DupsContainer<V> values = containerTuple.getValue();
-
- if ( containerTuple.getValue().isArrayTree() )
- {
- dupsCursor = new ArrayTreeCursor<V>( values.getArrayTree() );
- }
- else
- {
- BTree bt = table.getBTree( values.getBTreeRedirect() );
- dupsCursor = new KeyBTreeCursor<V>( bt, table.getValueComparator() );
- }
-
- /*
- * Since only tables with duplicate keys enabled use this
- * cursor, entries must have at least one value, and therefore
- * call to last() will always return true.
- */
- dupsCursor.first();
- valueAvailable = true;
- returnedTuple.setKey( containerTuple.getKey() );
- returnedTuple.setValue( dupsCursor.get() );
- return true;
- }
-
- return false;
- }
-
-
- public boolean last() throws Exception
- {
- checkNotClosed( "last()" );
- clearValue();
- dupsCursor = null;
-
- if ( containerCursor.last() )
- {
- containerTuple.setBoth( containerCursor.get() );
- DupsContainer<V> values = containerTuple.getValue();
-
- if ( values.isArrayTree() )
- {
- ArrayTree<V> set = values.getArrayTree();
- dupsCursor = new ArrayTreeCursor<V>( set );
- }
- else
- {
- BTree tree = table.getBTree( values.getBTreeRedirect() );
- dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
- }
-
- /*
- * Since only tables with duplicate keys enabled use this
- * cursor, entries must have at least one value, and therefore
- * call to last() will always return true.
- */
- dupsCursor.last();
- valueAvailable = true;
- returnedTuple.setKey( containerTuple.getKey() );
- returnedTuple.setValue( dupsCursor.get() );
- return true;
- }
-
- return false;
- }
-
-
-
- private void clearValue()
- {
- returnedTuple.setKey( null );
- returnedTuple.setValue( null );
- valueAvailable = false;
- }
-
-
- public boolean previous() throws Exception
- {
- checkNotClosed( "previous()" );
- /*
- * If the iterator over the values of the current key is null or is
- * extinguished then we need to advance to the previous key.
- */
- if ( null == dupsCursor || ! dupsCursor.previous() )
- {
- /*
- * If the wrappedCursor cursor has more elements we get the previous
- * key/AvlTree Tuple to work with and get a cursor over it's
- * values.
- */
- if ( containerCursor.previous() )
- {
- containerTuple.setBoth( containerCursor.get() );
- DupsContainer<V> values = containerTuple.getValue();
-
- if ( values.isArrayTree() )
- {
- ArrayTree<V> set = values.getArrayTree();
- dupsCursor = new ArrayTreeCursor<V>( set );
- }
- else
- {
- BTree tree = table.getBTree( values.getBTreeRedirect() );
- dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
- }
-
- /*
- * Since only tables with duplicate keys enabled use this
- * cursor, entries must have at least one value, and therefore
- * call to previous() after bringing the cursor to afterLast()
- * will always return true.
- */
- dupsCursor.afterLast();
- dupsCursor.previous();
- }
- else
- {
- dupsCursor = null;
- return false;
- }
- }
-
- returnedTuple.setKey( containerTuple.getKey() );
- returnedTuple.setValue( dupsCursor.get() );
- return valueAvailable = true;
- }
-
-
- public boolean next() throws Exception
- {
- checkNotClosed( "next()" );
- /*
- * If the iterator over the values of the current key is null or is
- * extinguished then we need to advance to the next key.
- */
- if ( null == dupsCursor || ! dupsCursor.next() )
- {
- /*
- * If the wrappedCursor cursor has more elements we get the next
- * key/AvlTree Tuple to work with and get a cursor over it.
- */
- if ( containerCursor.next() )
- {
- containerTuple.setBoth( containerCursor.get() );
- DupsContainer<V> values = containerTuple.getValue();
-
- if ( values.isArrayTree() )
- {
- ArrayTree<V> set = values.getArrayTree();
- dupsCursor = new ArrayTreeCursor<V>( set );
- }
- else
- {
- BTree tree = table.getBTree( values.getBTreeRedirect() );
- dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
- }
-
- /*
- * Since only tables with duplicate keys enabled use this
- * cursor, entries must have at least one value, and therefore
- * call to next() after bringing the cursor to beforeFirst()
- * will always return true.
- */
- dupsCursor.beforeFirst();
- dupsCursor.next();
- }
- else
- {
- dupsCursor = null;
- return false;
- }
- }
-
- /*
- * If we get to this point then cursor has more elements and
- * containerTuple holds the Tuple containing the key and the btree or
- * AvlTree of values for that key which the Cursor traverses. All we
- * need to do is populate our tuple object with the key and the value
- * in the cursor.
- */
- returnedTuple.setKey( containerTuple.getKey() );
- returnedTuple.setValue( dupsCursor.get() );
- return valueAvailable = true;
- }
-
-
- public Tuple<K,V> get() throws Exception
- {
- checkNotClosed( "get()" );
-
- if ( ! valueAvailable )
- {
- throw new InvalidCursorPositionException();
- }
-
- return returnedTuple;
- }
-
-
- public boolean isElementReused()
- {
- return true;
- }
-}
+/*
+ * 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.partition.impl.btree.jdbm;
+
+
+import jdbm.btree.BTree;
+
+import org.apache.directory.server.core.avltree.ArrayTree;
+import org.apache.directory.server.core.avltree.ArrayTreeCursor;
+import org.apache.directory.server.xdbm.Tuple;
+import org.apache.directory.server.xdbm.AbstractTupleCursor;
+import org.apache.directory.shared.ldap.cursor.Cursor;
+import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Cursor over a BTree which manages duplicate keys.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+class DupsCursor<K,V> extends AbstractTupleCursor<K,V>
+{
+ private static final Logger LOG = LoggerFactory.getLogger( DupsCursor.class.getSimpleName() );
+
+ /**
+ * The JDBM backed table this Cursor traverses over.
+ */
+ private final JdbmTable<K,V> table;
+
+ /**
+ * An wrappedCursor Cursor which returns Tuples whose values are
+ * DupsContainer objects representing either AvlTrees or BTreeRedirect
+ * objects used to store the values of duplicate keys. It does not return
+ * different values for the same key.
+ */
+ private final DupsContainerCursor<K,V> containerCursor;
+
+ /**
+ * The current Tuple returned from the wrappedCursor DupsContainerCursor.
+ */
+ private final Tuple<K,DupsContainer<V>> containerTuple = new Tuple<K, DupsContainer<V>>();
+
+ /**
+ * A Cursor over a set of value objects for the current key held in the
+ * containerTuple. A new Cursor will be set for each new key as we
+ * traverse. The Cursor traverses over either a AvlTree object full
+ * of values in a multi-valued key or it traverses over a BTree which
+ * contains the values in the key field of it's Tuples.
+ */
+ private Cursor<V> dupsCursor;
+
+ /**
+ * The Tuple that is used to return values via the get() method. This
+ * same Tuple instance will be returned every time. At different
+ * positions it may return different values for the same key.
+ */
+ private final Tuple<K,V> returnedTuple = new Tuple<K,V>();
+
+ /**
+ * Whether or not a value is available when get() is called.
+ */
+ private boolean valueAvailable;
+
+
+ public DupsCursor( JdbmTable<K,V> table ) throws Exception
+ {
+ this.table = table;
+ this.containerCursor = new DupsContainerCursor<K,V>( table );
+ LOG.debug( "Created on table {}", table );
+ }
+
+
+ public boolean available()
+ {
+ return valueAvailable;
+ }
+
+
+ public void beforeKey( K key ) throws Exception
+ {
+ beforeValue( key, null );
+ }
+
+
+ public void beforeValue( K key, V value ) throws Exception
+ {
+ checkNotClosed( "beforeValue()" );
+ containerCursor.before( new Tuple<K,DupsContainer<V>>( key, null ) );
+
+ if ( containerCursor.next() )
+ {
+ containerTuple.setBoth( containerCursor.get() );
+ DupsContainer<V> values = containerTuple.getValue();
+
+ if ( values.isArrayTree() )
+ {
+ ArrayTree<V> set = values.getArrayTree();
+ dupsCursor = new ArrayTreeCursor<V>( set );
+ }
+ else
+ {
+ BTree tree = table.getBTree( values.getBTreeRedirect() );
+ dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
+ }
+
+ if ( value == null )
+ {
+ return;
+ }
+
+ // advance the dupsCursor only if we're on same key
+ if ( table.getKeyComparator().compare( containerTuple.getKey(), key ) == 0 )
+ {
+ dupsCursor.before( value );
+ }
+
+ return;
+ }
+
+ clearValue();
+ containerTuple.setKey( null );
+ containerTuple.setValue( null );
+ }
+
+
+ public void afterKey( K key ) throws Exception
+ {
+ afterValue( key, null );
+ }
+
+
+ public void afterValue( K key, V value ) throws Exception
+ {
+ checkNotClosed( "afterValue()" );
+ /*
+ * There is a subtle difference between after and before handling
+ * with duplicate key values. Say we have the following tuples:
+ *
+ * (0, 0)
+ * (1, 1)
+ * (1, 2)
+ * (1, 3)
+ * (2, 2)
+ *
+ * If we request an after cursor on (1, 2). We must make sure that
+ * the container cursor does not advance after the entry with key 1
+ * since this would result in us skip returning (1. 3) on the call to
+ * next which will incorrectly return (2, 2) instead.
+ *
+ * So if the value is null in the element then we don't care about
+ * this obviously since we just want to advance past the duplicate key
+ * values all together. But when it is not null, then we want to
+ * go right before this key instead of after it.
+ */
+
+ if ( value == null )
+ {
+ containerCursor.after( new Tuple<K,DupsContainer<V>>( key, null ) );
+ }
+ else
+ {
+ containerCursor.before( new Tuple<K,DupsContainer<V>>( key, null ) );
+ }
+
+ if ( containerCursor.next() )
+ {
+ containerTuple.setBoth( containerCursor.get() );
+ DupsContainer<V> values = containerTuple.getValue();
+
+ if ( values.isArrayTree() )
+ {
+ ArrayTree<V> set = values.getArrayTree();
+ dupsCursor = new ArrayTreeCursor<V>( set );
+ }
+ else
+ {
+ BTree tree = table.getBTree( values.getBTreeRedirect() );
+ dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
+ }
+
+ if ( value == null )
+ {
+ return;
+ }
+
+ // only advance the dupsCursor if we're on same key
+ if ( table.getKeyComparator().compare( containerTuple.getKey(), key ) == 0 )
+ {
+ dupsCursor.after( value );
+ }
+
+ return;
+ }
+
+ clearValue();
+ containerTuple.setKey( null );
+ containerTuple.setValue( null );
+ }
+
+
+ public void before( Tuple<K,V> element ) throws Exception
+ {
+ beforeValue( element.getKey(), element.getValue() );
+ }
+
+
+ public void after( Tuple<K,V> element ) throws Exception
+ {
+ afterValue( element.getKey(), element.getValue() );
+ }
+
+
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ clearValue();
+ containerCursor.beforeFirst();
+ containerTuple.setKey( null );
+ containerTuple.setValue( null );
+ dupsCursor = null;
+ }
+
+
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+ clearValue();
+ containerCursor.afterLast();
+ containerTuple.setKey( null );
+ containerTuple.setValue( null );
+ dupsCursor = null;
+ }
+
+
+ public boolean first() throws Exception
+ {
+ checkNotClosed( "first()" );
+ clearValue();
+ dupsCursor = null;
+
+ if ( containerCursor.first() )
+ {
+ containerTuple.setBoth( containerCursor.get() );
+ DupsContainer<V> values = containerTuple.getValue();
+
+ if ( containerTuple.getValue().isArrayTree() )
+ {
+ dupsCursor = new ArrayTreeCursor<V>( values.getArrayTree() );
+ }
+ else
+ {
+ BTree bt = table.getBTree( values.getBTreeRedirect() );
+ dupsCursor = new KeyBTreeCursor<V>( bt, table.getValueComparator() );
+ }
+
+ /*
+ * Since only tables with duplicate keys enabled use this
+ * cursor, entries must have at least one value, and therefore
+ * call to last() will always return true.
+ */
+ dupsCursor.first();
+ valueAvailable = true;
+ returnedTuple.setKey( containerTuple.getKey() );
+ returnedTuple.setValue( dupsCursor.get() );
+ return true;
+ }
+
+ return false;
+ }
+
+
+ public boolean last() throws Exception
+ {
+ checkNotClosed( "last()" );
+ clearValue();
+ dupsCursor = null;
+
+ if ( containerCursor.last() )
+ {
+ containerTuple.setBoth( containerCursor.get() );
+ DupsContainer<V> values = containerTuple.getValue();
+
+ if ( values.isArrayTree() )
+ {
+ ArrayTree<V> set = values.getArrayTree();
+ dupsCursor = new ArrayTreeCursor<V>( set );
+ }
+ else
+ {
+ BTree tree = table.getBTree( values.getBTreeRedirect() );
+ dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
+ }
+
+ /*
+ * Since only tables with duplicate keys enabled use this
+ * cursor, entries must have at least one value, and therefore
+ * call to last() will always return true.
+ */
+ dupsCursor.last();
+ valueAvailable = true;
+ returnedTuple.setKey( containerTuple.getKey() );
+ returnedTuple.setValue( dupsCursor.get() );
+ return true;
+ }
+
+ return false;
+ }
+
+
+
+ private void clearValue()
+ {
+ returnedTuple.setKey( null );
+ returnedTuple.setValue( null );
+ valueAvailable = false;
+ }
+
+
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "previous()" );
+ /*
+ * If the iterator over the values of the current key is null or is
+ * extinguished then we need to advance to the previous key.
+ */
+ if ( null == dupsCursor || ! dupsCursor.previous() )
+ {
+ /*
+ * If the wrappedCursor cursor has more elements we get the previous
+ * key/AvlTree Tuple to work with and get a cursor over it's
+ * values.
+ */
+ if ( containerCursor.previous() )
+ {
+ containerTuple.setBoth( containerCursor.get() );
+ DupsContainer<V> values = containerTuple.getValue();
+
+ if ( values.isArrayTree() )
+ {
+ ArrayTree<V> set = values.getArrayTree();
+ dupsCursor = new ArrayTreeCursor<V>( set );
+ }
+ else
+ {
+ BTree tree = table.getBTree( values.getBTreeRedirect() );
+ dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
+ }
+
+ /*
+ * Since only tables with duplicate keys enabled use this
+ * cursor, entries must have at least one value, and therefore
+ * call to previous() after bringing the cursor to afterLast()
+ * will always return true.
+ */
+ dupsCursor.afterLast();
+ dupsCursor.previous();
+ }
+ else
+ {
+ dupsCursor = null;
+ return false;
+ }
+ }
+
+ returnedTuple.setKey( containerTuple.getKey() );
+ returnedTuple.setValue( dupsCursor.get() );
+ return valueAvailable = true;
+ }
+
+
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "next()" );
+ /*
+ * If the iterator over the values of the current key is null or is
+ * extinguished then we need to advance to the next key.
+ */
+ if ( null == dupsCursor || ! dupsCursor.next() )
+ {
+ /*
+ * If the wrappedCursor cursor has more elements we get the next
+ * key/AvlTree Tuple to work with and get a cursor over it.
+ */
+ if ( containerCursor.next() )
+ {
+ containerTuple.setBoth( containerCursor.get() );
+ DupsContainer<V> values = containerTuple.getValue();
+
+ if ( values.isArrayTree() )
+ {
+ ArrayTree<V> set = values.getArrayTree();
+ dupsCursor = new ArrayTreeCursor<V>( set );
+ }
+ else
+ {
+ BTree tree = table.getBTree( values.getBTreeRedirect() );
+ dupsCursor = new KeyBTreeCursor<V>( tree, table.getValueComparator() );
+ }
+
+ /*
+ * Since only tables with duplicate keys enabled use this
+ * cursor, entries must have at least one value, and therefore
+ * call to next() after bringing the cursor to beforeFirst()
+ * will always return true.
+ */
+ dupsCursor.beforeFirst();
+ dupsCursor.next();
+ }
+ else
+ {
+ dupsCursor = null;
+ return false;
+ }
+ }
+
+ /*
+ * If we get to this point then cursor has more elements and
+ * containerTuple holds the Tuple containing the key and the btree or
+ * AvlTree of values for that key which the Cursor traverses. All we
+ * need to do is populate our tuple object with the key and the value
+ * in the cursor.
+ */
+ returnedTuple.setKey( containerTuple.getKey() );
+ returnedTuple.setValue( dupsCursor.get() );
+ return valueAvailable = true;
+ }
+
+
+ public Tuple<K,V> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+
+ if ( ! valueAvailable )
+ {
+ throw new InvalidCursorPositionException();
+ }
+
+ return returnedTuple;
+ }
+
+
+ public boolean isElementReused()
+ {
+ return true;
+ }
+}
Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java (original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java Wed Aug 5 17:55:15 2009
@@ -1,212 +1,212 @@
-/*
- * 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.partition.impl.btree.jdbm;
-
-
-import jdbm.btree.BTree;
-import jdbm.helper.Tuple;
-import jdbm.helper.TupleBrowser;
-
-import java.util.Comparator;
-
-import org.apache.directory.shared.ldap.cursor.AbstractCursor;
-import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
-
-
-/**
- * Cursor over the keys of a JDBM BTree. Obviously does not return duplicate
- * keys since JDBM does not natively support multiple values for the same key.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class KeyBTreeCursor<E> extends AbstractCursor<E>
-{
- private final Tuple tuple = new Tuple();
-
- private final BTree btree;
- private final Comparator<E> comparator;
- private boolean valueAvailable;
- private TupleBrowser browser;
-
-
- /**
- * Creates a Cursor over the keys of a JDBM BTree.
- *
- * @param btree the JDBM BTree to build a Cursor over
- * @param comparator the Comparator used to determine key ordering
- * @throws Exception of there are problems accessing the BTree
- */
- public KeyBTreeCursor( BTree btree, Comparator<E> comparator ) throws Exception
- {
- this.btree = btree;
- this.comparator = comparator;
- }
-
-
- private void clearValue()
- {
- tuple.setKey( null );
- tuple.setValue( null );
- valueAvailable = false;
- }
-
-
- public boolean available()
- {
- return valueAvailable;
- }
-
-
- public void before( E element ) throws Exception
- {
- checkNotClosed( "before()" );
- browser = btree.browse( element );
- clearValue();
- }
-
-
- @SuppressWarnings("unchecked")
- public void after( E element ) throws Exception
- {
- browser = btree.browse( element );
-
- /*
- * While the next value is less than or equal to the element keep
- * advancing forward to the next item. If we cannot advance any
- * further then stop and return. If we find a value greater than
- * the element then we stop, backup, and return so subsequent calls
- * to getNext() will return a value greater than the element.
- */
- while ( browser.getNext( tuple ) )
- {
- checkNotClosed( "after()" );
- E next = ( E ) tuple.getKey();
- int nextCompared = comparator.compare( next, element );
-
- if ( nextCompared <= 0 )
- {
- // just continue
- }
- else
- {
- /*
- * If we just have values greater than the element argument
- * then we are before the first element and must backup to
- * before the first element state for the JDBM browser which
- * apparently the browser supports.
- */
- browser.getPrevious( tuple );
- clearValue();
- return;
- }
- }
-
- clearValue();
- // just return
- }
-
-
- public void beforeFirst() throws Exception
- {
- checkNotClosed( "beforeFirst()" );
- browser = btree.browse();
- clearValue();
- }
-
-
- public void afterLast() throws Exception
- {
- checkNotClosed( "afterLast()" );
- browser = btree.browse( null );
- }
-
-
- public boolean first() throws Exception
- {
- beforeFirst();
- return next();
- }
-
-
- public boolean last() throws Exception
- {
- afterLast();
- return previous();
- }
-
-
- public boolean previous() throws Exception
- {
- checkNotClosed( "previous()" );
- if ( browser == null )
- {
- browser = btree.browse( null );
- }
-
- if ( browser.getPrevious( tuple ) )
- {
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- public boolean next() throws Exception
- {
- checkNotClosed( "next()" );
- if ( browser == null )
- {
- browser = btree.browse();
- }
-
- if ( browser.getNext( tuple ) )
- {
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- @SuppressWarnings("unchecked")
- public E get() throws Exception
- {
- checkNotClosed( "get()" );
- if ( valueAvailable )
- {
- return ( E ) tuple.getKey();
- }
-
- throw new InvalidCursorPositionException();
- }
-
-
- public boolean isElementReused()
- {
- return false;
- }
-}
+/*
+ * 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.partition.impl.btree.jdbm;
+
+
+import jdbm.btree.BTree;
+import jdbm.helper.Tuple;
+import jdbm.helper.TupleBrowser;
+
+import java.util.Comparator;
+
+import org.apache.directory.shared.ldap.cursor.AbstractCursor;
+import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
+
+
+/**
+ * Cursor over the keys of a JDBM BTree. Obviously does not return duplicate
+ * keys since JDBM does not natively support multiple values for the same key.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KeyBTreeCursor<E> extends AbstractCursor<E>
+{
+ private final Tuple tuple = new Tuple();
+
+ private final BTree btree;
+ private final Comparator<E> comparator;
+ private boolean valueAvailable;
+ private TupleBrowser browser;
+
+
+ /**
+ * Creates a Cursor over the keys of a JDBM BTree.
+ *
+ * @param btree the JDBM BTree to build a Cursor over
+ * @param comparator the Comparator used to determine key ordering
+ * @throws Exception of there are problems accessing the BTree
+ */
+ public KeyBTreeCursor( BTree btree, Comparator<E> comparator ) throws Exception
+ {
+ this.btree = btree;
+ this.comparator = comparator;
+ }
+
+
+ private void clearValue()
+ {
+ tuple.setKey( null );
+ tuple.setValue( null );
+ valueAvailable = false;
+ }
+
+
+ public boolean available()
+ {
+ return valueAvailable;
+ }
+
+
+ public void before( E element ) throws Exception
+ {
+ checkNotClosed( "before()" );
+ browser = btree.browse( element );
+ clearValue();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public void after( E element ) throws Exception
+ {
+ browser = btree.browse( element );
+
+ /*
+ * While the next value is less than or equal to the element keep
+ * advancing forward to the next item. If we cannot advance any
+ * further then stop and return. If we find a value greater than
+ * the element then we stop, backup, and return so subsequent calls
+ * to getNext() will return a value greater than the element.
+ */
+ while ( browser.getNext( tuple ) )
+ {
+ checkNotClosed( "after()" );
+ E next = ( E ) tuple.getKey();
+ int nextCompared = comparator.compare( next, element );
+
+ if ( nextCompared <= 0 )
+ {
+ // just continue
+ }
+ else
+ {
+ /*
+ * If we just have values greater than the element argument
+ * then we are before the first element and must backup to
+ * before the first element state for the JDBM browser which
+ * apparently the browser supports.
+ */
+ browser.getPrevious( tuple );
+ clearValue();
+ return;
+ }
+ }
+
+ clearValue();
+ // just return
+ }
+
+
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ browser = btree.browse();
+ clearValue();
+ }
+
+
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+ browser = btree.browse( null );
+ }
+
+
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+ return next();
+ }
+
+
+ public boolean last() throws Exception
+ {
+ afterLast();
+ return previous();
+ }
+
+
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "previous()" );
+ if ( browser == null )
+ {
+ browser = btree.browse( null );
+ }
+
+ if ( browser.getPrevious( tuple ) )
+ {
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "next()" );
+ if ( browser == null )
+ {
+ browser = btree.browse();
+ }
+
+ if ( browser.getNext( tuple ) )
+ {
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public E get() throws Exception
+ {
+ checkNotClosed( "get()" );
+ if ( valueAvailable )
+ {
+ return ( E ) tuple.getKey();
+ }
+
+ throw new InvalidCursorPositionException();
+ }
+
+
+ public boolean isElementReused()
+ {
+ return false;
+ }
+}
Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleArrayCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleArrayCursor.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleArrayCursor.java (original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleArrayCursor.java Wed Aug 5 17:55:15 2009
@@ -1,215 +1,215 @@
-/*
- * 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.partition.impl.btree.jdbm;
-
-
-import org.apache.directory.server.xdbm.Tuple;
-import org.apache.directory.server.xdbm.AbstractTupleCursor;
-import org.apache.directory.server.core.avltree.ArrayTree;
-import org.apache.directory.server.core.avltree.ArrayTreeCursor;
-import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
-
-
-/**
- * Cursor over a set of values for the same key which are store in an in
- * memory ArrayTree. This Cursor is limited to the same key and it's tuples
- * will always return the same key.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class KeyTupleArrayCursor<K,V> extends AbstractTupleCursor<K,V>
-{
- private final ArrayTreeCursor<V> wrapped;
- private final K key;
-
- private Tuple<K,V> returnedTuple = new Tuple<K,V>();
- private boolean valueAvailable;
-
-
- /**
- * Creates a Cursor over the tuples of an ArrayTree.
- *
- * @param avlTree the ArrayTree to build a Tuple returning Cursor over
- * @param key the constant key for which values are returned
- */
- public KeyTupleArrayCursor( ArrayTree<V> arrayTree, K key )
- {
- this.key = key;
- this.wrapped = new ArrayTreeCursor<V>( arrayTree );
- }
-
-
- private void clearValue()
- {
- returnedTuple.setKey( key );
- returnedTuple.setValue( null );
- valueAvailable = false;
- }
-
-
- public boolean available()
- {
- return valueAvailable;
- }
-
-
- public void beforeKey( K key ) throws Exception
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
-
- public void afterKey( K key ) throws Exception
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
-
- public void beforeValue( K key, V value ) throws Exception
- {
- checkNotClosed( "beforeValue()" );
- if ( key != null && ! key.equals( this.key ) )
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
- wrapped.before( value );
- clearValue();
- }
-
-
- public void afterValue( K key, V value ) throws Exception
- {
- checkNotClosed( "afterValue()" );
- if ( key != null && ! key.equals( this.key ) )
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
- wrapped.after( value );
- clearValue();
- }
-
-
- /**
- * Positions this Cursor over the same keys before the value of the
- * supplied element Tuple. The supplied element Tuple's key is not
- * considered at all.
- *
- * @param element the valueTuple who's value is used to position this Cursor
- * @throws Exception if there are failures to position the Cursor
- */
- public void before( Tuple<K,V> element ) throws Exception
- {
- checkNotClosed( "before()" );
- wrapped.before( element.getValue() );
- clearValue();
- }
-
-
- public void after( Tuple<K,V> element ) throws Exception
- {
- checkNotClosed( "after()" );
- wrapped.after( element.getValue() );
- clearValue();
- }
-
-
- public void beforeFirst() throws Exception
- {
- checkNotClosed( "beforeFirst()" );
- wrapped.beforeFirst();
- clearValue();
- }
-
-
- public void afterLast() throws Exception
- {
- checkNotClosed( "afterLast()" );
- wrapped.afterLast();
- clearValue();
- }
-
-
- public boolean first() throws Exception
- {
- beforeFirst();
- return next();
- }
-
-
- public boolean last() throws Exception
- {
- afterLast();
- return previous();
- }
-
-
- public boolean previous() throws Exception
- {
- checkNotClosed( "previous()" );
- if ( wrapped.previous() )
- {
- returnedTuple.setKey( key );
- returnedTuple.setValue( wrapped.get() );
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- public boolean next() throws Exception
- {
- checkNotClosed( "next()" );
- if ( wrapped.next() )
- {
- returnedTuple.setKey( key );
- returnedTuple.setValue( wrapped.get() );
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- public Tuple<K,V> get() throws Exception
- {
- checkNotClosed( "get()" );
- if ( valueAvailable )
- {
- return returnedTuple;
- }
-
- throw new InvalidCursorPositionException();
- }
-
-
- public boolean isElementReused()
- {
- return true;
- }
-}
\ No newline at end of file
+/*
+ * 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.partition.impl.btree.jdbm;
+
+
+import org.apache.directory.server.xdbm.Tuple;
+import org.apache.directory.server.xdbm.AbstractTupleCursor;
+import org.apache.directory.server.core.avltree.ArrayTree;
+import org.apache.directory.server.core.avltree.ArrayTreeCursor;
+import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
+
+
+/**
+ * Cursor over a set of values for the same key which are store in an in
+ * memory ArrayTree. This Cursor is limited to the same key and it's tuples
+ * will always return the same key.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KeyTupleArrayCursor<K,V> extends AbstractTupleCursor<K,V>
+{
+ private final ArrayTreeCursor<V> wrapped;
+ private final K key;
+
+ private Tuple<K,V> returnedTuple = new Tuple<K,V>();
+ private boolean valueAvailable;
+
+
+ /**
+ * Creates a Cursor over the tuples of an ArrayTree.
+ *
+ * @param avlTree the ArrayTree to build a Tuple returning Cursor over
+ * @param key the constant key for which values are returned
+ */
+ public KeyTupleArrayCursor( ArrayTree<V> arrayTree, K key )
+ {
+ this.key = key;
+ this.wrapped = new ArrayTreeCursor<V>( arrayTree );
+ }
+
+
+ private void clearValue()
+ {
+ returnedTuple.setKey( key );
+ returnedTuple.setValue( null );
+ valueAvailable = false;
+ }
+
+
+ public boolean available()
+ {
+ return valueAvailable;
+ }
+
+
+ public void beforeKey( K key ) throws Exception
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+
+ public void afterKey( K key ) throws Exception
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+
+ public void beforeValue( K key, V value ) throws Exception
+ {
+ checkNotClosed( "beforeValue()" );
+ if ( key != null && ! key.equals( this.key ) )
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+ wrapped.before( value );
+ clearValue();
+ }
+
+
+ public void afterValue( K key, V value ) throws Exception
+ {
+ checkNotClosed( "afterValue()" );
+ if ( key != null && ! key.equals( this.key ) )
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+ wrapped.after( value );
+ clearValue();
+ }
+
+
+ /**
+ * Positions this Cursor over the same keys before the value of the
+ * supplied element Tuple. The supplied element Tuple's key is not
+ * considered at all.
+ *
+ * @param element the valueTuple who's value is used to position this Cursor
+ * @throws Exception if there are failures to position the Cursor
+ */
+ public void before( Tuple<K,V> element ) throws Exception
+ {
+ checkNotClosed( "before()" );
+ wrapped.before( element.getValue() );
+ clearValue();
+ }
+
+
+ public void after( Tuple<K,V> element ) throws Exception
+ {
+ checkNotClosed( "after()" );
+ wrapped.after( element.getValue() );
+ clearValue();
+ }
+
+
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ wrapped.beforeFirst();
+ clearValue();
+ }
+
+
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+ wrapped.afterLast();
+ clearValue();
+ }
+
+
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+ return next();
+ }
+
+
+ public boolean last() throws Exception
+ {
+ afterLast();
+ return previous();
+ }
+
+
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "previous()" );
+ if ( wrapped.previous() )
+ {
+ returnedTuple.setKey( key );
+ returnedTuple.setValue( wrapped.get() );
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "next()" );
+ if ( wrapped.next() )
+ {
+ returnedTuple.setKey( key );
+ returnedTuple.setValue( wrapped.get() );
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ public Tuple<K,V> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+ if ( valueAvailable )
+ {
+ return returnedTuple;
+ }
+
+ throw new InvalidCursorPositionException();
+ }
+
+
+ public boolean isElementReused()
+ {
+ return true;
+ }
+}
Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java (original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java Wed Aug 5 17:55:15 2009
@@ -1,277 +1,277 @@
-/*
- * 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.partition.impl.btree.jdbm;
-
-
-import org.apache.directory.server.xdbm.Tuple;
-import org.apache.directory.server.xdbm.AbstractTupleCursor;
-import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
-
-import java.util.Comparator;
-
-import jdbm.helper.TupleBrowser;
-import jdbm.btree.BTree;
-
-
-/**
- * Cursor over a set of values for the same key which are store in another
- * BTree. This Cursor is limited to the same key and it's tuples will always
- * return the same key.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-public class KeyTupleBTreeCursor<K,V> extends AbstractTupleCursor<K,V>
-{
- private final Comparator<V> comparator;
- private final BTree btree;
- private final K key;
-
- private jdbm.helper.Tuple valueTuple = new jdbm.helper.Tuple();
- private Tuple<K,V> returnedTuple = new Tuple<K,V>();
- private TupleBrowser browser;
- private boolean valueAvailable;
-
-
- /**
- * Creates a Cursor over the tuples of a JDBM BTree.
- *
- * @param btree the JDBM BTree to build a Cursor over
- * @param key the constant key for which values are returned
- * @param comparator the Comparator used to determine <b>key</b> ordering
- * @throws Exception of there are problems accessing the BTree
- */
- public KeyTupleBTreeCursor( BTree btree, K key, Comparator<V> comparator ) throws Exception
- {
- this.key = key;
- this.btree = btree;
- this.comparator = comparator;
- this.browser = btree.browse();
- }
-
-
- private void clearValue()
- {
- returnedTuple.setKey( key );
- returnedTuple.setValue( null );
- valueAvailable = false;
- }
-
-
- public boolean available()
- {
- return valueAvailable;
- }
-
-
- public void beforeKey( K key ) throws Exception
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
-
- public void afterKey( K key ) throws Exception
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
-
- public void beforeValue( K key, V value ) throws Exception
- {
- checkNotClosed( "beforeValue()" );
- if ( key != null && ! key.equals( this.key ) )
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
- browser = btree.browse( value );
- clearValue();
- }
-
-
- @SuppressWarnings("unchecked")
- public void afterValue( K key, V value ) throws Exception
- {
- if ( key != null && ! key.equals( this.key ) )
- {
- throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
- }
-
- browser = btree.browse( value );
-
- /*
- * While the next value is less than or equal to the element keep
- * advancing forward to the next item. If we cannot advance any
- * further then stop and return. If we find a value greater than
- * the element then we stop, backup, and return so subsequent calls
- * to getNext() will return a value greater than the element.
- */
- while ( browser.getNext( valueTuple ) )
- {
- checkNotClosed( "afterValue" );
-
- V next = ( V ) valueTuple.getKey();
-
- int nextCompared = comparator.compare( next, value );
-
- if ( nextCompared <= 0 )
- {
- // just continue
- }
- else if ( nextCompared > 0 )
- {
- /*
- * If we just have values greater than the element argument
- * then we are before the first element and cannot backup, and
- * the call below to getPrevious() will fail. In this special
- * case we just reset the Cursor's browser and return.
- */
- if ( browser.getPrevious( valueTuple ) )
- {
- }
- else
- {
- browser = btree.browse( this.key );
- }
-
- clearValue();
- return;
- }
- }
-
- clearValue();
- }
-
-
- /**
- * Positions this Cursor over the same keys before the value of the
- * supplied valueTuple. The supplied element Tuple's key is not considered at
- * all.
- *
- * @param element the valueTuple who's value is used to position this Cursor
- * @throws Exception if there are failures to position the Cursor
- */
- public void before( Tuple<K,V> element ) throws Exception
- {
- checkNotClosed( "before()" );
- browser = btree.browse( element.getValue() );
- clearValue();
- }
-
-
- public void after( Tuple<K,V> element ) throws Exception
- {
- afterValue( key, element.getValue() );
- }
-
-
- public void beforeFirst() throws Exception
- {
- checkNotClosed( "beforeFirst()" );
- browser = btree.browse();
- clearValue();
- }
-
-
- public void afterLast() throws Exception
- {
- checkNotClosed( "afterLast()" );
- browser = btree.browse( null );
- }
-
-
- public boolean first() throws Exception
- {
- beforeFirst();
- return next();
- }
-
-
- public boolean last() throws Exception
- {
- afterLast();
- return previous();
- }
-
-
- @SuppressWarnings("unchecked")
- public boolean previous() throws Exception
- {
- checkNotClosed( "previous()" );
- if ( browser.getPrevious( valueTuple ) )
- {
- // work around to fix direction change problem with jdbm browser
- if ( returnedTuple.getValue() != null &&
- comparator.compare( ( V ) valueTuple.getKey(), returnedTuple.getValue() ) == 0 )
- {
- browser.getPrevious( valueTuple ) ;
- }
- returnedTuple.setKey( key );
- returnedTuple.setValue( ( V ) valueTuple.getKey() );
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- @SuppressWarnings("unchecked")
- public boolean next() throws Exception
- {
- checkNotClosed( "next()" );
- if ( browser.getNext( valueTuple ) )
- {
- // work around to fix direction change problem with jdbm browser
- if ( returnedTuple.getValue() != null &&
- comparator.compare( ( V ) valueTuple.getKey(), returnedTuple.getValue() ) == 0 )
- {
- browser.getNext( valueTuple ) ;
- }
- returnedTuple.setKey( key );
- returnedTuple.setValue( ( V ) valueTuple.getKey() );
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- public Tuple<K,V> get() throws Exception
- {
- checkNotClosed( "get()" );
- if ( valueAvailable )
- {
- return returnedTuple;
- }
-
- throw new InvalidCursorPositionException();
- }
-
-
- public boolean isElementReused()
- {
- return true;
- }
-}
\ No newline at end of file
+/*
+ * 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.partition.impl.btree.jdbm;
+
+
+import org.apache.directory.server.xdbm.Tuple;
+import org.apache.directory.server.xdbm.AbstractTupleCursor;
+import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
+
+import java.util.Comparator;
+
+import jdbm.helper.TupleBrowser;
+import jdbm.btree.BTree;
+
+
+/**
+ * Cursor over a set of values for the same key which are store in another
+ * BTree. This Cursor is limited to the same key and it's tuples will always
+ * return the same key.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KeyTupleBTreeCursor<K,V> extends AbstractTupleCursor<K,V>
+{
+ private final Comparator<V> comparator;
+ private final BTree btree;
+ private final K key;
+
+ private jdbm.helper.Tuple valueTuple = new jdbm.helper.Tuple();
+ private Tuple<K,V> returnedTuple = new Tuple<K,V>();
+ private TupleBrowser browser;
+ private boolean valueAvailable;
+
+
+ /**
+ * Creates a Cursor over the tuples of a JDBM BTree.
+ *
+ * @param btree the JDBM BTree to build a Cursor over
+ * @param key the constant key for which values are returned
+ * @param comparator the Comparator used to determine <b>key</b> ordering
+ * @throws Exception of there are problems accessing the BTree
+ */
+ public KeyTupleBTreeCursor( BTree btree, K key, Comparator<V> comparator ) throws Exception
+ {
+ this.key = key;
+ this.btree = btree;
+ this.comparator = comparator;
+ this.browser = btree.browse();
+ }
+
+
+ private void clearValue()
+ {
+ returnedTuple.setKey( key );
+ returnedTuple.setValue( null );
+ valueAvailable = false;
+ }
+
+
+ public boolean available()
+ {
+ return valueAvailable;
+ }
+
+
+ public void beforeKey( K key ) throws Exception
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+
+ public void afterKey( K key ) throws Exception
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+
+ public void beforeValue( K key, V value ) throws Exception
+ {
+ checkNotClosed( "beforeValue()" );
+ if ( key != null && ! key.equals( this.key ) )
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+ browser = btree.browse( value );
+ clearValue();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public void afterValue( K key, V value ) throws Exception
+ {
+ if ( key != null && ! key.equals( this.key ) )
+ {
+ throw new UnsupportedOperationException( "This cursor locks down the key so keywise advances are not allowed." );
+ }
+
+ browser = btree.browse( value );
+
+ /*
+ * While the next value is less than or equal to the element keep
+ * advancing forward to the next item. If we cannot advance any
+ * further then stop and return. If we find a value greater than
+ * the element then we stop, backup, and return so subsequent calls
+ * to getNext() will return a value greater than the element.
+ */
+ while ( browser.getNext( valueTuple ) )
+ {
+ checkNotClosed( "afterValue" );
+
+ V next = ( V ) valueTuple.getKey();
+
+ int nextCompared = comparator.compare( next, value );
+
+ if ( nextCompared <= 0 )
+ {
+ // just continue
+ }
+ else if ( nextCompared > 0 )
+ {
+ /*
+ * If we just have values greater than the element argument
+ * then we are before the first element and cannot backup, and
+ * the call below to getPrevious() will fail. In this special
+ * case we just reset the Cursor's browser and return.
+ */
+ if ( browser.getPrevious( valueTuple ) )
+ {
+ }
+ else
+ {
+ browser = btree.browse( this.key );
+ }
+
+ clearValue();
+ return;
+ }
+ }
+
+ clearValue();
+ }
+
+
+ /**
+ * Positions this Cursor over the same keys before the value of the
+ * supplied valueTuple. The supplied element Tuple's key is not considered at
+ * all.
+ *
+ * @param element the valueTuple who's value is used to position this Cursor
+ * @throws Exception if there are failures to position the Cursor
+ */
+ public void before( Tuple<K,V> element ) throws Exception
+ {
+ checkNotClosed( "before()" );
+ browser = btree.browse( element.getValue() );
+ clearValue();
+ }
+
+
+ public void after( Tuple<K,V> element ) throws Exception
+ {
+ afterValue( key, element.getValue() );
+ }
+
+
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ browser = btree.browse();
+ clearValue();
+ }
+
+
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+ browser = btree.browse( null );
+ }
+
+
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+ return next();
+ }
+
+
+ public boolean last() throws Exception
+ {
+ afterLast();
+ return previous();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "previous()" );
+ if ( browser.getPrevious( valueTuple ) )
+ {
+ // work around to fix direction change problem with jdbm browser
+ if ( returnedTuple.getValue() != null &&
+ comparator.compare( ( V ) valueTuple.getKey(), returnedTuple.getValue() ) == 0 )
+ {
+ browser.getPrevious( valueTuple ) ;
+ }
+ returnedTuple.setKey( key );
+ returnedTuple.setValue( ( V ) valueTuple.getKey() );
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "next()" );
+ if ( browser.getNext( valueTuple ) )
+ {
+ // work around to fix direction change problem with jdbm browser
+ if ( returnedTuple.getValue() != null &&
+ comparator.compare( ( V ) valueTuple.getKey(), returnedTuple.getValue() ) == 0 )
+ {
+ browser.getNext( valueTuple ) ;
+ }
+ returnedTuple.setKey( key );
+ returnedTuple.setValue( ( V ) valueTuple.getKey() );
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ public Tuple<K,V> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+ if ( valueAvailable )
+ {
+ return returnedTuple;
+ }
+
+ throw new InvalidCursorPositionException();
+ }
+
+
+ public boolean isElementReused()
+ {
+ return true;
+ }
+}
Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java?rev=801340&r1=801339&r2=801340&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java (original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java Wed Aug 5 17:55:15 2009
@@ -1,257 +1,257 @@
-/*
- * 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.partition.impl.btree.jdbm;
-
-
-import org.apache.directory.server.xdbm.Tuple;
-import org.apache.directory.server.xdbm.AbstractTupleCursor;
-import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
-
-import java.io.IOException;
-
-import jdbm.helper.TupleBrowser;
-
-
-/**
- * Cursor over the Tuples of a JDBM BTree. Duplicate keys are not supported
- * by JDBM natively so you will not see duplicate keys. For this reason as
- * well before() and after() positioning only considers the key of the Tuple
- * arguments provided.
- *
- * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
- * @version $Rev$, $Date$
- */
-class NoDupsCursor<K,V> extends AbstractTupleCursor<K,V>
-{
- private final JdbmTable<K,V> table;
-
- private jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple();
- private Tuple<K,V> returnedTuple = new Tuple<K,V>();
- private TupleBrowser browser;
- private boolean valueAvailable;
-
-
- /**
- * Creates a Cursor over the tuples of a JDBM table.
- *
- * @param table the JDBM Table to build a Cursor over
- * @throws IOException of there are problems accessing the BTree
- */
- public NoDupsCursor( JdbmTable<K,V> table ) throws IOException
- {
- this.table = table;
- }
-
-
- private void clearValue()
- {
- returnedTuple.setKey( null );
- returnedTuple.setValue( null );
- jdbmTuple.setKey( null );
- jdbmTuple.setValue( null );
- valueAvailable = false;
- }
-
-
- public boolean available()
- {
- return valueAvailable;
- }
-
-
- public void beforeKey( K key ) throws Exception
- {
- checkNotClosed( "beforeKey()" );
- browser = table.getBTree().browse( key );
- clearValue();
- }
-
-
- @SuppressWarnings("unchecked")
- public void afterKey( K key ) throws Exception
- {
- browser = table.getBTree().browse( key );
-
- /*
- * While the next value is less than or equal to the element keep
- * advancing forward to the next item. If we cannot advance any
- * further then stop and return. If we find a value greater than
- * the element then we stop, backup, and return so subsequent calls
- * to getNext() will return a value greater than the element.
- */
- while ( browser.getNext( jdbmTuple ) )
- {
- checkNotClosed( "afterKey()" );
- K next = ( K ) jdbmTuple.getKey();
-
- int nextCompared = table.getKeyComparator().compare( next, key );
-
- if ( nextCompared > 0 )
- {
- browser.getPrevious( jdbmTuple );
- clearValue();
- return;
- }
- }
-
- clearValue();
- }
-
-
- public void beforeValue( K key, V value ) throws Exception
- {
- throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." );
- }
-
-
- public void afterValue( K key, V value ) throws Exception
- {
- throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." );
- }
-
-
- /**
- * Positions this Cursor before the key of the supplied tuple.
- *
- * @param element the tuple who's key is used to position this Cursor
- * @throws IOException if there are failures to position the Cursor
- */
- public void before( Tuple<K,V> element ) throws Exception
- {
- beforeKey( element.getKey() );
- }
-
-
- public void after( Tuple<K,V> element ) throws Exception
- {
- afterKey( element.getKey() );
- }
-
-
- public void beforeFirst() throws Exception
- {
- checkNotClosed( "beforeFirst()" );
- browser = table.getBTree().browse();
- clearValue();
- }
-
-
- public void afterLast() throws Exception
- {
- checkNotClosed( "afterLast()" );
- browser = table.getBTree().browse( null );
- clearValue();
- }
-
-
- public boolean first() throws Exception
- {
- beforeFirst();
- return next();
- }
-
-
- public boolean last() throws Exception
- {
- afterLast();
- return previous();
- }
-
-
- @SuppressWarnings("unchecked")
- public boolean previous() throws Exception
- {
- checkNotClosed( "previous()" );
- if ( browser == null )
- {
- afterLast();
- }
-
- if ( browser.getPrevious( jdbmTuple ) )
- {
- if( returnedTuple.getKey() != null )
- {
- if( table.getKeyComparator().compare(
- ( K) jdbmTuple.getKey(), ( K) returnedTuple.getKey() ) == 0 )
- {
- browser.getPrevious( jdbmTuple );
- }
- }
-
- returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
- returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- @SuppressWarnings("unchecked")
- public boolean next() throws Exception
- {
- checkNotClosed( "previous()" );
- if ( browser == null )
- {
- beforeFirst();
- }
-
- if ( browser.getNext( jdbmTuple ) )
- {
- if( returnedTuple.getKey() != null )
- {
- if( table.getKeyComparator().compare(
- ( K) jdbmTuple.getKey(), ( K) returnedTuple.getKey() ) == 0 )
- {
- browser.getNext( jdbmTuple );
- }
- }
-
- returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
- returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
- return valueAvailable = true;
- }
- else
- {
- clearValue();
- return false;
- }
- }
-
-
- public Tuple<K,V> get() throws Exception
- {
- checkNotClosed( "get()" );
- if ( valueAvailable )
- {
- return returnedTuple;
- }
-
- throw new InvalidCursorPositionException();
- }
-
-
- public boolean isElementReused()
- {
- return true;
- }
-}
+/*
+ * 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.partition.impl.btree.jdbm;
+
+
+import org.apache.directory.server.xdbm.Tuple;
+import org.apache.directory.server.xdbm.AbstractTupleCursor;
+import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
+
+import java.io.IOException;
+
+import jdbm.helper.TupleBrowser;
+
+
+/**
+ * Cursor over the Tuples of a JDBM BTree. Duplicate keys are not supported
+ * by JDBM natively so you will not see duplicate keys. For this reason as
+ * well before() and after() positioning only considers the key of the Tuple
+ * arguments provided.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+class NoDupsCursor<K,V> extends AbstractTupleCursor<K,V>
+{
+ private final JdbmTable<K,V> table;
+
+ private jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple();
+ private Tuple<K,V> returnedTuple = new Tuple<K,V>();
+ private TupleBrowser browser;
+ private boolean valueAvailable;
+
+
+ /**
+ * Creates a Cursor over the tuples of a JDBM table.
+ *
+ * @param table the JDBM Table to build a Cursor over
+ * @throws IOException of there are problems accessing the BTree
+ */
+ public NoDupsCursor( JdbmTable<K,V> table ) throws IOException
+ {
+ this.table = table;
+ }
+
+
+ private void clearValue()
+ {
+ returnedTuple.setKey( null );
+ returnedTuple.setValue( null );
+ jdbmTuple.setKey( null );
+ jdbmTuple.setValue( null );
+ valueAvailable = false;
+ }
+
+
+ public boolean available()
+ {
+ return valueAvailable;
+ }
+
+
+ public void beforeKey( K key ) throws Exception
+ {
+ checkNotClosed( "beforeKey()" );
+ browser = table.getBTree().browse( key );
+ clearValue();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public void afterKey( K key ) throws Exception
+ {
+ browser = table.getBTree().browse( key );
+
+ /*
+ * While the next value is less than or equal to the element keep
+ * advancing forward to the next item. If we cannot advance any
+ * further then stop and return. If we find a value greater than
+ * the element then we stop, backup, and return so subsequent calls
+ * to getNext() will return a value greater than the element.
+ */
+ while ( browser.getNext( jdbmTuple ) )
+ {
+ checkNotClosed( "afterKey()" );
+ K next = ( K ) jdbmTuple.getKey();
+
+ int nextCompared = table.getKeyComparator().compare( next, key );
+
+ if ( nextCompared > 0 )
+ {
+ browser.getPrevious( jdbmTuple );
+ clearValue();
+ return;
+ }
+ }
+
+ clearValue();
+ }
+
+
+ public void beforeValue( K key, V value ) throws Exception
+ {
+ throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." );
+ }
+
+
+ public void afterValue( K key, V value ) throws Exception
+ {
+ throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." );
+ }
+
+
+ /**
+ * Positions this Cursor before the key of the supplied tuple.
+ *
+ * @param element the tuple who's key is used to position this Cursor
+ * @throws IOException if there are failures to position the Cursor
+ */
+ public void before( Tuple<K,V> element ) throws Exception
+ {
+ beforeKey( element.getKey() );
+ }
+
+
+ public void after( Tuple<K,V> element ) throws Exception
+ {
+ afterKey( element.getKey() );
+ }
+
+
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ browser = table.getBTree().browse();
+ clearValue();
+ }
+
+
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+ browser = table.getBTree().browse( null );
+ clearValue();
+ }
+
+
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+ return next();
+ }
+
+
+ public boolean last() throws Exception
+ {
+ afterLast();
+ return previous();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "previous()" );
+ if ( browser == null )
+ {
+ afterLast();
+ }
+
+ if ( browser.getPrevious( jdbmTuple ) )
+ {
+ if( returnedTuple.getKey() != null )
+ {
+ if( table.getKeyComparator().compare(
+ ( K) jdbmTuple.getKey(), ( K) returnedTuple.getKey() ) == 0 )
+ {
+ browser.getPrevious( jdbmTuple );
+ }
+ }
+
+ returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
+ returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "previous()" );
+ if ( browser == null )
+ {
+ beforeFirst();
+ }
+
+ if ( browser.getNext( jdbmTuple ) )
+ {
+ if( returnedTuple.getKey() != null )
+ {
+ if( table.getKeyComparator().compare(
+ ( K) jdbmTuple.getKey(), ( K) returnedTuple.getKey() ) == 0 )
+ {
+ browser.getNext( jdbmTuple );
+ }
+ }
+
+ returnedTuple.setKey( ( K ) jdbmTuple.getKey() );
+ returnedTuple.setValue( ( V ) jdbmTuple.getValue() );
+ return valueAvailable = true;
+ }
+ else
+ {
+ clearValue();
+ return false;
+ }
+ }
+
+
+ public Tuple<K,V> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+ if ( valueAvailable )
+ {
+ return returnedTuple;
+ }
+
+ throw new InvalidCursorPositionException();
+ }
+
+
+ public boolean isElementReused()
+ {
+ return true;
+ }
+}