Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/KeyTupleArrayCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/KeyTupleArrayCursor.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/KeyTupleArrayCursor.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/KeyTupleArrayCursor.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,284 @@
+/*
+ * 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.xdbm;
+
+
+import org.apache.directory.server.core.avltree.ArrayTree;
+import org.apache.directory.server.core.avltree.ArrayTreeCursor;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.model.cursor.AbstractCursor;
+import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
+import org.apache.directory.shared.ldap.model.cursor.Tuple;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * 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>
+ */
+public class KeyTupleArrayCursor<K, V> extends AbstractCursor<Tuple<K, V>>
+{
+ /** A dedicated log for cursors */
+ private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
+ 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 arrayTree 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 );
+ LOG_CURSOR.debug( "Creating KeyTupleArrayCursor {}", this );
+ }
+
+
+ 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( I18n.err( I18n.ERR_446 ) );
+ }
+
+
+ public void afterKey( K key ) throws Exception
+ {
+ throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+ }
+
+
+ public void beforeValue( K key, V value ) throws Exception
+ {
+ checkNotClosed( "beforeValue()" );
+ if ( key != null && !key.equals( this.key ) )
+ {
+ throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+ }
+
+ 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( I18n.err( I18n.ERR_446 ) );
+ }
+
+ 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();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws Exception
+ {
+ LOG_CURSOR.debug( "Closing KeyTupleArrayCursor {}", this );
+
+ if ( wrapped != null )
+ {
+ wrapped.close();
+ }
+
+ super.close();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close( Exception reason ) throws Exception
+ {
+ LOG_CURSOR.debug( "Closing KeyTupleArrayCursor {}", this );
+
+ if ( wrapped != null )
+ {
+ wrapped.close( reason );
+ }
+
+ super.close( reason );
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString( String tabs )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( tabs ).append( "KeyTupleArrayCursor (" );
+
+ if ( available() )
+ {
+ sb.append( "available)" );
+ }
+ else
+ {
+ sb.append( "absent)" );
+ }
+
+ sb.append( "#" ).append( key );
+
+ sb.append( " :\n" );
+
+ sb.append( wrapped.toString( tabs + " " ) );
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return toString( "" );
+ }
+}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/MasterTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/MasterTable.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/MasterTable.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/MasterTable.java Mon Sep 24 02:17:13 2012
@@ -20,12 +20,15 @@
package org.apache.directory.server.xdbm;
+import org.apache.directory.shared.ldap.model.entry.Entry;
+
+
/**
* A master table used to store indexable entries.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public interface MasterTable<ID, E> extends Table<ID, E>
+public interface MasterTable extends Table<String, Entry>
{
/** the base name for the db file for this table */
String DBF = "master";
@@ -42,14 +45,5 @@ public interface MasterTable<ID, E> exte
* @return the current value of this MasterTable's sequence incremented by one
* @throws Exception on failure to update the id sequence
*/
- ID getNextId( E entry ) throws Exception;
-
-
- /**
- * Resets the root ID to 0, this method should be called after deleting the
- * context entry of the partition
- *
- * @throws Exception in case of any failure while resetting the root id value
- */
- void resetCounter() throws Exception;
+ String getNextId( Entry entry ) throws Exception;
}
\ No newline at end of file
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdn.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdn.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdn.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdn.java Mon Sep 24 02:17:13 2012
@@ -37,10 +37,10 @@ import org.apache.directory.shared.ldap.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class ParentIdAndRdn<ID extends Comparable<ID>> implements Externalizable, Comparable<ParentIdAndRdn<ID>>
+public class ParentIdAndRdn implements Externalizable, Comparable<ParentIdAndRdn>
{
/** The entry ID */
- protected ID parentId;
+ protected String parentId;
/** The list of Rdn for this instance */
protected Rdn[] rdns;
@@ -51,6 +51,7 @@ public class ParentIdAndRdn<ID extends C
/** Number of global descendant */
protected int nbDescendants;
+
/**
* Serializable constructor.
*/
@@ -65,7 +66,7 @@ public class ParentIdAndRdn<ID extends C
* @param parentId the parent ID
* @param rdns the RDNs
*/
- public ParentIdAndRdn( ID parentId, Rdn... rdns )
+ public ParentIdAndRdn( String parentId, Rdn... rdns )
{
this.parentId = parentId;
this.rdns = rdns;
@@ -78,7 +79,7 @@ public class ParentIdAndRdn<ID extends C
* @param parentId the parent ID
* @param rdns the RDNs
*/
- public ParentIdAndRdn( ID parentId, List<Rdn> rdns )
+ public ParentIdAndRdn( String parentId, List<Rdn> rdns )
{
this.parentId = parentId;
this.rdns = rdns.toArray( new Rdn[rdns.size()] );
@@ -92,7 +93,7 @@ public class ParentIdAndRdn<ID extends C
*
* @return the parent ID
*/
- public ID getParentId()
+ public String getParentId()
{
return parentId;
}
@@ -103,7 +104,7 @@ public class ParentIdAndRdn<ID extends C
*
* @param parentId the new parent ID
*/
- public void setParentId( ID parentId )
+ public void setParentId( String parentId )
{
this.parentId = parentId;
}
@@ -152,12 +153,12 @@ public class ParentIdAndRdn<ID extends C
return true;
}
- if ( !( obj instanceof ParentIdAndRdn<?> ) )
+ if ( !( obj instanceof ParentIdAndRdn ) )
{
return false;
}
- ParentIdAndRdn<ID> that = ( ParentIdAndRdn<ID> ) obj;
+ ParentIdAndRdn that = ( ParentIdAndRdn ) obj;
if ( rdns == null )
{
@@ -183,18 +184,18 @@ public class ParentIdAndRdn<ID extends C
return true;
}
-
-
+
+
/**
* {@inheritDoc}
*/
- public int compareTo( ParentIdAndRdn<ID> that )
+ public int compareTo( ParentIdAndRdn that )
{
// Special case when that.rdns = null : we are searching for oneLevel or subLevel scope
if ( that.rdns == null )
{
int val = parentId.compareTo( that.parentId );
-
+
if ( val != 0 )
{
return val;
@@ -209,7 +210,7 @@ public class ParentIdAndRdn<ID extends C
if ( rdns == null )
{
int res = parentId.compareTo( that.parentId );
-
+
if ( res == 0 )
{
return -1;
@@ -219,14 +220,14 @@ public class ParentIdAndRdn<ID extends C
return res;
}
}
-
+
int val = parentId.compareTo( that.getParentId() );
if ( val != 0 )
{
return val;
}
-
+
// The ID is the same, check the RDNs now
val = rdns.length - that.rdns.length;
@@ -235,12 +236,12 @@ public class ParentIdAndRdn<ID extends C
{
return val;
}
-
+
if ( rdns.length == 1 )
{
// Special case : we only have one rdn.
val = rdns[0].getNormName().compareTo( that.rdns[0].getNormName() );
-
+
return val;
}
else
@@ -248,13 +249,13 @@ public class ParentIdAndRdn<ID extends C
for ( int i = 0; i < rdns.length; i++ )
{
val = rdns[i].getNormName().compareTo( that.rdns[i].getNormName() );
-
+
if ( val != 0 )
{
return val;
}
}
-
+
return 0;
}
}
@@ -262,7 +263,7 @@ public class ParentIdAndRdn<ID extends C
public void writeExternal( ObjectOutput out ) throws IOException
{
- out.writeObject( parentId );
+ out.writeUTF( parentId );
out.writeInt( nbChildren );
out.writeInt( nbDescendants );
out.writeInt( rdns.length );
@@ -277,7 +278,7 @@ public class ParentIdAndRdn<ID extends C
@SuppressWarnings("unchecked")
public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
{
- parentId = ( ID ) in.readObject();
+ parentId = in.readUTF();
nbChildren = in.readInt();
nbDescendants = in.readInt();
int size = in.readInt();
@@ -330,8 +331,6 @@ public class ParentIdAndRdn<ID extends C
}
-
-
/**
* {@inheritDoc}
*/
@@ -349,7 +348,7 @@ public class ParentIdAndRdn<ID extends C
else
{
boolean isFirst = true;
-
+
for ( Rdn rdn : rdns )
{
if ( isFirst )
@@ -360,16 +359,15 @@ public class ParentIdAndRdn<ID extends C
{
sb.append( "," );
}
-
+
sb.append( rdn );
}
sb.append( "'>" );
-
+
sb.append( "[nbC:" ).append( nbChildren ).append( ", nbD:" ).append( nbDescendants ).append( "]" );
}
-
return sb.toString();
}
}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdnComparator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdnComparator.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdnComparator.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/ParentIdAndRdnComparator.java Mon Sep 24 02:17:13 2012
@@ -29,7 +29,7 @@ import org.apache.directory.shared.ldap.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class ParentIdAndRdnComparator<ID extends Comparable<ID>> extends SerializableComparator<ParentIdAndRdn<ID>>
+public class ParentIdAndRdnComparator<ID extends Comparable<ID>> extends SerializableComparator<ParentIdAndRdn>
{
/** The serial version UID */
private static final long serialVersionUID = 2L;
@@ -50,7 +50,7 @@ public class ParentIdAndRdnComparator<ID
* {@inheritDoc}
*/
@Override
- public int compare( ParentIdAndRdn<ID> rdn1, ParentIdAndRdn<ID> rdn2 )
+ public int compare( ParentIdAndRdn rdn1, ParentIdAndRdn rdn2 )
{
return rdn1.compareTo( rdn2 );
}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/SingletonIndexCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/SingletonIndexCursor.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/SingletonIndexCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/SingletonIndexCursor.java Mon Sep 24 02:17:13 2012
@@ -21,7 +21,6 @@ package org.apache.directory.server.xdbm
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
-import org.apache.directory.shared.ldap.model.entry.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,7 +30,7 @@ import org.slf4j.LoggerFactory;
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class SingletonIndexCursor<V, ID> extends AbstractIndexCursor<V, Entry, ID>
+public class SingletonIndexCursor<V> extends AbstractIndexCursor<V>
{
/** A dedicated log for cursors */
private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
@@ -39,10 +38,10 @@ public class SingletonIndexCursor<V, ID>
private boolean beforeFirst = true;
private boolean afterLast;
private boolean onSingleton;
- private final IndexEntry<V, ID> singleton;
+ private final IndexEntry<V, String> singleton;
- public SingletonIndexCursor( IndexEntry<V, ID> singleton )
+ public SingletonIndexCursor( IndexEntry<V, String> singleton )
{
LOG_CURSOR.debug( "Creating SingletonIndexCursor {}", this );
this.singleton = singleton;
@@ -178,7 +177,7 @@ public class SingletonIndexCursor<V, ID>
}
- public IndexEntry<V, ID> get() throws Exception
+ public IndexEntry<V, String> get() throws Exception
{
checkNotClosed( "()" );
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/Store.java Mon Sep 24 02:17:13 2012
@@ -29,6 +29,7 @@ import java.util.Set;
import org.apache.directory.server.constants.ApacheSchemaConstants;
import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.cursor.Cursor;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.entry.Modification;
import org.apache.directory.shared.ldap.model.name.Dn;
@@ -42,7 +43,7 @@ import org.apache.directory.shared.ldap.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public interface Store<E, ID extends Comparable<ID>>
+public interface Store
{
/*
* W H Y H A V E A S T O R E I N T E R F A C E ?
@@ -121,14 +122,6 @@ public interface Store<E, ID extends Com
/**
- * Gets the root ID of this store implementation.
- *
- * @return the root ID
- */
- ID getRootId();
-
-
- /**
* Sets the flag telling the server to flush on disk when some
* modification has been done.
* @param isSyncOnWrite A boolean set to true if we have to flush on disk
@@ -165,7 +158,7 @@ public interface Store<E, ID extends Com
* @param index The index to add
* @throws Exception If the addition failed
*/
- void addIndex( Index<?, E, ID> index ) throws Exception;
+ void addIndex( Index<?, Entry, String> index ) throws Exception;
//------------------------------------------------------------------------
@@ -174,49 +167,43 @@ public interface Store<E, ID extends Com
/**
* @return The Presence system index
*/
- Index<String, E, ID> getPresenceIndex();
+ Index<String, Entry, String> getPresenceIndex();
/**
* @return The Alias system index
*/
- Index<String, E, ID> getAliasIndex();
+ Index<String, Entry, String> getAliasIndex();
/**
* @return The OneAlias system index
*/
- Index<ID, E, ID> getOneAliasIndex();
+ Index<String, Entry, String> getOneAliasIndex();
/**
* @return The SubAlias system index
*/
- Index<ID, E, ID> getSubAliasIndex();
+ Index<String, Entry, String> getSubAliasIndex();
/**
* @return The Rdn system index
*/
- Index<ParentIdAndRdn<ID>, E, ID> getRdnIndex();
+ Index<ParentIdAndRdn, Entry, String> getRdnIndex();
/**
* @return The ObjectClass system index
*/
- Index<String, E, ID> getObjectClassIndex();
-
-
- /**
- * @return The EntryUUID system index
- */
- Index<String, E, ID> getEntryUuidIndex();
+ Index<String, Entry, String> getObjectClassIndex();
/**
* @return The EntryCSN system index
*/
- Index<String, E, ID> getEntryCsnIndex();
+ Index<String, Entry, String> getEntryCsnIndex();
/**
@@ -268,7 +255,7 @@ public interface Store<E, ID extends Com
* @return The associated user <strong>or</strong> system index
* @throws IndexNotFoundException If the index does not exist
*/
- Index<?, E, ID> getIndex( AttributeType attributeType ) throws IndexNotFoundException;
+ Index<?, Entry, String> getIndex( AttributeType attributeType ) throws IndexNotFoundException;
/**
@@ -277,7 +264,7 @@ public interface Store<E, ID extends Com
* @return The associated user index
* @throws IndexNotFoundException If the index does not exist
*/
- Index<?, E, ID> getUserIndex( AttributeType attributeType ) throws IndexNotFoundException;
+ Index<?, Entry, String> getUserIndex( AttributeType attributeType ) throws IndexNotFoundException;
/**
@@ -286,7 +273,7 @@ public interface Store<E, ID extends Com
* @return The associated system index
* @throws IndexNotFoundException If the index does not exist
*/
- Index<?, E, ID> getSystemIndex( AttributeType attributeType ) throws IndexNotFoundException;
+ Index<?, Entry, String> getSystemIndex( AttributeType attributeType ) throws IndexNotFoundException;
/**
@@ -295,7 +282,7 @@ public interface Store<E, ID extends Com
* @param dn the normalized entry Dn
* @return the entry's id, or <code>null</code> if the Dn doesn't exists
*/
- ID getEntryId( Dn dn ) throws Exception;
+ String getEntryId( Dn dn ) throws Exception;
/**
@@ -304,18 +291,18 @@ public interface Store<E, ID extends Com
* @param id the entry's id
* @return the entry's Dn
*/
- Dn getEntryDn( ID id ) throws Exception;
+ Dn getEntryDn( String id ) throws Exception;
/**
- * Gets the ID of an entry's parent using the child entry's ID.
+ * Gets the UUID of an entry's parent using the child entry's UUID.
* Note that the suffix entry returns 0, which does not map to any entry.
*
- * @param childId the ID of the entry
- * @return the id of the parent entry or zero if the suffix entry ID is used
+ * @param childId the UUID of the entry
+ * @return the id of the parent entry or zero if the suffix entry UUID is used
* @throws Exception on failures to access the underlying store
*/
- ID getParentId( ID childId ) throws Exception;
+ String getParentId( String childId ) throws Exception;
/**
@@ -330,10 +317,10 @@ public interface Store<E, ID extends Com
/**
* Delete an entry from the store
*
- * @param id The Entry ID we want to delete
+ * @param id The Entry UUID we want to delete
* @throws Exception If the deletion failed for any reason
*/
- void delete( ID id ) throws Exception;
+ void delete( String id ) throws Exception;
/**
@@ -343,38 +330,38 @@ public interface Store<E, ID extends Com
* @return an IndexEntry Cursor over the child entries
* @throws Exception on failures to access the underlying store
*/
- IndexCursor<ID, E, ID> list( ID id ) throws Exception;
+ Cursor<IndexEntry<String, String>> list( String id ) throws Exception;
/**
- * Get back an entry knowing its ID
+ * Get back an entry knowing its UUID
*
- * @param id The Entry ID we want to get back
+ * @param id The Entry UUID we want to get back
* @return The found Entry, or null if not found
* @throws Exception If the lookup failed for any reason (except a not found entry)
*/
- Entry lookup( ID id ) throws Exception;
+ Entry lookup( String id ) throws Exception;
/**
- * Get back an entry knowing its ID
+ * Get back an entry knowing its UUID
*
- * @param id The Entry ID we want to get back
+ * @param id The Entry UUID we want to get back
* @param dn The entry DN when we have it
* @return The found Entry, or null if not found
* @throws Exception If the lookup failed for any reason (except a not found entry)
*/
- Entry lookup( ID id, Dn dn ) throws Exception;
+ Entry lookup( String id, Dn dn ) throws Exception;
/**
- * Gets the count of immediate children of the given entry ID.
+ * Gets the count of immediate children of the given entry UUID.
*
- * @param id the entry ID
+ * @param id the entry UUID
* @return the child count
* @throws Exception on failures to access the underlying store
*/
- int getChildCount( ID id ) throws Exception;
+ int getChildCount( String id ) throws Exception;
/**
@@ -427,7 +414,7 @@ public interface Store<E, ID extends Com
* <li><b>oneAlias</b> index</li>
* <li><b>subAlias</b> index</li>
* </ul>
- * <p>The <b>Alias</b> index is not updated, as the entry ID won't change.</p>
+ * <p>The <b>Alias</b> index is not updated, as the entry UUID won't change.</p>
* <p>We have a few check we must do before moving the entry :
* <ul>
* <li>The destination must not exist
@@ -445,9 +432,8 @@ public interface Store<E, ID extends Com
/**
- * Gets the default ID.
- *
- * @return the default ID.
+ * Expose the Master table
+ * @return The masterTable instance
*/
- ID getDefaultId() throws Exception;
+ MasterTable getMasterTable();
}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlIndex.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlIndex.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlIndex.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlIndex.java Mon Sep 24 02:17:13 2012
@@ -23,11 +23,10 @@ package org.apache.directory.server.xdbm
import java.net.URI;
import org.apache.directory.server.core.partition.impl.btree.IndexCursorAdaptor;
-import org.apache.directory.server.core.partition.impl.btree.LongComparator;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.xdbm.AbstractIndex;
import org.apache.directory.server.xdbm.EmptyIndexCursor;
-import org.apache.directory.server.xdbm.IndexCursor;
+import org.apache.directory.server.xdbm.IndexEntry;
import org.apache.directory.shared.ldap.model.cursor.Cursor;
import org.apache.directory.shared.ldap.model.cursor.EmptyCursor;
import org.apache.directory.shared.ldap.model.cursor.Tuple;
@@ -36,6 +35,7 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.model.schema.MatchingRule;
import org.apache.directory.shared.ldap.model.schema.Normalizer;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.ldap.model.schema.comparators.UuidComparator;
/**
@@ -43,11 +43,11 @@ import org.apache.directory.shared.ldap.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class AvlIndex<K, O> extends AbstractIndex<K, O, Long>
+public class AvlIndex<K, O> extends AbstractIndex<K, O, String>
{
protected Normalizer normalizer;
- protected AvlTable<K, Long> forward;
- protected AvlTable<Long, K> reverse;
+ protected AvlTable<K, String> forward;
+ protected AvlTable<String, K> reverse;
public AvlIndex()
@@ -98,7 +98,7 @@ public class AvlIndex<K, O> extends Abst
* primary keys. A value for an attribute can occur several times in
* different entries so the forward map can have more than one value.
*/
- forward = new AvlTable<K, Long>( attributeType.getName(), comp, LongComparator.INSTANCE, true );
+ forward = new AvlTable<K, String>( attributeType.getName(), comp, UuidComparator.INSTANCE, true );
/*
* Now the reverse map stores the primary key into the master table as
@@ -110,17 +110,17 @@ public class AvlIndex<K, O> extends Abst
{
if ( attributeType.isSingleValued() )
{
- reverse = new AvlTable<Long, K>( attributeType.getName(), LongComparator.INSTANCE, comp, false );
+ reverse = new AvlTable<String, K>( attributeType.getName(), UuidComparator.INSTANCE, comp, false );
}
else
{
- reverse = new AvlTable<Long, K>( attributeType.getName(), LongComparator.INSTANCE, comp, true );
+ reverse = new AvlTable<String, K>( attributeType.getName(), UuidComparator.INSTANCE, comp, true );
}
}
}
- public void add( K attrVal, Long id ) throws Exception
+ public void add( K attrVal, String id ) throws Exception
{
forward.put( attrVal, id );
@@ -169,17 +169,17 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public void drop( Long id ) throws Exception
+ public void drop( String id ) throws Exception
{
if ( withReverse )
{
if ( isDupsEnabled() )
{
- Cursor<Tuple<Long, K>> cursor = reverse.cursor( id );
+ Cursor<Tuple<String, K>> cursor = reverse.cursor( id );
while ( cursor.next() )
{
- Tuple<Long, K> tuple = cursor.get();
+ Tuple<String, K> tuple = cursor.get();
forward.remove( tuple.getValue(), id );
}
@@ -200,7 +200,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public void drop( K attrVal, Long id ) throws Exception
+ public void drop( K attrVal, String id ) throws Exception
{
forward.remove( attrVal, id );
@@ -223,7 +223,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean forward( K attrVal, Long id ) throws Exception
+ public boolean forward( K attrVal, String id ) throws Exception
{
return forward.has( attrVal, id );
}
@@ -233,7 +233,7 @@ public class AvlIndex<K, O> extends Abst
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
- public IndexCursor<K, O, Long> forwardCursor() throws Exception
+ public Cursor<IndexEntry<K, String>> forwardCursor() throws Exception
{
return new IndexCursorAdaptor( forward.cursor(), true );
}
@@ -243,7 +243,7 @@ public class AvlIndex<K, O> extends Abst
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
- public IndexCursor<K, O, Long> forwardCursor( K key ) throws Exception
+ public Cursor<IndexEntry<K, String>> forwardCursor( K key ) throws Exception
{
return new IndexCursorAdaptor( forward.cursor( key ), true );
}
@@ -261,7 +261,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean forwardGreaterOrEq( K attrVal, Long id ) throws Exception
+ public boolean forwardGreaterOrEq( K attrVal, String id ) throws Exception
{
return forward.hasGreaterOrEqual( attrVal, id );
}
@@ -279,7 +279,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean forwardLessOrEq( K attrVal, Long id ) throws Exception
+ public boolean forwardLessOrEq( K attrVal, String id ) throws Exception
{
return forward.hasLessOrEqual( attrVal, id );
}
@@ -288,7 +288,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public Long forwardLookup( K attrVal ) throws Exception
+ public String forwardLookup( K attrVal ) throws Exception
{
return forward.get( attrVal );
}
@@ -297,7 +297,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public Cursor<Long> forwardValueCursor( K key ) throws Exception
+ public Cursor<String> forwardValueCursor( K key ) throws Exception
{
return forward.valueCursor( key );
}
@@ -324,7 +324,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean reverse( Long id ) throws Exception
+ public boolean reverse( String id ) throws Exception
{
if ( withReverse )
{
@@ -340,7 +340,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean reverse( Long id, K attrVal ) throws Exception
+ public boolean reverse( String id, K attrVal ) throws Exception
{
if ( withReverse )
{
@@ -357,7 +357,7 @@ public class AvlIndex<K, O> extends Abst
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
- public IndexCursor<K, O, Long> reverseCursor() throws Exception
+ public Cursor<IndexEntry<K, String>> reverseCursor() throws Exception
{
if ( withReverse )
{
@@ -365,7 +365,7 @@ public class AvlIndex<K, O> extends Abst
}
else
{
- return new EmptyIndexCursor<K, O, Long>();
+ return new EmptyIndexCursor<K>();
}
}
@@ -374,7 +374,7 @@ public class AvlIndex<K, O> extends Abst
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
- public IndexCursor<K, O, Long> reverseCursor( Long id ) throws Exception
+ public Cursor<IndexEntry<K, String>> reverseCursor( String id ) throws Exception
{
if ( withReverse )
{
@@ -382,7 +382,7 @@ public class AvlIndex<K, O> extends Abst
}
else
{
- return new EmptyIndexCursor<K, O, Long>();
+ return new EmptyIndexCursor<K>();
}
}
@@ -390,7 +390,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean reverseGreaterOrEq( Long id ) throws Exception
+ public boolean reverseGreaterOrEq( String id ) throws Exception
{
if ( withReverse )
{
@@ -406,7 +406,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean reverseGreaterOrEq( Long id, K attrVal ) throws Exception
+ public boolean reverseGreaterOrEq( String id, K attrVal ) throws Exception
{
if ( withReverse )
{
@@ -422,7 +422,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean reverseLessOrEq( Long id ) throws Exception
+ public boolean reverseLessOrEq( String id ) throws Exception
{
if ( withReverse )
{
@@ -438,7 +438,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public boolean reverseLessOrEq( Long id, K attrVal ) throws Exception
+ public boolean reverseLessOrEq( String id, K attrVal ) throws Exception
{
if ( withReverse )
{
@@ -454,7 +454,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public K reverseLookup( Long id ) throws Exception
+ public K reverseLookup( String id ) throws Exception
{
if ( withReverse )
{
@@ -470,7 +470,7 @@ public class AvlIndex<K, O> extends Abst
/**
* {@inheritDoc}
*/
- public Cursor<K> reverseValueCursor( Long id ) throws Exception
+ public Cursor<K> reverseValueCursor( String id ) throws Exception
{
if ( withReverse )
{
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlMasterTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlMasterTable.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlMasterTable.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlMasterTable.java Mon Sep 24 02:17:13 2012
@@ -21,9 +21,10 @@ package org.apache.directory.server.xdbm
import java.util.Comparator;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.UUID;
import org.apache.directory.server.xdbm.MasterTable;
+import org.apache.directory.shared.ldap.model.entry.Entry;
/**
@@ -32,12 +33,9 @@ import org.apache.directory.server.xdbm.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class AvlMasterTable<E> extends AvlTable<Long, E> implements MasterTable<Long, E>
+public class AvlMasterTable extends AvlTable<String, Entry> implements MasterTable
{
- private AtomicLong counter = new AtomicLong( 0 );
-
-
- public AvlMasterTable( String name, Comparator<Long> keyComparator, Comparator<E> valComparator,
+ public AvlMasterTable( String name, Comparator<String> keyComparator, Comparator<Entry> valComparator,
boolean dupsEnabled )
{
super( name, keyComparator, valComparator, dupsEnabled );
@@ -47,17 +45,8 @@ public class AvlMasterTable<E> extends A
/**
* {@inheritDoc}
*/
- public Long getNextId( E entry ) throws Exception
- {
- return counter.incrementAndGet();
- }
-
-
- /**
- * {@inheritDoc}
- */
- public void resetCounter() throws Exception
+ public String getNextId( Entry entry ) throws Exception
{
- counter.set( 0L );
+ return UUID.randomUUID().toString();
}
}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlRdnIndex.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlRdnIndex.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlRdnIndex.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlRdnIndex.java Mon Sep 24 02:17:13 2012
@@ -21,13 +21,14 @@
package org.apache.directory.server.xdbm.impl.avl;
-import org.apache.directory.server.core.partition.impl.btree.LongComparator;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.xdbm.ParentIdAndRdn;
import org.apache.directory.server.xdbm.ParentIdAndRdnComparator;
+import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.schema.AttributeType;
import org.apache.directory.shared.ldap.model.schema.MatchingRule;
import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.ldap.model.schema.comparators.UuidComparator;
/**
@@ -35,7 +36,7 @@ import org.apache.directory.shared.ldap.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public class AvlRdnIndex<E> extends AvlIndex<ParentIdAndRdn<Long>, E>
+public class AvlRdnIndex extends AvlIndex<ParentIdAndRdn, Entry>
{
public AvlRdnIndex()
{
@@ -72,18 +73,18 @@ public class AvlRdnIndex<E> extends AvlI
throw new Exception( I18n.err( I18n.ERR_212, attributeType ) );
}
- ParentIdAndRdnComparator<Long> comp = new ParentIdAndRdnComparator<Long>( mr.getOid() );
+ ParentIdAndRdnComparator<String> comp = new ParentIdAndRdnComparator<String>( mr.getOid() );
- LongComparator.INSTANCE.setSchemaManager( schemaManager );
+ UuidComparator.INSTANCE.setSchemaManager( schemaManager );
/*
* The forward key/value map stores attribute values to master table
* primary keys. A value for an attribute can occur several times in
* different entries so the forward map can have more than one value.
*/
- forward = new AvlTable<ParentIdAndRdn<Long>, Long>( attributeType.getName(), comp, LongComparator.INSTANCE,
+ forward = new AvlTable<ParentIdAndRdn, String>( attributeType.getName(), comp, UuidComparator.INSTANCE,
false );
- reverse = new AvlTable<Long, ParentIdAndRdn<Long>>( attributeType.getName(), LongComparator.INSTANCE, comp,
+ reverse = new AvlTable<String, ParentIdAndRdn>( attributeType.getName(), UuidComparator.INSTANCE, comp,
false );
}
}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/Evaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/Evaluator.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/Evaluator.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/Evaluator.java Mon Sep 24 02:17:13 2012
@@ -21,6 +21,7 @@ package org.apache.directory.server.xdbm
import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.filter.ExprNode;
@@ -48,7 +49,7 @@ import org.apache.directory.shared.ldap.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public interface Evaluator<N extends ExprNode, E, ID>
+public interface Evaluator<N extends ExprNode>
{
/**
* Evaluates a candidate to determine if a filter expression selects it.
@@ -62,7 +63,7 @@ public interface Evaluator<N extends Exp
* @return true if filter selects the candidate false otherwise
* @throws Exception if there are faults during evaluation
*/
- boolean evaluate( IndexEntry<?, ID> entry ) throws Exception;
+ boolean evaluate( IndexEntry<?, String> entry ) throws Exception;
/**
@@ -73,7 +74,7 @@ public interface Evaluator<N extends Exp
* @return true if filter selects the candidate false otherwise
* @throws Exception if there are faults during evaluation
*/
- boolean evaluateEntry( E entry ) throws Exception;
+ boolean evaluate( Entry entry ) throws Exception;
/**
@@ -82,4 +83,12 @@ public interface Evaluator<N extends Exp
* @return the AST for the expression
*/
N getExpression();
+
+
+ /**
+ * Pretty-print an Evaluator
+ * @param tabs The tabs to add before the evaluator
+ * @return The pretty-printed evaluator and its descendants
+ */
+ String toString( String tabs );
}
Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/PartitionSearchResult.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,234 @@
+/*
+ * 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.xdbm.search;
+
+
+import java.util.Set;
+
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.shared.ldap.model.cursor.SetCursor;
+import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+
+
+/**
+ * A class containing the result of a search :
+ * <ul>
+ * <li>A set of candidate UUIDs</li>
+ * <li>A set of aliased entry if we have any</li>
+ * <li>A flag telling if we are dereferencing aliases or not</li>
+ * <li>A hierarchy of evaluators to use to validate the candidates</li>
+ * </ul>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PartitionSearchResult
+{
+ /** The set of candidate UUIDs selected by the search */
+ private SetCursor<IndexEntry<String, String>> resultSet;
+
+ /** The set of candidate UUIDs */
+ private Set<String> candidateSet;
+
+ /** The flag indicating if we are dereferencing the aliases. Default to Never. */
+ private AliasDerefMode aliasDerefMode = AliasDerefMode.NEVER_DEREF_ALIASES;
+
+ /** The evaluator to validate the candidates */
+ private Evaluator<? extends ExprNode> evaluator;
+
+ /** The SchemaManager */
+ private SchemaManager schemaManager;
+
+
+ /**
+ * Create a PartitionSearchResult instance
+ */
+ public PartitionSearchResult( SchemaManager schemaManager )
+ {
+ this.schemaManager = schemaManager;
+ }
+
+
+ /**
+ * @return the resultSet
+ */
+ public SetCursor<IndexEntry<String, String>> getResultSet()
+ {
+ return resultSet;
+ }
+
+
+ /**
+ * @param resultSet the resultSet to set
+ */
+ public void setResultSet( Set<IndexEntry<String, String>> set )
+ {
+ resultSet = new SetCursor<IndexEntry<String, String>>( set );
+ }
+
+
+ /**
+ * @return the candidateSet
+ */
+ public Set<String> getCandidateSet()
+ {
+ return candidateSet;
+ }
+
+
+ /**
+ * @param candidateSet the candidateSet to set
+ */
+ public void setCandidateSet( Set<String> set )
+ {
+ candidateSet = set;
+ }
+
+
+ /**
+ * @return the evaluator
+ */
+ public Evaluator<? extends ExprNode> getEvaluator()
+ {
+ return evaluator;
+ }
+
+
+ /**
+ * @param evaluator the evaluator to set
+ */
+ public void setEvaluator( Evaluator<? extends ExprNode> evaluator )
+ {
+ this.evaluator = evaluator;
+ }
+
+
+ /**
+ * @param aliasDerefMode the aliasDerefMode to set
+ */
+ public void setAliasDerefMode( AliasDerefMode aliasDerefMode )
+ {
+ this.aliasDerefMode = aliasDerefMode;
+ }
+
+
+ /**
+ * @return True if the alias is never dereferenced
+ */
+ public boolean isNeverDeref()
+ {
+ return aliasDerefMode == AliasDerefMode.NEVER_DEREF_ALIASES;
+ }
+
+
+ /**
+ * @return True if the alias is always dereferenced
+ */
+ public boolean isDerefAlways()
+ {
+ return aliasDerefMode == AliasDerefMode.DEREF_ALWAYS;
+ }
+
+
+ /**
+ * @return True if the alias is dereferenced while searching
+ */
+ public boolean isDerefInSearching()
+ {
+ return aliasDerefMode == AliasDerefMode.DEREF_IN_SEARCHING;
+ }
+
+
+ /**
+ * @return True if the alias is dereferenced while finding
+ */
+ public boolean isDerefFinding()
+ {
+ return aliasDerefMode == AliasDerefMode.DEREF_FINDING_BASE_OBJ;
+ }
+
+
+ /**
+ * @return the schemaManager
+ */
+ public SchemaManager getSchemaManager()
+ {
+ return schemaManager;
+ }
+
+
+ /**
+ * @param schemaManager the schemaManager to set
+ */
+ public void setSchemaManager( SchemaManager schemaManager )
+ {
+ this.schemaManager = schemaManager;
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "Search result : \n" );
+ sb.append( "Alias : " ).append( aliasDerefMode ).append( "\n" );
+ sb.append( "Evaluator : " ).append( evaluator ).append( "\n" );
+
+ if ( resultSet == null )
+ {
+ sb.append( "No UUID found" );
+ }
+ else
+ {
+ sb.append( '{' );
+ boolean isFirst = true;
+
+ try
+ {
+ while ( resultSet.next() )
+ {
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ sb.append( ", " );
+ }
+
+ sb.append( resultSet.get().getId() );
+ }
+
+ resultSet.beforeFirst();
+ }
+ catch ( Exception e )
+ {
+ // Nothing we can do...
+ }
+
+ sb.append( '}' );
+ }
+
+ return sb.toString();
+ }
+}
Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/SearchEngine.java Mon Sep 24 02:17:13 2012
@@ -20,13 +20,10 @@
package org.apache.directory.server.xdbm.search;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
import org.apache.directory.shared.ldap.model.constants.JndiPropertyConstants;
-import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.filter.ExprNode;
-import org.apache.directory.shared.ldap.model.message.AliasDerefMode;
-import org.apache.directory.shared.ldap.model.message.SearchScope;
-import org.apache.directory.shared.ldap.model.name.Dn;
-import org.apache.directory.server.xdbm.IndexCursor;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
/**
@@ -35,7 +32,7 @@ import org.apache.directory.server.xdbm.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
-public interface SearchEngine<E, ID>
+public interface SearchEngine
{
/**
* @todo put this in the right place
@@ -73,17 +70,16 @@ public interface SearchEngine<E, ID>
/**
- * Conducts a search on a database.
+ * Conducts a search on a database. It returns a set of UUID we found for the
+ * given filter.
*
- * @param base the search base
- * @param aliasDerefMode the alias dereferencing mode to use
- * @param filter the search filter AST root
- * @param scope the Scope
- * @return enumeration over SearchResults
+ * @param The SchemaManager instance
+ * @param searchContext the search context
+ * @return A set of UUID representing the full result, up to he sizeLimit
* @throws Exception if the search fails
*/
- IndexCursor<ID, E, ID> cursor( Dn base, AliasDerefMode aliasDerefMode, ExprNode filter,
- SearchScope scope ) throws Exception;
+ PartitionSearchResult computeResult( SchemaManager schemaManager, SearchOperationContext searchContext )
+ throws Exception;
/**
@@ -93,5 +89,5 @@ public interface SearchEngine<E, ID>
* @return true if the filter passes the entry, false otherwise
* @throws Exception if something goes wrong while accessing the db
*/
- Evaluator<? extends ExprNode, Entry, ID> evaluator( ExprNode filter ) throws Exception;
+ Evaluator<? extends ExprNode> evaluator( ExprNode filter ) throws Exception;
}
\ No newline at end of file
Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AllEntriesCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AllEntriesCursor.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AllEntriesCursor.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AllEntriesCursor.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,238 @@
+/*
+ * 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.xdbm.search.cursor;
+
+
+import org.apache.directory.server.core.partition.impl.btree.IndexCursorAdaptor;
+import org.apache.directory.server.xdbm.AbstractIndexCursor;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.Store;
+import org.apache.directory.shared.ldap.model.cursor.Cursor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Cursor over all entries in a partition which returns IndexEntries.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class AllEntriesCursor extends AbstractIndexCursor<String>
+{
+ /** A dedicated log for cursors */
+ private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
+ /** The index entry we use to return entries one by one. */
+ private IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
+
+ /** The cursor on the MsterTable index */
+ private final Cursor<IndexEntry<String, String>> wrapped;
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getUnsupportedMessage()
+ {
+ return UNSUPPORTED_MSG;
+ }
+
+
+ /**
+ * Creates a new instance of AllEntriesCursor
+ * @param store
+ * @throws Exception
+ */
+ public AllEntriesCursor( Store store ) throws Exception
+ {
+ LOG_CURSOR.debug( "Creating AllEntriesCursor {}", this );
+ // Uses the MasterTable
+ wrapped = new IndexCursorAdaptor( store.getMasterTable().cursor(), true );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void after( IndexEntry<String, String> indexEntry ) throws Exception
+ {
+ checkNotClosed( "after()" );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+
+ wrapped.afterLast();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean available()
+ {
+ return wrapped.available();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void before( IndexEntry<String, String> indexEntry ) throws Exception
+ {
+ checkNotClosed( "before()" );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+
+ wrapped.beforeFirst();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean first() throws Exception
+ {
+ checkNotClosed( "first()" );
+
+ return wrapped.first();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public IndexEntry<String, String> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+
+ // Create the returned IndexEntry, copying what we get from the wrapped cursor
+ // As we are using the MasterTable, we have to use the key as the
+ // ID and value
+ IndexEntry<?, String> wrappedEntry = wrapped.get();
+ indexEntry.setId( ( String ) wrappedEntry.getKey() );
+ indexEntry.setKey( ( String ) wrappedEntry.getKey() );
+ indexEntry.setEntry( null );
+
+ return indexEntry;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean last() throws Exception
+ {
+ checkNotClosed( "last()" );
+
+ return wrapped.last();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "next()" );
+
+ return wrapped.next();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "previous()" );
+
+ return wrapped.previous();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() throws Exception
+ {
+ LOG_CURSOR.debug( "Closing AllEntriesCursor {}", this );
+ wrapped.close();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close( Exception cause ) throws Exception
+ {
+ LOG_CURSOR.debug( "Closing AllEntriesCursor {}", this );
+ wrapped.close( cause );
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString( String tabs )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( tabs ).append( "AllEntriesCursor (" );
+
+ if ( available() )
+ {
+ sb.append( "available)" );
+ }
+ else
+ {
+ sb.append( "absent)" );
+ }
+
+ sb.append( " :\n" );
+
+ sb.append( wrapped.toString( tabs + " " ) );
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return toString( "" );
+ }
+}
Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AndCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AndCursor.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AndCursor.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/AndCursor.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,300 @@
+/*
+ * 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.xdbm.search.cursor;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.AbstractIndexCursor;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.search.Evaluator;
+import org.apache.directory.server.xdbm.search.impl.ScanCountComparator;
+import org.apache.directory.shared.ldap.model.cursor.Cursor;
+import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
+import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Cursor returning candidates satisfying a logical conjunction expression.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class AndCursor<V> extends AbstractIndexCursor<V>
+{
+ /** A dedicated log for cursors */
+ private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
+ /** The message for unsupported operations */
+ private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_707 );
+
+ /** */
+ private final Cursor<IndexEntry<V, String>> wrapped;
+
+ /** The evaluators used for the members of the And filter */
+ private final List<Evaluator<? extends ExprNode>> evaluators;
+
+
+ /**
+ * Creates an instance of a AndCursor. It wraps an index cursor and the list
+ * of evaluators associated with all the elements connected by the And.
+ *
+ * @param wrapped The encapsulated IndexCursor
+ * @param evaluators The list of evaluators associated wth the elements
+ */
+ public AndCursor( Cursor<IndexEntry<V, String>> wrapped,
+ List<Evaluator<? extends ExprNode>> evaluators )
+ {
+ LOG_CURSOR.debug( "Creating AndCursor {}", this );
+ this.wrapped = wrapped;
+ this.evaluators = optimize( evaluators );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getUnsupportedMessage()
+ {
+ return UNSUPPORTED_MSG;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ wrapped.beforeFirst();
+ setAvailable( false );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+ wrapped.afterLast();
+ setAvailable( false );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+
+ return next();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean last() throws Exception
+ {
+ afterLast();
+
+ return previous();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean previous() throws Exception
+ {
+ while ( wrapped.previous() )
+ {
+ checkNotClosed( "previous()" );
+
+ IndexEntry<V, String> candidate = wrapped.get();
+
+ if ( matches( candidate ) )
+ {
+ return setAvailable( true );
+ }
+ }
+
+ return setAvailable( false );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean next() throws Exception
+ {
+ while ( wrapped.next() )
+ {
+ checkNotClosed( "next()" );
+ IndexEntry<V, String> candidate = wrapped.get();
+
+ if ( matches( candidate ) )
+ {
+ return setAvailable( true );
+ }
+ }
+
+ return setAvailable( false );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public IndexEntry<V, String> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+
+ if ( available() )
+ {
+ return wrapped.get();
+ }
+
+ throw new InvalidCursorPositionException( I18n.err( I18n.ERR_708 ) );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws Exception
+ {
+ LOG_CURSOR.debug( "Closing AndCursor {}", this );
+ super.close();
+ wrapped.close();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close( Exception cause ) throws Exception
+ {
+ LOG_CURSOR.debug( "Closing AndCursor {}", this );
+ super.close( cause );
+ wrapped.close( cause );
+ }
+
+
+ /**
+ * Takes a set of Evaluators and copies then sorts them in a new list with
+ * increasing scan counts on their expression nodes. This is done to have
+ * the Evaluators with the least scan count which have the highest
+ * probability of rejecting a candidate first. That will increase the
+ * chance of shorting the checks on evaluators early so extra lookups and
+ * comparisons are avoided.
+ *
+ * @param unoptimized the unoptimized list of Evaluators
+ * @return optimized Evaluator list with increasing scan count ordering
+ */
+ private List<Evaluator<? extends ExprNode>> optimize(
+ List<Evaluator<? extends ExprNode>> unoptimized )
+ {
+ List<Evaluator<? extends ExprNode>> optimized = new ArrayList<Evaluator<? extends ExprNode>>(
+ unoptimized.size() );
+ optimized.addAll( unoptimized );
+
+ Collections.sort( optimized, new ScanCountComparator() );
+
+ return optimized;
+ }
+
+
+ /**
+ * Checks if the entry is a valid candidate by using the evaluators.
+ */
+ private boolean matches( IndexEntry<V, String> indexEntry ) throws Exception
+ {
+ for ( Evaluator<?> evaluator : evaluators )
+ {
+ if ( !evaluator.evaluate( indexEntry ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Dumps the evaluators
+ */
+ private String dumpEvaluators( String tabs )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ for ( Evaluator<? extends ExprNode> evaluator : evaluators )
+ {
+ sb.append( evaluator.toString( tabs + " >>" ) );
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString( String tabs )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( tabs ).append( "AndCursor (" );
+
+ if ( available() )
+ {
+ sb.append( "available) :\n" );
+ }
+ else
+ {
+ sb.append( "absent) :\n" );
+ }
+
+ if ( ( evaluators != null ) && ( evaluators.size() > 0 ) )
+ {
+ sb.append( dumpEvaluators( tabs ) );
+ }
+
+ sb.append( wrapped.toString( tabs + " " ) );
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return toString( "" );
+ }
+}
Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ApproximateCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ApproximateCursor.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ApproximateCursor.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ApproximateCursor.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,370 @@
+/*
+ * 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.xdbm.search.cursor;
+
+
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.AbstractIndexCursor;
+import org.apache.directory.server.xdbm.Index;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.Store;
+import org.apache.directory.server.xdbm.search.evaluator.ApproximateEvaluator;
+import org.apache.directory.shared.ldap.model.cursor.Cursor;
+import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
+import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.apache.directory.shared.ldap.model.entry.Value;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Cursor over entry candidates matching an approximate assertion filter.
+ * This Cursor really is a copy of EqualityCursor for now but later on
+ * approximate matching can be implemented and this can change. It operates
+ * in two modes. The first is when an index exists for the attribute the
+ * approximate assertion is built on. The second is when the user index for
+ * the assertion attribute does not exist. Different Cursors are used in each
+ * of these cases where the other remains null.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ApproximateCursor<V> extends AbstractIndexCursor<V>
+{
+ /** A dedicated log for cursors */
+ private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
+ /** The message for unsupported operations */
+ private static final String UNSUPPORTED_MSG = "ApproximateCursors only support positioning by element when a user index exists on the asserted attribute.";
+
+ /** An approximate evaluator for candidates */
+ private final ApproximateEvaluator<V> approximateEvaluator;
+
+ /** Cursor over attribute entry matching filter: set when index present */
+ private final Cursor<IndexEntry<V, String>> userIdxCursor;
+
+ /** NDN Cursor on all entries in (set when no index on user attribute) */
+ private final Cursor<IndexEntry<String, String>> uuidIdxCursor;
+
+
+ /**
+ * Creates a new instance of ApproximateCursor
+ * @param store The Store we want to build a cursor on
+ * @param approximateEvaluator The evaluator
+ * @throws Exception If the creation failed
+ */
+ @SuppressWarnings("unchecked")
+ public ApproximateCursor( Store store, ApproximateEvaluator<V> approximateEvaluator ) throws Exception
+ {
+ LOG_CURSOR.debug( "Creating ApproximateCursor {}", this );
+ this.approximateEvaluator = approximateEvaluator;
+
+ AttributeType attributeType = approximateEvaluator.getExpression().getAttributeType();
+ Value<V> value = approximateEvaluator.getExpression().getValue();
+
+ if ( store.hasIndexOn( attributeType ) )
+ {
+ Index<V, Entry, String> index = ( Index<V, Entry, String> ) store.getIndex( attributeType );
+ userIdxCursor = index.forwardCursor( value.getValue() );
+ uuidIdxCursor = null;
+ }
+ else
+ {
+ uuidIdxCursor = new AllEntriesCursor( store );
+ userIdxCursor = null;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getUnsupportedMessage()
+ {
+ return UNSUPPORTED_MSG;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean available()
+ {
+ if ( userIdxCursor != null )
+ {
+ return userIdxCursor.available();
+ }
+
+ return super.available();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void before( IndexEntry<V, String> element ) throws Exception
+ {
+ checkNotClosed( "before()" );
+
+ if ( userIdxCursor != null )
+ {
+ userIdxCursor.before( element );
+ }
+ else
+ {
+ super.before( element );
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void after( IndexEntry<V, String> element ) throws Exception
+ {
+ checkNotClosed( "after()" );
+
+ if ( userIdxCursor != null )
+ {
+ userIdxCursor.after( element );
+ }
+ else
+ {
+ super.after( element );
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ if ( userIdxCursor != null )
+ {
+ userIdxCursor.beforeFirst();
+ }
+ else
+ {
+ uuidIdxCursor.beforeFirst();
+ setAvailable( false );
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void afterLast() throws Exception
+ {
+ checkNotClosed( "afterLast()" );
+
+ if ( userIdxCursor != null )
+ {
+ userIdxCursor.afterLast();
+ }
+ else
+ {
+ uuidIdxCursor.afterLast();
+ setAvailable( false );
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+
+ return next();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean last() throws Exception
+ {
+ afterLast();
+
+ return previous();
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean previous() throws Exception
+ {
+ if ( userIdxCursor != null )
+ {
+ return userIdxCursor.previous();
+ }
+
+ while ( uuidIdxCursor.previous() )
+ {
+ checkNotClosed( "previous()" );
+ IndexEntry<?, String> candidate = uuidIdxCursor.get();
+
+ if ( approximateEvaluator.evaluate( candidate ) )
+ {
+ return setAvailable( true );
+ }
+ }
+
+ return setAvailable( false );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean next() throws Exception
+ {
+ if ( userIdxCursor != null )
+ {
+ return userIdxCursor.next();
+ }
+
+ while ( uuidIdxCursor.next() )
+ {
+ checkNotClosed( "next()" );
+ IndexEntry<?, String> candidate = uuidIdxCursor.get();
+
+ if ( approximateEvaluator.evaluate( candidate ) )
+ {
+ return setAvailable( true );
+ }
+ }
+
+ return setAvailable( false );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public IndexEntry<V, String> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+
+ if ( userIdxCursor != null )
+ {
+ return userIdxCursor.get();
+ }
+
+ if ( available() )
+ {
+ return ( IndexEntry<V, String> ) uuidIdxCursor.get();
+ }
+
+ throw new InvalidCursorPositionException( I18n.err( I18n.ERR_708 ) );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws Exception
+ {
+ LOG_CURSOR.debug( "Closing ApproximateCursor {}", this );
+ super.close();
+
+ if ( userIdxCursor != null )
+ {
+ userIdxCursor.close();
+ }
+ else
+ {
+ uuidIdxCursor.close();
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close( Exception cause ) throws Exception
+ {
+ LOG_CURSOR.debug( "Closing ApproximateCursor {}", this );
+ super.close( cause );
+
+ if ( userIdxCursor != null )
+ {
+ userIdxCursor.close( cause );
+ }
+ else
+ {
+ uuidIdxCursor.close( cause );
+ }
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString( String tabs )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( tabs ).append( "ApproximateCursor (" );
+
+ if ( available() )
+ {
+ sb.append( "available)" );
+ }
+ else
+ {
+ sb.append( "absent)" );
+ }
+
+ sb.append( " :\n" );
+
+ sb.append( tabs + " >>" ).append( approximateEvaluator ).append( '\n' );
+
+ if ( userIdxCursor != null )
+ {
+ sb.append( tabs + " <user>\n" );
+ sb.append( userIdxCursor.toString( tabs + " " ) );
+ }
+
+ if ( uuidIdxCursor != null )
+ {
+ sb.append( tabs + " <uuid>\n" );
+ sb.append( uuidIdxCursor.toString( tabs + " " ) );
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return toString( "" );
+ }
+}
\ No newline at end of file
Added: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ChildrenCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ChildrenCursor.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ChildrenCursor.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/cursor/ChildrenCursor.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,218 @@
+/*
+ * 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.xdbm.search.cursor;
+
+
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.AbstractIndexCursor;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.ParentIdAndRdn;
+import org.apache.directory.server.xdbm.Store;
+import org.apache.directory.shared.ldap.model.cursor.Cursor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Cursor over entries satisfying one level scope constraints with alias
+ * dereferencing considerations when enabled during search.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class ChildrenCursor extends AbstractIndexCursor<String>
+{
+ /** A dedicated log for cursors */
+ private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
+ /** Error message for unsupported operations */
+ private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_719 );
+
+ /** A Cursor over the entries in the scope of the search base */
+ private final Cursor<IndexEntry<ParentIdAndRdn, String>> cursor;
+
+ /** The Parent ID */
+ private String parentId;
+
+ /** The prefetched element */
+ private IndexEntry<String, String> prefetched;
+
+
+ /**
+ * Creates a Cursor over entries satisfying one level scope criteria.
+ *
+ * @param db the entry store
+ * @param evaluator an IndexEntry (candidate) evaluator
+ * @throws Exception on db access failures
+ */
+ public ChildrenCursor( Store db, String parentId, Cursor<IndexEntry<ParentIdAndRdn, String>> cursor )
+ throws Exception
+ {
+ this.parentId = parentId;
+ this.cursor = cursor;
+ LOG_CURSOR.debug( "Creating ChildrenCursor {}", this );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected String getUnsupportedMessage()
+ {
+ return UNSUPPORTED_MSG;
+ }
+
+
+ public void beforeFirst() throws Exception
+ {
+ checkNotClosed( "beforeFirst()" );
+ setAvailable( false );
+ }
+
+
+ public void afterLast() throws Exception
+ {
+ throw new UnsupportedOperationException( getUnsupportedMessage() );
+ }
+
+
+ public boolean first() throws Exception
+ {
+ beforeFirst();
+
+ return next();
+ }
+
+
+ public boolean last() throws Exception
+ {
+ throw new UnsupportedOperationException( getUnsupportedMessage() );
+ }
+
+
+ public boolean previous() throws Exception
+ {
+ checkNotClosed( "next()" );
+
+ boolean hasPrevious = cursor.previous();
+
+ if ( hasPrevious )
+ {
+ IndexEntry entry = cursor.get();
+
+ if ( ( ( ParentIdAndRdn ) entry.getTuple().getKey() ).getParentId().equals( parentId ) )
+ {
+ prefetched = entry;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean next() throws Exception
+ {
+ checkNotClosed( "next()" );
+
+ boolean hasNext = cursor.next();
+
+ if ( hasNext )
+ {
+ IndexEntry cursorEntry = cursor.get();
+ IndexEntry<String, String> entry = new IndexEntry();
+ entry.setId( ( String ) cursorEntry.getId() );
+ entry.setKey( ( ( ParentIdAndRdn ) cursorEntry.getTuple().getKey() ).getParentId() );
+
+ if ( entry.getKey().equals( parentId ) )
+ {
+ prefetched = entry;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ public IndexEntry<String, String> get() throws Exception
+ {
+ checkNotClosed( "get()" );
+
+ return prefetched;
+ }
+
+
+ @Override
+ public void close() throws Exception
+ {
+ LOG_CURSOR.debug( "Closing ChildrenCursor {}", this );
+ cursor.close();
+
+ super.close();
+ }
+
+
+ @Override
+ public void close( Exception cause ) throws Exception
+ {
+ LOG_CURSOR.debug( "Closing ChildrenCursor {}", this );
+ cursor.close( cause );
+
+ super.close( cause );
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString( String tabs )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( tabs ).append( "ChildrenCursor (" );
+
+ if ( available() )
+ {
+ sb.append( "available)" );
+ }
+ else
+ {
+ sb.append( "absent)" );
+ }
+
+ sb.append( "#parent<" ).append( parentId ).append( "> :\n" );
+
+ sb.append( cursor.toString( tabs + " " ) );
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return toString( "" );
+ }
+}
\ No newline at end of file
|