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 Apache Directory Project - * @version $Rev$ - */ -class DupsCursor extends AbstractTupleCursor -{ - private static final Logger LOG = LoggerFactory.getLogger( DupsCursor.class.getSimpleName() ); - - /** - * The JDBM backed table this Cursor traverses over. - */ - private final JdbmTable 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 containerCursor; - - /** - * The current Tuple returned from the wrappedCursor DupsContainerCursor. - */ - private final Tuple> containerTuple = new Tuple>(); - - /** - * 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 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 returnedTuple = new Tuple(); - - /** - * Whether or not a value is available when get() is called. - */ - private boolean valueAvailable; - - - public DupsCursor( JdbmTable table ) throws Exception - { - this.table = table; - this.containerCursor = new DupsContainerCursor( 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>( key, null ) ); - - if ( containerCursor.next() ) - { - containerTuple.setBoth( containerCursor.get() ); - DupsContainer values = containerTuple.getValue(); - - if ( values.isArrayTree() ) - { - ArrayTree set = values.getArrayTree(); - dupsCursor = new ArrayTreeCursor( set ); - } - else - { - BTree tree = table.getBTree( values.getBTreeRedirect() ); - dupsCursor = new KeyBTreeCursor( 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>( key, null ) ); - } - else - { - containerCursor.before( new Tuple>( key, null ) ); - } - - if ( containerCursor.next() ) - { - containerTuple.setBoth( containerCursor.get() ); - DupsContainer values = containerTuple.getValue(); - - if ( values.isArrayTree() ) - { - ArrayTree set = values.getArrayTree(); - dupsCursor = new ArrayTreeCursor( set ); - } - else - { - BTree tree = table.getBTree( values.getBTreeRedirect() ); - dupsCursor = new KeyBTreeCursor( 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 element ) throws Exception - { - beforeValue( element.getKey(), element.getValue() ); - } - - - public void after( Tuple 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 values = containerTuple.getValue(); - - if ( containerTuple.getValue().isArrayTree() ) - { - dupsCursor = new ArrayTreeCursor( values.getArrayTree() ); - } - else - { - BTree bt = table.getBTree( values.getBTreeRedirect() ); - dupsCursor = new KeyBTreeCursor( 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 values = containerTuple.getValue(); - - if ( values.isArrayTree() ) - { - ArrayTree set = values.getArrayTree(); - dupsCursor = new ArrayTreeCursor( set ); - } - else - { - BTree tree = table.getBTree( values.getBTreeRedirect() ); - dupsCursor = new KeyBTreeCursor( 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 values = containerTuple.getValue(); - - if ( values.isArrayTree() ) - { - ArrayTree set = values.getArrayTree(); - dupsCursor = new ArrayTreeCursor( set ); - } - else - { - BTree tree = table.getBTree( values.getBTreeRedirect() ); - dupsCursor = new KeyBTreeCursor( 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 values = containerTuple.getValue(); - - if ( values.isArrayTree() ) - { - ArrayTree set = values.getArrayTree(); - dupsCursor = new ArrayTreeCursor( set ); - } - else - { - BTree tree = table.getBTree( values.getBTreeRedirect() ); - dupsCursor = new KeyBTreeCursor( 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 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 Apache Directory Project + * @version $Rev$ + */ +class DupsCursor extends AbstractTupleCursor +{ + private static final Logger LOG = LoggerFactory.getLogger( DupsCursor.class.getSimpleName() ); + + /** + * The JDBM backed table this Cursor traverses over. + */ + private final JdbmTable 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 containerCursor; + + /** + * The current Tuple returned from the wrappedCursor DupsContainerCursor. + */ + private final Tuple> containerTuple = new Tuple>(); + + /** + * 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 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 returnedTuple = new Tuple(); + + /** + * Whether or not a value is available when get() is called. + */ + private boolean valueAvailable; + + + public DupsCursor( JdbmTable table ) throws Exception + { + this.table = table; + this.containerCursor = new DupsContainerCursor( 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>( key, null ) ); + + if ( containerCursor.next() ) + { + containerTuple.setBoth( containerCursor.get() ); + DupsContainer values = containerTuple.getValue(); + + if ( values.isArrayTree() ) + { + ArrayTree set = values.getArrayTree(); + dupsCursor = new ArrayTreeCursor( set ); + } + else + { + BTree tree = table.getBTree( values.getBTreeRedirect() ); + dupsCursor = new KeyBTreeCursor( 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>( key, null ) ); + } + else + { + containerCursor.before( new Tuple>( key, null ) ); + } + + if ( containerCursor.next() ) + { + containerTuple.setBoth( containerCursor.get() ); + DupsContainer values = containerTuple.getValue(); + + if ( values.isArrayTree() ) + { + ArrayTree set = values.getArrayTree(); + dupsCursor = new ArrayTreeCursor( set ); + } + else + { + BTree tree = table.getBTree( values.getBTreeRedirect() ); + dupsCursor = new KeyBTreeCursor( 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 element ) throws Exception + { + beforeValue( element.getKey(), element.getValue() ); + } + + + public void after( Tuple 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 values = containerTuple.getValue(); + + if ( containerTuple.getValue().isArrayTree() ) + { + dupsCursor = new ArrayTreeCursor( values.getArrayTree() ); + } + else + { + BTree bt = table.getBTree( values.getBTreeRedirect() ); + dupsCursor = new KeyBTreeCursor( 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 values = containerTuple.getValue(); + + if ( values.isArrayTree() ) + { + ArrayTree set = values.getArrayTree(); + dupsCursor = new ArrayTreeCursor( set ); + } + else + { + BTree tree = table.getBTree( values.getBTreeRedirect() ); + dupsCursor = new KeyBTreeCursor( 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 values = containerTuple.getValue(); + + if ( values.isArrayTree() ) + { + ArrayTree set = values.getArrayTree(); + dupsCursor = new ArrayTreeCursor( set ); + } + else + { + BTree tree = table.getBTree( values.getBTreeRedirect() ); + dupsCursor = new KeyBTreeCursor( 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 values = containerTuple.getValue(); + + if ( values.isArrayTree() ) + { + ArrayTree set = values.getArrayTree(); + dupsCursor = new ArrayTreeCursor( set ); + } + else + { + BTree tree = table.getBTree( values.getBTreeRedirect() ); + dupsCursor = new KeyBTreeCursor( 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 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 Apache Directory Project - * @version $Rev$, $Date$ - */ -public class KeyBTreeCursor extends AbstractCursor -{ - private final Tuple tuple = new Tuple(); - - private final BTree btree; - private final Comparator 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 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 Apache Directory Project + * @version $Rev$, $Date$ + */ +public class KeyBTreeCursor extends AbstractCursor +{ + private final Tuple tuple = new Tuple(); + + private final BTree btree; + private final Comparator 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 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 Apache Directory Project - * @version $Rev$, $Date$ - */ -public class KeyTupleArrayCursor extends AbstractTupleCursor -{ - private final ArrayTreeCursor wrapped; - private final K key; - - private Tuple returnedTuple = new Tuple(); - 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 arrayTree, K key ) - { - this.key = key; - this.wrapped = new ArrayTreeCursor( 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 element ) throws Exception - { - checkNotClosed( "before()" ); - wrapped.before( element.getValue() ); - clearValue(); - } - - - public void after( Tuple 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 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 Apache Directory Project + * @version $Rev$, $Date$ + */ +public class KeyTupleArrayCursor extends AbstractTupleCursor +{ + private final ArrayTreeCursor wrapped; + private final K key; + + private Tuple returnedTuple = new Tuple(); + 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 arrayTree, K key ) + { + this.key = key; + this.wrapped = new ArrayTreeCursor( 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 element ) throws Exception + { + checkNotClosed( "before()" ); + wrapped.before( element.getValue() ); + clearValue(); + } + + + public void after( Tuple 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 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 Apache Directory Project - * @version $Rev$, $Date$ - */ -public class KeyTupleBTreeCursor extends AbstractTupleCursor -{ - private final Comparator comparator; - private final BTree btree; - private final K key; - - private jdbm.helper.Tuple valueTuple = new jdbm.helper.Tuple(); - private Tuple returnedTuple = new Tuple(); - 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 key ordering - * @throws Exception of there are problems accessing the BTree - */ - public KeyTupleBTreeCursor( BTree btree, K key, Comparator 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 element ) throws Exception - { - checkNotClosed( "before()" ); - browser = btree.browse( element.getValue() ); - clearValue(); - } - - - public void after( Tuple 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 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 Apache Directory Project + * @version $Rev$, $Date$ + */ +public class KeyTupleBTreeCursor extends AbstractTupleCursor +{ + private final Comparator comparator; + private final BTree btree; + private final K key; + + private jdbm.helper.Tuple valueTuple = new jdbm.helper.Tuple(); + private Tuple returnedTuple = new Tuple(); + 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 key ordering + * @throws Exception of there are problems accessing the BTree + */ + public KeyTupleBTreeCursor( BTree btree, K key, Comparator 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 element ) throws Exception + { + checkNotClosed( "before()" ); + browser = btree.browse( element.getValue() ); + clearValue(); + } + + + public void after( Tuple 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 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 Apache Directory Project - * @version $Rev$, $Date$ - */ -class NoDupsCursor extends AbstractTupleCursor -{ - private final JdbmTable table; - - private jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple(); - private Tuple returnedTuple = new Tuple(); - 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 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 element ) throws Exception - { - beforeKey( element.getKey() ); - } - - - public void after( Tuple 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 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 Apache Directory Project + * @version $Rev$, $Date$ + */ +class NoDupsCursor extends AbstractTupleCursor +{ + private final JdbmTable table; + + private jdbm.helper.Tuple jdbmTuple = new jdbm.helper.Tuple(); + private Tuple returnedTuple = new Tuple(); + 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 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 element ) throws Exception + { + beforeKey( element.getKey() ); + } + + + public void after( Tuple 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 get() throws Exception + { + checkNotClosed( "get()" ); + if ( valueAvailable ) + { + return returnedTuple; + } + + throw new InvalidCursorPositionException(); + } + + + public boolean isElementReused() + { + return true; + } +}