directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1389184 [7/13] - in /directory/apacheds/trunk: core-annotations/src/main/java/org/apache/directory/server/core/factory/ core-api/src/main/java/org/apache/directory/server/core/api/ core-api/src/main/java/org/apache/directory/server/core/ap...
Date Mon, 24 Sep 2012 02:17:20 GMT
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



Mime
View raw message