You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2012/09/24 04:17:20 UTC

svn commit: r1389184 [10/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/a...

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/CursorBuilder.java Mon Sep 24 02:17:13 2012
@@ -20,20 +20,43 @@
 package org.apache.directory.server.xdbm.search.impl;
 
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
 
+import org.apache.directory.server.core.api.partition.Partition;
 import org.apache.directory.server.i18n.I18n;
-import org.apache.directory.server.xdbm.IndexCursor;
+import org.apache.directory.server.xdbm.Index;
+import org.apache.directory.server.xdbm.IndexEntry;
+import org.apache.directory.server.xdbm.ParentIdAndRdn;
+import org.apache.directory.server.xdbm.SingletonIndexCursor;
 import org.apache.directory.server.xdbm.Store;
-import org.apache.directory.server.xdbm.search.Evaluator;
+import org.apache.directory.server.xdbm.search.PartitionSearchResult;
+import org.apache.directory.server.xdbm.search.cursor.ApproximateCursor;
+import org.apache.directory.server.xdbm.search.cursor.ChildrenCursor;
+import org.apache.directory.server.xdbm.search.cursor.DescendantCursor;
+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.entry.Entry;
+import org.apache.directory.shared.ldap.model.entry.Value;
 import org.apache.directory.shared.ldap.model.filter.AndNode;
+import org.apache.directory.shared.ldap.model.filter.ApproximateNode;
+import org.apache.directory.shared.ldap.model.filter.EqualityNode;
 import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.filter.GreaterEqNode;
+import org.apache.directory.shared.ldap.model.filter.LessEqNode;
 import org.apache.directory.shared.ldap.model.filter.NotNode;
 import org.apache.directory.shared.ldap.model.filter.OrNode;
+import org.apache.directory.shared.ldap.model.filter.PresenceNode;
 import org.apache.directory.shared.ldap.model.filter.ScopeNode;
+import org.apache.directory.shared.ldap.model.filter.SubstringNode;
 import org.apache.directory.shared.ldap.model.message.SearchScope;
+import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.name.Rdn;
+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.Normalizer;
+import org.apache.directory.shared.ldap.model.schema.normalizers.NoOpNormalizer;
 import org.apache.directory.shared.util.exception.NotImplementedException;
 
 
@@ -42,13 +65,13 @@ import org.apache.directory.shared.util.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class CursorBuilder<ID extends Comparable<ID>>
+public class CursorBuilder
 {
     /** The database used by this builder */
-    private Store<Entry, ID> db = null;
+    private Store db = null;
 
     /** Evaluator dependency on a EvaluatorBuilder */
-    private EvaluatorBuilder<ID> evaluatorBuilder;
+    private EvaluatorBuilder evaluatorBuilder;
 
 
     /**
@@ -57,59 +80,65 @@ public class CursorBuilder<ID extends Co
      * @param db database used by this enumerator
      * @param evaluatorBuilder the evaluator builder
      */
-    public CursorBuilder( Store<Entry, ID> db, EvaluatorBuilder<ID> evaluatorBuilder )
+    public CursorBuilder( Store db, EvaluatorBuilder evaluatorBuilder )
     {
         this.db = db;
         this.evaluatorBuilder = evaluatorBuilder;
     }
 
 
-    public <T> IndexCursor<?, Entry, ID> build( ExprNode node ) throws Exception
+    public <T> long build( ExprNode node, PartitionSearchResult searchResult ) throws Exception
     {
+        Object count = node.get( "count" );
+
+        if ( ( count != null ) && ( ( Long ) count ) == 0L )
+        {
+            return 0;
+        }
+
         switch ( node.getAssertionType() )
         {
         /* ---------- LEAF NODE HANDLING ---------- */
 
             case APPROXIMATE:
-                return new ApproximateCursor<T, ID>( db, ( ApproximateEvaluator<T, ID> ) evaluatorBuilder.build( node ) );
+                return computeApproximate( ( ApproximateNode<T> ) node, searchResult );
 
             case EQUALITY:
-                return new EqualityCursor<T, ID>( db, ( EqualityEvaluator<T, ID> ) evaluatorBuilder.build( node ) );
+                return computeEquality( ( EqualityNode<T> ) node, searchResult );
 
             case GREATEREQ:
-                return new GreaterEqCursor<T, ID>( db, ( GreaterEqEvaluator<T, ID> ) evaluatorBuilder.build( node ) );
+                return computeGreaterEq( ( GreaterEqNode<T> ) node, searchResult );
 
             case LESSEQ:
-                return new LessEqCursor<T, ID>( db, ( LessEqEvaluator<T, ID> ) evaluatorBuilder.build( node ) );
+                return computeLessEq( ( LessEqNode<T> ) node, searchResult );
 
             case PRESENCE:
-                return new PresenceCursor<ID>( db, ( PresenceEvaluator<ID> ) evaluatorBuilder.build( node ) );
+                return computePresence( ( PresenceNode ) node, searchResult );
 
             case SCOPE:
                 if ( ( ( ScopeNode ) node ).getScope() == SearchScope.ONELEVEL )
                 {
-                    return new OneLevelScopeCursor<ID>( db,
-                        ( OneLevelScopeEvaluator<Entry, ID> ) evaluatorBuilder.build( node ) );
+                    return computeOneLevelScope( ( ScopeNode ) node, searchResult );
                 }
                 else
                 {
-                    return new SubtreeScopeCursor<ID>( db, ( SubtreeScopeEvaluator<Entry, ID> ) evaluatorBuilder
-                        .build( node ) );
+                    return computeSubLevelScope( ( ScopeNode ) node, searchResult );
                 }
 
             case SUBSTRING:
-                return new SubstringCursor<ID>( db, ( SubstringEvaluator<ID> ) evaluatorBuilder.build( node ) );
+                return computeSubstring( ( SubstringNode ) node, searchResult );
 
                 /* ---------- LOGICAL OPERATORS ---------- */
 
             case AND:
-                return buildAndCursor( ( AndNode ) node );
+                return computeAnd( ( AndNode ) node, searchResult );
 
             case NOT:
-                return new NotCursor<ID, ID>( db, evaluatorBuilder.build( ( ( NotNode ) node ).getFirstChild() ) );
+                // Always return infinite, except if the resulting eva 
+                return computeNot( ( NotNode ) node, searchResult );
 
             case OR:
-                return buildOrCursor( ( OrNode ) node );
+                return computeOr( ( OrNode ) node, searchResult );
 
                 /* ----------  NOT IMPLEMENTED  ---------- */
 
@@ -124,28 +153,544 @@ public class CursorBuilder<ID extends Co
 
 
     /**
+     * Computes the set of candidates for an Approximate filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+
+    private <T> long computeApproximate( ApproximateNode<T> node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        ApproximateCursor<T> cursor = new ApproximateCursor<T>( db,
+            ( ApproximateEvaluator<T> ) evaluatorBuilder
+                .build( node ) );
+
+        int nbResults = 0;
+        Set<String> uuidSet = searchResult.getCandidateSet();
+
+        while ( cursor.next() )
+        {
+            IndexEntry<T, String> indexEntry = cursor.get();
+
+            String uuid = indexEntry.getId();
+
+            if ( !uuidSet.contains( uuid ) )
+            {
+                uuidSet.add( uuid );
+                nbResults++;
+            }
+        }
+
+        cursor.close();
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for an Equality filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private <T> long computeEquality( EqualityNode<T> node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        AttributeType attributeType = node.getAttributeType();
+        Value<T> value = node.getValue();
+        int nbResults = 0;
+
+        // Fetch all the UUIDs if we have an index
+        if ( db.hasIndexOn( attributeType ) )
+        {
+            // Get the cursor using the index
+            Index<T, Entry, String> userIndex = ( Index<T, Entry, String> ) db.getIndex( attributeType );
+            Cursor<IndexEntry<T, String>> userIdxCursor = userIndex.forwardCursor( value.getValue() );
+            Set<String> uuidSet = searchResult.getCandidateSet();
+
+            // And loop on it
+            while ( userIdxCursor.next() )
+            {
+                IndexEntry<T, String> indexEntry = userIdxCursor.get();
+
+                String uuid = indexEntry.getId();
+
+                if ( !uuidSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    uuidSet.add( uuid );
+                    nbResults++;
+                }
+            }
+
+            userIdxCursor.close();
+        }
+        else
+        {
+            // No index, we will have to do a full scan
+            return Long.MAX_VALUE;
+        }
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for an GreateEq filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private <T> long computeGreaterEq( GreaterEqNode<T> node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        AttributeType attributeType = node.getAttributeType();
+        Value<T> value = node.getValue();
+        int nbResults = 0;
+
+        // Fetch all the UUIDs if we have an index
+        if ( db.hasIndexOn( attributeType ) )
+        {
+            // Get the cursor using the index
+            Index<T, Entry, String> userIndex = ( Index<T, Entry, String> ) db.getIndex( attributeType );
+            Cursor<IndexEntry<T, String>> userIdxCursor = userIndex.forwardCursor();
+
+            // Position the index on the element we should start from
+            IndexEntry<T, String> indexEntry = new IndexEntry<T, String>();
+            indexEntry.setKey( value.getValue() );
+
+            userIdxCursor.before( indexEntry );
+            Set<String> uuidSet = searchResult.getCandidateSet();
+
+            // And loop on it
+            while ( userIdxCursor.next() )
+            {
+                indexEntry = userIdxCursor.get();
+
+                String uuid = indexEntry.getId();
+
+                if ( !uuidSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    uuidSet.add( uuid );
+                    nbResults++;
+                }
+            }
+
+            userIdxCursor.close();
+        }
+        else
+        {
+            // No index, we will have to do a full scan
+            return Long.MAX_VALUE;
+        }
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for an LessEq filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private <T> long computeLessEq( LessEqNode<T> node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        AttributeType attributeType = node.getAttributeType();
+        Value<T> value = node.getValue();
+        int nbResults = 0;
+
+        // Fetch all the UUIDs if we have an index
+        if ( db.hasIndexOn( attributeType ) )
+        {
+            // Get the cursor using the index
+            Index<T, Entry, String> userIndex = ( Index<T, Entry, String> ) db.getIndex( attributeType );
+            Cursor<IndexEntry<T, String>> userIdxCursor = userIndex.forwardCursor();
+
+            // Position the index on the element we should start from
+            IndexEntry<T, String> indexEntry = new IndexEntry<T, String>();
+            indexEntry.setKey( value.getValue() );
+
+            userIdxCursor.after( indexEntry );
+            Set<String> uuidSet = searchResult.getCandidateSet();
+
+            // And loop on it
+            while ( userIdxCursor.previous() )
+            {
+                indexEntry = userIdxCursor.get();
+
+                String uuid = indexEntry.getId();
+
+                if ( !uuidSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    uuidSet.add( uuid );
+                    nbResults++;
+                }
+            }
+
+            userIdxCursor.close();
+        }
+        else
+        {
+            // No index, we will have to do a full scan
+            return Long.MAX_VALUE;
+        }
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for a Presence filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private <T> long computePresence( PresenceNode node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        AttributeType attributeType = node.getAttributeType();
+        int nbResults = 0;
+
+        // Fetch all the UUIDs if we have an index
+        if ( db.hasIndexOn( attributeType ) )
+        {
+            // Get the cursor using the index
+            Cursor<IndexEntry<String, String>> presenceCursor = db.getPresenceIndex().forwardCursor(
+                attributeType.getOid() );
+
+            // Position the index on the element we should start from
+            IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
+            Set<String> uuidSet = searchResult.getCandidateSet();
+
+            // And loop on it
+            while ( presenceCursor.next() )
+            {
+                indexEntry = presenceCursor.get();
+
+                String uuid = indexEntry.getId();
+
+                if ( !uuidSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    uuidSet.add( uuid );
+                    nbResults++;
+                }
+            }
+
+            presenceCursor.close();
+        }
+        else
+        {
+            // No index, we will have to do a full scan
+            return Long.MAX_VALUE;
+        }
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for a OneLevelScope filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private long computeOneLevelScope( ScopeNode node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        int nbResults = 0;
+
+        // We use the RdnIndex to get all the entries from a starting point
+        // and below up to the number of children
+        Cursor<IndexEntry<ParentIdAndRdn, String>> rdnCursor = db.getRdnIndex().forwardCursor();
+
+        IndexEntry<ParentIdAndRdn, String> startingPos = new IndexEntry<ParentIdAndRdn, String>();
+        startingPos.setKey( new ParentIdAndRdn( node.getBaseId(), ( Rdn[] ) null ) );
+        rdnCursor.before( startingPos );
+
+        Cursor<IndexEntry<String, String>> scopeCursor = new ChildrenCursor( db, node.getBaseId(), rdnCursor );
+        Set<String> candidateSet = searchResult.getCandidateSet();
+
+        // Fetch all the UUIDs if we have an index
+        // And loop on it
+        while ( scopeCursor.next() )
+        {
+            IndexEntry<String, String> indexEntry = scopeCursor.get();
+
+            String uuid = indexEntry.getId();
+
+            // If the entry is an alias, and we asked for it to be dereferenced,
+            // we will dereference the alias
+            if ( searchResult.isDerefAlways() || searchResult.isDerefInSearching() )
+            {
+                String aliasedDn = db.getAliasIndex().reverseLookup( uuid );
+
+                if ( aliasedDn != null )
+                {
+                    String aliasedId = db.getEntryId( new Dn( searchResult.getSchemaManager(), aliasedDn ) );
+
+                    // This is an alias. Add it to the set of candidates to process, if it's not already
+                    // present in the candidate set 
+                    if ( !candidateSet.contains( aliasedId ) )
+                    {
+                        candidateSet.add( aliasedId );
+                        nbResults++;
+                    }
+                }
+                else
+                {
+                    // This is not an alias
+                    if ( !candidateSet.contains( uuid ) )
+                    {
+                        // The UUID is not present in the Set, we add it
+                        candidateSet.add( uuid );
+                        nbResults++;
+                    }
+                }
+            }
+            else
+            {
+                if ( !candidateSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    candidateSet.add( uuid );
+                    nbResults++;
+                }
+            }
+        }
+
+        scopeCursor.close();
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for a SubLevelScope filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private long computeSubLevelScope( ScopeNode node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        // If we are searching from the partition DN, better get out.
+        String contextEntryId = db.getEntryId( ( ( Partition ) db ).getSuffixDn() );
+
+        if ( node.getBaseId() == contextEntryId )
+        {
+            return Long.MAX_VALUE;
+        }
+
+        int nbResults = 0;
+
+        // We use the RdnIndex to get all the entries from a starting point
+        // and below up to the number of descendant
+        String baseId = node.getBaseId();
+        ParentIdAndRdn parentIdAndRdn = db.getRdnIndex().reverseLookup( baseId );
+        IndexEntry<ParentIdAndRdn, String> startingPos = new IndexEntry<ParentIdAndRdn, String>();
+
+        startingPos.setKey( parentIdAndRdn );
+        startingPos.setId( baseId );
+
+        Cursor<IndexEntry<ParentIdAndRdn, String>> rdnCursor = new SingletonIndexCursor<ParentIdAndRdn>(
+            startingPos );
+        String parentId = parentIdAndRdn.getParentId();
+
+        Cursor<IndexEntry<String, String>> scopeCursor = new DescendantCursor( db, baseId, parentId, rdnCursor );
+        Set<String> candidateSet = searchResult.getCandidateSet();
+
+        // Fetch all the UUIDs if we have an index
+        // And loop on it
+        while ( scopeCursor.next() )
+        {
+            IndexEntry<String, String> indexEntry = scopeCursor.get();
+
+            String uuid = indexEntry.getId();
+
+            // If the entry is an alias, and we asked for it to be dereferenced,
+            // we will dereference the alias
+            if ( searchResult.isDerefAlways() || searchResult.isDerefInSearching() )
+            {
+                String aliasedDn = db.getAliasIndex().reverseLookup( uuid );
+
+                if ( aliasedDn != null )
+                {
+                    String aliasedId = db.getEntryId( new Dn( searchResult.getSchemaManager(), aliasedDn ) );
+
+                    // This is an alias. Add it to the set of candidates to process, if it's not already
+                    // present in the candidate set 
+                    if ( !candidateSet.contains( aliasedId ) )
+                    {
+                        candidateSet.add( aliasedId );
+                        nbResults++;
+
+                        ScopeNode newScopeNode = new ScopeNode(
+                            node.getDerefAliases(),
+                            new Dn( searchResult.getSchemaManager(), aliasedDn ),
+                            aliasedId,
+                            node.getScope() );
+
+                        nbResults += computeSubLevelScope( newScopeNode, searchResult );
+                    }
+                }
+                else
+                {
+                    // This is not an alias
+                    if ( !candidateSet.contains( uuid ) )
+                    {
+                        // The UUID is not present in the Set, we add it
+                        candidateSet.add( uuid );
+                        nbResults++;
+                    }
+                }
+            }
+            else
+            {
+                if ( !candidateSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    candidateSet.add( uuid );
+                    nbResults++;
+                }
+            }
+        }
+
+        scopeCursor.close();
+
+        return nbResults;
+    }
+
+
+    /**
+     * Computes the set of candidates for an Substring filter. We will feed the set only if
+     * we have an index for the AT.
+     */
+    private long computeSubstring( SubstringNode node, PartitionSearchResult searchResult )
+        throws Exception
+    {
+        AttributeType attributeType = node.getAttributeType();
+
+        // Fetch all the UUIDs if we have an index
+        if ( db.hasIndexOn( attributeType ) )
+        {
+            Index<String, Entry, String> userIndex = ( ( Index<String, Entry, String> ) db.getIndex( attributeType ) );
+            Cursor<IndexEntry<String, String>> cursor = userIndex.forwardCursor();
+
+            // Position the index on the element we should start from
+            IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
+            indexEntry.setKey( node.getInitial() );
+
+            cursor.before( indexEntry );
+            int nbResults = 0;
+
+            MatchingRule rule = attributeType.getSubstring();
+
+            if ( rule == null )
+            {
+                rule = attributeType.getEquality();
+            }
+
+            Normalizer normalizer;
+            Pattern regexp;
+
+            if ( rule != null )
+            {
+                normalizer = rule.getNormalizer();
+            }
+            else
+            {
+                normalizer = new NoOpNormalizer( attributeType.getSyntaxOid() );
+            }
+
+            // compile the regular expression to search for a matching attribute
+            // if the attributeType is humanReadable
+            if ( attributeType.getSyntax().isHumanReadable() )
+            {
+                regexp = node.getRegex( normalizer );
+            }
+            else
+            {
+                regexp = null;
+            }
+
+            Set<String> uuidSet = searchResult.getCandidateSet();
+
+            // And loop on it
+            while ( cursor.next() )
+            {
+                indexEntry = cursor.get();
+
+                String key = indexEntry.getKey();
+
+                if ( !regexp.matcher( key ).matches() )
+                {
+                    cursor.close();
+
+                    return nbResults;
+                }
+
+                String uuid = indexEntry.getId();
+
+                if ( !uuidSet.contains( uuid ) )
+                {
+                    // The UUID is not present in the Set, we add it
+                    uuidSet.add( uuid );
+                    nbResults++;
+                }
+            }
+
+            cursor.close();
+
+            return nbResults;
+        }
+        else
+        {
+            // No index, we will have to do a full scan
+            return Long.MAX_VALUE;
+        }
+    }
+
+
+    /**
      * Creates a OrCursor over a disjunction expression branch node.
      *
      * @param node the disjunction expression branch node
      * @return Cursor over candidates satisfying disjunction expression
      * @throws Exception on db access failures
      */
-    private IndexCursor<?, Entry, ID> buildOrCursor( OrNode node ) throws Exception
+    private <T> long computeOr( OrNode node, PartitionSearchResult searchResult ) throws Exception
     {
         List<ExprNode> children = node.getChildren();
-        List<IndexCursor<?, Entry, ID>> childCursors = new ArrayList<IndexCursor<?, Entry, ID>>(
-            children.size() );
-        List<Evaluator<? extends ExprNode, Entry, ID>> childEvaluators = new ArrayList<Evaluator<? extends ExprNode, Entry, ID>>(
-            children.size() );
+
+        long nbOrResults = 0;
 
         // Recursively create Cursors and Evaluators for each child expression node
         for ( ExprNode child : children )
         {
-            childCursors.add( build( child ) );
-            childEvaluators.add( evaluatorBuilder.build( child ) );
+            Object count = child.get( "count" );
+
+            if ( ( count != null ) && ( ( Long ) count == 0L ) )
+            {
+                long countLong = ( Long ) count;
+
+                if ( countLong == 0 )
+                {
+                    // We can skip the cursor, it will not return any candidate
+                    continue;
+                }
+                else if ( countLong == Long.MAX_VALUE )
+                {
+                    // We can stop here, we will anyway do a full scan
+                    return countLong;
+                }
+            }
+
+            long nbResults = build( child, searchResult );
+
+            if ( nbResults == Long.MAX_VALUE )
+            {
+                // We can stop here, we will anyway do a full scan
+                return nbResults;
+            }
+            else
+            {
+                nbOrResults += nbResults;
+            }
         }
 
-        return new OrCursor( childCursors, childEvaluators );
+        return nbOrResults;
     }
 
 
@@ -156,7 +701,7 @@ public class CursorBuilder<ID extends Co
      * @return Cursor over the conjunction expression
      * @throws Exception on db access failures
      */
-    private IndexCursor<?, Entry, ID> buildAndCursor( AndNode node ) throws Exception
+    private long computeAnd( AndNode node, PartitionSearchResult searchResult ) throws Exception
     {
         int minIndex = 0;
         long minValue = Long.MAX_VALUE;
@@ -165,7 +710,7 @@ public class CursorBuilder<ID extends Co
         /*
          * We scan the child nodes of a branch node searching for the child
          * expression node with the smallest scan count.  This is the child
-         * we will use for iteration by creating a Cursor over its expression.
+         * we will use for iteration
          */
         final List<ExprNode> children = node.getChildren();
 
@@ -180,32 +725,55 @@ public class CursorBuilder<ID extends Co
             }
 
             value = ( Long ) count;
-            minValue = Math.min( minValue, value );
 
-            if ( minValue == value )
+            if ( value == 0L )
+            {
+                // No need to go any further : we won't have matching candidates anyway
+                return 0L;
+            }
+
+            if ( value < minValue )
             {
+                minValue = value;
                 minIndex = i;
             }
         }
 
-        // Once found we build the child Evaluators minus the one for the minChild
+        // Once found we return the number of candidates for this child
         ExprNode minChild = children.get( minIndex );
-        List<Evaluator<? extends ExprNode, Entry, ID>> childEvaluators = new ArrayList<Evaluator<? extends ExprNode, Entry, ID>>(
-            children.size() - 1 );
+        long nbResults = build( minChild, searchResult );
+
+        return nbResults;
+    }
 
-        for ( ExprNode child : children )
-        {
-            if ( child == minChild )
-            {
-                continue;
-            }
 
-            childEvaluators.add( evaluatorBuilder.build( child ) );
+    /**
+     * Creates an AndCursor over a conjunction expression branch node.
+     *
+     * @param node a conjunction expression branch node
+     * @return Cursor over the conjunction expression
+     * @throws Exception on db access failures
+     */
+    private long computeNot( NotNode node, PartitionSearchResult searchResult ) throws Exception
+    {
+        final List<ExprNode> children = node.getChildren();
+
+        ExprNode child = children.get( 0 );
+        Object count = child.get( "count" );
+
+        if ( count == null )
+        {
+            return Long.MAX_VALUE;
         }
 
-        // Do recursive call to build min child Cursor then create AndCursor
-        IndexCursor<?, Entry, ID> childCursor = build( minChild );
+        long value = ( Long ) count;
+
+        if ( value == Long.MAX_VALUE )
+        {
+            // No need to go any further : we won't have matching candidates anyway
+            return 0L;
+        }
 
-        return new AndCursor( childCursor, childEvaluators );
+        return Long.MAX_VALUE;
     }
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultOptimizer.java Mon Sep 24 02:17:13 2012
@@ -27,6 +27,8 @@ import org.apache.directory.server.i18n.
 import org.apache.directory.server.xdbm.Index;
 import org.apache.directory.server.xdbm.Store;
 import org.apache.directory.server.xdbm.search.Optimizer;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.filter.AndNode;
 import org.apache.directory.shared.ldap.model.filter.ApproximateNode;
 import org.apache.directory.shared.ldap.model.filter.AssertionNode;
@@ -50,11 +52,11 @@ import org.apache.directory.shared.ldap.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class DefaultOptimizer<E, ID extends Comparable<ID>> implements Optimizer
+public class DefaultOptimizer<E> implements Optimizer
 {
     /** the database this optimizer operates on */
-    private final Store<E, ID> db;
-    private ID contextEntryId;
+    private final Store db;
+    private String contextEntryId;
 
 
     /**
@@ -62,7 +64,7 @@ public class DefaultOptimizer<E, ID exte
      *
      * @param db the database this optimizer works for.
      */
-    public DefaultOptimizer( Store<E, ID> db ) throws Exception
+    public DefaultOptimizer( Store db ) throws Exception
     {
         this.db = db;
     }
@@ -70,7 +72,7 @@ public class DefaultOptimizer<E, ID exte
 
     // This will suppress PMD.EmptyCatchBlock warnings in this method
     @SuppressWarnings("PMD.EmptyCatchBlock")
-    private ID getContextEntryId() throws Exception
+    private String getContextEntryId() throws Exception
     {
         if ( contextEntryId == null )
         {
@@ -86,7 +88,7 @@ public class DefaultOptimizer<E, ID exte
 
         if ( contextEntryId == null )
         {
-            return db.getDefaultId();
+            return Partition.DEFAULT_ID;
         }
 
         return contextEntryId;
@@ -122,7 +124,7 @@ public class DefaultOptimizer<E, ID exte
 
         if ( node instanceof ScopeNode )
         {
-            count = getScopeScan( ( ScopeNode<ID> ) node );
+            count = getScopeScan( ( ScopeNode ) node );
         }
         else if ( node instanceof AssertionNode )
         {
@@ -210,7 +212,7 @@ public class DefaultOptimizer<E, ID exte
         }
 
         node.set( "count", count );
-        
+
         return count;
     }
 
@@ -278,7 +280,8 @@ public class DefaultOptimizer<E, ID exte
     {
         if ( db.hasIndexOn( node.getAttributeType() ) )
         {
-            Index<V, E, ID> idx = ( Index<V, E, ID> ) db.getIndex( node.getAttributeType() );
+            Index<V, E, String> idx = ( Index<V, E, String> ) db.getIndex( node.getAttributeType() );
+
             return idx.count( node.getValue().getValue() );
         }
 
@@ -301,7 +304,7 @@ public class DefaultOptimizer<E, ID exte
     {
         if ( db.hasIndexOn( node.getAttributeType() ) )
         {
-            Index<V, E, ID> idx = ( Index<V, E, ID> ) db.getIndex( node.getAttributeType() );
+            Index<V, E, String> idx = ( Index<V, E, String> ) db.getIndex( node.getAttributeType() );
             if ( isGreaterThan )
             {
                 return idx.greaterThanCount( node.getValue().getValue() );
@@ -350,12 +353,13 @@ public class DefaultOptimizer<E, ID exte
     {
         if ( db.hasUserIndexOn( node.getAttributeType() ) )
         {
-            Index<String, E, ID> idx = db.getPresenceIndex();
+            Index<String, Entry, String> idx = db.getPresenceIndex();
             return idx.count( node.getAttributeType().getOid() );
         }
-        else if ( db.hasSystemIndexOn( node.getAttributeType() ) )
+        else if ( db.hasSystemIndexOn( node.getAttributeType() )
+            || ( node.getAttributeType().getOid() == SchemaConstants.ENTRY_UUID_AT_OID ) )
         {
-            // the system indices (objectClass, entryUUID, entryCSN) are maintained for
+            // the system indices (objectClass, entryUUID and entryCSN) are maintained for
             // each entry, so we could just return the database count
             return db.count();
         }
@@ -371,10 +375,10 @@ public class DefaultOptimizer<E, ID exte
      * @return the scan count for scope
      * @throws Exception if any errors result
      */
-    private long getScopeScan( ScopeNode<ID> node ) throws Exception
+    private long getScopeScan( ScopeNode node ) throws Exception
     {
-        ID id = node.getBaseId();
-        
+        String id = node.getBaseId();
+
         switch ( node.getScope() )
         {
             case OBJECT:

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/DefaultSearchEngine.java Mon Sep 24 02:17:13 2012
@@ -20,17 +20,20 @@
 package org.apache.directory.server.xdbm.search.impl;
 
 
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 import org.apache.directory.server.core.api.partition.Partition;
+import org.apache.directory.server.core.partition.impl.btree.IndexCursorAdaptor;
 import org.apache.directory.server.i18n.I18n;
-import org.apache.directory.server.xdbm.EmptyIndexCursor;
-import org.apache.directory.server.xdbm.ForwardIndexEntry;
-import org.apache.directory.server.xdbm.IndexCursor;
 import org.apache.directory.server.xdbm.IndexEntry;
-import org.apache.directory.server.xdbm.SingletonIndexCursor;
 import org.apache.directory.server.xdbm.Store;
 import org.apache.directory.server.xdbm.search.Evaluator;
 import org.apache.directory.server.xdbm.search.Optimizer;
+import org.apache.directory.server.xdbm.search.PartitionSearchResult;
 import org.apache.directory.server.xdbm.search.SearchEngine;
+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.exception.LdapNoSuchObjectException;
 import org.apache.directory.shared.ldap.model.filter.AndNode;
@@ -40,6 +43,7 @@ import org.apache.directory.shared.ldap.
 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.shared.ldap.model.schema.SchemaManager;
 
 
 /**
@@ -48,17 +52,19 @@ import org.apache.directory.shared.ldap.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class DefaultSearchEngine<ID extends Comparable<ID>> implements SearchEngine<Entry, ID>
+public class DefaultSearchEngine implements SearchEngine
 {
     /** the Optimizer used by this DefaultSearchEngine */
     private final Optimizer optimizer;
-    
+
     /** the Database this DefaultSearchEngine operates on */
-    private final Store<Entry, ID> db;
+    private final Store db;
+
     /** creates Cursors over entries satisfying filter expressions */
-    private final CursorBuilder<ID> cursorBuilder;
+    private final CursorBuilder cursorBuilder;
+
     /** creates evaluators which check to see if candidates satisfy a filter expression */
-    private final EvaluatorBuilder<ID> evaluatorBuilder;
+    private final EvaluatorBuilder evaluatorBuilder;
 
 
     // ------------------------------------------------------------------------
@@ -73,8 +79,8 @@ public class DefaultSearchEngine<ID exte
      * @param evaluatorBuilder an expression evaluator builder
      * @param optimizer an optimizer to use during search
      */
-    public DefaultSearchEngine( Store<Entry, ID> db, CursorBuilder<ID> cursorBuilder,
-        EvaluatorBuilder<ID> evaluatorBuilder, Optimizer optimizer )
+    public DefaultSearchEngine( Store db, CursorBuilder cursorBuilder,
+        EvaluatorBuilder evaluatorBuilder, Optimizer optimizer )
     {
         this.db = db;
         this.optimizer = optimizer;
@@ -97,110 +103,135 @@ public class DefaultSearchEngine<ID exte
     /**
      * {@inheritDoc}
      */
-    public IndexCursor<ID, Entry, ID> cursor( Dn base, AliasDerefMode aliasDerefMode, ExprNode filter,
-        SearchScope scope ) throws Exception
+    public PartitionSearchResult computeResult( SchemaManager schemaManager, SearchOperationContext searchContext )
+        throws Exception
     {
-        Dn effectiveBase;
-        ID baseId = db.getEntryId( base );
+        SearchScope scope = searchContext.getScope();
+        Dn baseDn = searchContext.getDn();
+        AliasDerefMode aliasDerefMode = searchContext.getAliasDerefMode();
+        ExprNode filter = searchContext.getFilter();
+
+        // Compute the UUID of the baseDN entry
+        String baseId = db.getEntryId( baseDn );
+
+        // Prepare the instance containing the search result
+        PartitionSearchResult searchResult = new PartitionSearchResult( schemaManager );
+        Set<IndexEntry<String, String>> resultSet = new HashSet<IndexEntry<String, String>>();
 
         // Check that we have an entry, otherwise we can immediately get out
         if ( baseId == null )
         {
-            if ( ( ( Partition ) db ).getSuffixDn().equals( base ) )
+            if ( ( ( Partition ) db ).getSuffixDn().equals( baseDn ) )
             {
-                // The context entry is not created yet, return an empty cursor
-                return new EmptyIndexCursor<ID, Entry, ID>();
+                // The context entry is not created yet, return an empty result
+                searchResult.setResultSet( resultSet );
+
+                return searchResult;
             }
             else
             {
                 // The search base doesn't exist
-                throw new LdapNoSuchObjectException( I18n.err( I18n.ERR_648, base ) );
+                throw new LdapNoSuchObjectException( I18n.err( I18n.ERR_648, baseDn ) );
             }
         }
 
-        String aliasedBase = db.getAliasIndex().reverseLookup( baseId );
-
         // --------------------------------------------------------------------
         // Determine the effective base with aliases
         // --------------------------------------------------------------------
+        String aliasedBase = db.getAliasIndex().reverseLookup( baseId );
+        Dn effectiveBase = baseDn;
+        String effectiveBaseId = baseId;
 
-        /*
-         * If the base is not an alias or if alias dereferencing does not
-         * occur on finding the base then we set the effective base to the
-         * given base.
-         */
-        if ( ( null == aliasedBase ) || !aliasDerefMode.isDerefFindingBase() )
-        {
-            effectiveBase = base;
-        }
-        /*
-         * If the base is an alias and alias dereferencing does occur on
-         * finding the base then we set the effective base to the alias target
-         * got from the alias index.
-         */
-        else
+        if ( ( aliasedBase != null ) && aliasDerefMode.isDerefFindingBase() )
         {
-            effectiveBase = new Dn( aliasedBase );
+            /*
+             * If the base is an alias and alias dereferencing does occur on
+             * finding the base, or always then we set the effective base to the alias target
+             * got from the alias index.
+             */
+            effectiveBase = new Dn( schemaManager, aliasedBase );
+            effectiveBaseId = db.getEntryId( effectiveBase );
         }
 
         // --------------------------------------------------------------------
         // Specifically Handle Object Level Scope
         // --------------------------------------------------------------------
-        ID effectiveBaseId = baseId;
-        
-        if ( effectiveBase != base )
-        {
-            effectiveBaseId = db.getEntryId( effectiveBase );
-        }
-
         if ( scope == SearchScope.OBJECT )
         {
-            IndexEntry<ID, ID> indexEntry = new ForwardIndexEntry<ID, ID>();
+            IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
             indexEntry.setId( effectiveBaseId );
             optimizer.annotate( filter );
-            Evaluator<? extends ExprNode, Entry, ID> evaluator = evaluatorBuilder.build( filter );
-            
+            Evaluator<? extends ExprNode> evaluator = evaluatorBuilder.build( filter );
+
             // Fetch the entry, as we have only one
-            Entry entry = null;
-            
-            if ( effectiveBase != base )
-            {
-                entry = db.lookup( indexEntry.getId() );
-            }
-            else
-            {
-                entry = db.lookup( indexEntry.getId(), effectiveBase );
-            }
-            
+            Entry entry = db.lookup( indexEntry.getId(), effectiveBase );
+
             indexEntry.setEntry( entry );
+            resultSet.add( indexEntry );
 
-            if ( evaluator.evaluate( indexEntry ) )
-            {
-                return new SingletonIndexCursor<ID, ID>( indexEntry );
-            }
-            else
-            {
-                return new EmptyIndexCursor<ID, Entry, ID>();
-            }
+            searchResult.setEvaluator( evaluator );
+            searchResult.setResultSet( resultSet );
+
+            return searchResult;
         }
 
+        // This is not a BaseObject scope search.
+
         // Add the scope node using the effective base to the filter
         BranchNode root = new AndNode();
-        ExprNode node = new ScopeNode<ID>( aliasDerefMode, effectiveBase, effectiveBaseId, scope );
+        ExprNode node = new ScopeNode( aliasDerefMode, effectiveBase, effectiveBaseId, scope );
         root.getChildren().add( node );
         root.getChildren().add( filter );
 
         // Annotate the node with the optimizer and return search enumeration.
         optimizer.annotate( root );
-        
-        return ( IndexCursor<ID, Entry, ID> ) cursorBuilder.build( root );
+        Evaluator<? extends ExprNode> evaluator = evaluatorBuilder.build( root );
+
+        Set<String> uuidSet = new HashSet<String>();
+        searchResult.setAliasDerefMode( aliasDerefMode );
+        searchResult.setCandidateSet( uuidSet );
+
+        long nbResults = cursorBuilder.build( root, searchResult );
+
+        if ( nbResults < Long.MAX_VALUE )
+        {
+            for ( String uuid : uuidSet )
+            {
+                IndexEntry<String, String> indexEntry = new IndexEntry<String, String>();
+                indexEntry.setId( uuid );
+                resultSet.add( indexEntry );
+            }
+        }
+        else
+        {
+            // Full scan : use the MasterTable
+            Cursor<IndexEntry<String, String>> cursor = new IndexCursorAdaptor( db.getMasterTable().cursor(), true );
+
+            while ( cursor.next() )
+            {
+                IndexEntry<String, String> indexEntry = cursor.get();
+
+                // Here, the indexEntry contains a <UUID, Entry> tuple. Convert it to <UUID, UUID> 
+                IndexEntry<String, String> forwardIndexEntry = new IndexEntry<String, String>();
+                forwardIndexEntry.setKey( indexEntry.getKey() );
+                forwardIndexEntry.setId( indexEntry.getKey() );
+                forwardIndexEntry.setEntry( null );
+
+                resultSet.add( forwardIndexEntry );
+            }
+        }
+
+        searchResult.setEvaluator( evaluator );
+        searchResult.setResultSet( resultSet );
+
+        return searchResult;
     }
 
 
     /**
      * @see SearchEngine#evaluator(ExprNode)
      */
-    public Evaluator<? extends ExprNode, Entry, ID> evaluator( ExprNode filter ) throws Exception
+    public Evaluator<? extends ExprNode> evaluator( ExprNode filter ) throws Exception
     {
         return evaluatorBuilder.build( filter );
     }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EvaluatorBuilder.java Mon Sep 24 02:17:13 2012
@@ -26,6 +26,17 @@ import java.util.List;
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.server.xdbm.Store;
 import org.apache.directory.server.xdbm.search.Evaluator;
+import org.apache.directory.server.xdbm.search.evaluator.AndEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.ApproximateEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.EqualityEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.GreaterEqEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.LessEqEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.NotEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.OneLevelScopeEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.OrEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.PresenceEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.SubstringEvaluator;
+import org.apache.directory.server.xdbm.search.evaluator.SubtreeScopeEvaluator;
 import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.filter.AndNode;
 import org.apache.directory.shared.ldap.model.filter.ApproximateNode;
@@ -48,9 +59,9 @@ import org.apache.directory.shared.util.
  * 
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class EvaluatorBuilder<ID extends Comparable<ID>>
+public class EvaluatorBuilder
 {
-    private final Store<Entry, ID> db;
+    private final Store db;
     private final SchemaManager schemaManager;
 
 
@@ -62,46 +73,52 @@ public class EvaluatorBuilder<ID extends
      * @param schemaManager the schema manager
      * @throws Exception failure to access db or lookup schema in registries
      */
-    public EvaluatorBuilder( Store<Entry, ID> db, SchemaManager schemaManager ) throws Exception
+    public EvaluatorBuilder( Store db, SchemaManager schemaManager ) throws Exception
     {
         this.db = db;
         this.schemaManager = schemaManager;
     }
 
 
-    public <T> Evaluator<? extends ExprNode, Entry, ID> build( ExprNode node ) throws Exception
+    public <T> Evaluator<? extends ExprNode> build( ExprNode node ) throws Exception
     {
+        Object count = node.get( "count" );
+        if ( ( count != null ) && ( ( Long ) count == 0L ) )
+        {
+            return null;
+        }
+
         switch ( node.getAssertionType() )
         {
         /* ---------- LEAF NODE HANDLING ---------- */
 
             case APPROXIMATE:
-                return new ApproximateEvaluator<T, ID>( ( ApproximateNode<T> ) node, db, schemaManager );
+                return new ApproximateEvaluator<T>( ( ApproximateNode<T> ) node, db, schemaManager );
 
             case EQUALITY:
-                return new EqualityEvaluator<T, ID>( ( EqualityNode<T> ) node, db, schemaManager );
+                return new EqualityEvaluator<T>( ( EqualityNode<T> ) node, db, schemaManager );
 
             case GREATEREQ:
-                return new GreaterEqEvaluator<T, ID>( ( GreaterEqNode<T> ) node, db, schemaManager );
+                return new GreaterEqEvaluator<T>( ( GreaterEqNode<T> ) node, db, schemaManager );
 
             case LESSEQ:
-                return new LessEqEvaluator<T, ID>( ( LessEqNode<T> ) node, db, schemaManager );
+                return new LessEqEvaluator<T>( ( LessEqNode<T> ) node, db, schemaManager );
 
             case PRESENCE:
-                return new PresenceEvaluator<ID>( ( PresenceNode ) node, db, schemaManager );
+                return new PresenceEvaluator( ( PresenceNode ) node, db, schemaManager );
 
             case SCOPE:
-                if ( ( ( ScopeNode<ID> ) node ).getScope() == SearchScope.ONELEVEL )
+                if ( ( ( ScopeNode ) node ).getScope() == SearchScope.ONELEVEL )
                 {
-                    return new OneLevelScopeEvaluator<Entry, ID>( db, ( ScopeNode<ID> ) node );
+                    return new OneLevelScopeEvaluator<Entry>( db, ( ScopeNode ) node );
                 }
                 else
                 {
-                    return new SubtreeScopeEvaluator<Entry, ID>( db, ( ScopeNode<ID> ) node );
+                    return new SubtreeScopeEvaluator( db, ( ScopeNode ) node );
                 }
 
             case SUBSTRING:
-                return new SubstringEvaluator<ID>( ( SubstringNode ) node, db, schemaManager );
+                return new SubstringEvaluator( ( SubstringNode ) node, db, schemaManager );
 
                 /* ---------- LOGICAL OPERATORS ---------- */
 
@@ -109,7 +126,7 @@ public class EvaluatorBuilder<ID extends
                 return buildAndEvaluator( ( AndNode ) node );
 
             case NOT:
-                return new NotEvaluator<ID>( ( NotNode ) node, build( ( ( NotNode ) node ).getFirstChild() ) );
+                return new NotEvaluator( ( NotNode ) node, build( ( ( NotNode ) node ).getFirstChild() ) );
 
             case OR:
                 return buildOrEvaluator( ( OrNode ) node );
@@ -126,28 +143,63 @@ public class EvaluatorBuilder<ID extends
     }
 
 
-    AndEvaluator<ID> buildAndEvaluator( AndNode node ) throws Exception
+    private <T> Evaluator<? extends ExprNode> buildAndEvaluator( AndNode node ) throws Exception
     {
         List<ExprNode> children = node.getChildren();
-        List<Evaluator<? extends ExprNode, Entry, ID>> evaluators = new ArrayList<Evaluator<? extends ExprNode, Entry, ID>>(
-            children.size() );
-        for ( ExprNode child : children )
+        List<Evaluator<? extends ExprNode>> evaluators = buildList( children );
+
+        int size = evaluators.size();
+
+        switch ( size )
         {
-            evaluators.add( build( child ) );
+            case 0:
+                return null;
+
+            case 1:
+                return evaluators.get( 0 );
+
+            default:
+                return new AndEvaluator( node, evaluators );
         }
-        return new AndEvaluator<ID>( node, evaluators );
     }
 
 
-    OrEvaluator<ID> buildOrEvaluator( OrNode node ) throws Exception
+    private <T> Evaluator<? extends ExprNode> buildOrEvaluator( OrNode node ) throws Exception
     {
         List<ExprNode> children = node.getChildren();
-        List<Evaluator<? extends ExprNode, Entry, ID>> evaluators = new ArrayList<Evaluator<? extends ExprNode, Entry, ID>>(
+        List<Evaluator<? extends ExprNode>> evaluators = buildList( children );
+
+        int size = evaluators.size();
+
+        switch ( size )
+        {
+            case 0:
+                return null;
+
+            case 1:
+                return evaluators.get( 0 );
+
+            default:
+                return new OrEvaluator( node, evaluators );
+        }
+    }
+
+
+    private List<Evaluator<? extends ExprNode>> buildList( List<ExprNode> children ) throws Exception
+    {
+        List<Evaluator<? extends ExprNode>> evaluators = new ArrayList<Evaluator<? extends ExprNode>>(
             children.size() );
+
         for ( ExprNode child : children )
         {
-            evaluators.add( build( child ) );
+            Evaluator<? extends ExprNode> evaluator = build( child );
+
+            if ( evaluator != null )
+            {
+                evaluators.add( evaluator );
+            }
         }
-        return new OrEvaluator<ID>( node, evaluators );
+
+        return evaluators;
     }
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ScanCountComparator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ScanCountComparator.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ScanCountComparator.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ScanCountComparator.java Mon Sep 24 02:17:13 2012
@@ -23,7 +23,6 @@ package org.apache.directory.server.xdbm
 import java.util.Comparator;
 
 import org.apache.directory.server.xdbm.search.Evaluator;
-import org.apache.directory.shared.ldap.model.entry.Entry;
 
 
 /**
@@ -33,15 +32,27 @@ import org.apache.directory.shared.ldap.
  *
  * @param <ID> The type of element
  */
-public class ScanCountComparator<ID> implements Comparator<Evaluator<?, Entry, ID>>
+public class ScanCountComparator implements Comparator<Evaluator<?>>
 {
     /**
      * Compare two scan counts frpm two evaluators 
      */
-    public int compare( Evaluator<?, Entry, ID> e1, Evaluator<?, Entry, ID> e2 )
+    public int compare( Evaluator<?> e1, Evaluator<?> e2 )
     {
-        long scanCount1 = ( Long ) e1.getExpression().get( "count" );
-        long scanCount2 = ( Long ) e2.getExpression().get( "count" );
+        Object count1 = e1.getExpression().get( "count" );;
+        Object count2 = e2.getExpression().get( "count" );;
+        long scanCount1 = Long.MAX_VALUE;
+        long scanCount2 = Long.MAX_VALUE;
+
+        if ( count1 != null )
+        {
+            scanCount1 = ( Long ) e1.getExpression().get( "count" );
+        }
+
+        if ( count2 != null )
+        {
+            scanCount2 = ( Long ) e2.getExpression().get( "count" );
+        }
 
         if ( scanCount1 == scanCount2 )
         {
@@ -61,5 +72,4 @@ public class ScanCountComparator<ID> imp
 
         return 1;
     }
-
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/AbstractIndexCursorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/AbstractIndexCursorTest.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/AbstractIndexCursorTest.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/AbstractIndexCursorTest.java Mon Sep 24 02:17:13 2012
@@ -28,7 +28,6 @@ import java.util.Iterator;
 
 import org.apache.directory.shared.ldap.model.cursor.CursorClosedException;
 import org.apache.directory.shared.ldap.model.cursor.DefaultClosureMonitor;
-import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -42,16 +41,16 @@ import org.junit.Test;
 public class AbstractIndexCursorTest
 {
 
-    private AbstractIndexCursor<String, Entry, Long> indexCursor;
+    private AbstractIndexCursor<String> indexCursor;
 
 
     @Before
     public void setUp()
     {
-        indexCursor = new EmptyIndexCursor<String, Entry, Long>();
+        indexCursor = new EmptyIndexCursor<String>();
     }
-    
-    
+
+
     @After
     public void cleanup() throws Exception
     {
@@ -125,7 +124,7 @@ public class AbstractIndexCursorTest
     @Test
     public void testIterator()
     {
-        Iterator<IndexEntry<String, Long>> iterator = indexCursor.iterator();
+        Iterator<IndexEntry<String, String>> iterator = indexCursor.iterator();
         assertNotNull( iterator );
     }
 

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/EmptyIndexCursorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/EmptyIndexCursorTest.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/EmptyIndexCursorTest.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/EmptyIndexCursorTest.java Mon Sep 24 02:17:13 2012
@@ -22,8 +22,8 @@ package org.apache.directory.server.xdbm
 
 import static junit.framework.Assert.assertFalse;
 
+import org.apache.directory.server.core.api.partition.Partition;
 import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
-import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -37,16 +37,16 @@ import org.junit.Test;
 public class EmptyIndexCursorTest
 {
 
-    private EmptyIndexCursor<String, Entry, Long> indexCursor;
+    private EmptyIndexCursor<String> indexCursor;
 
 
     @Before
     public void setUp()
     {
-        indexCursor = new EmptyIndexCursor<String, Entry, Long>();
+        indexCursor = new EmptyIndexCursor<String>();
     }
-    
-    
+
+
     @After
     public void cleanup() throws Exception
     {
@@ -60,8 +60,8 @@ public class EmptyIndexCursorTest
     @Test
     public void testConstructor() throws Exception
     {
-        EmptyIndexCursor<String, Entry, Long> cursor = new EmptyIndexCursor<String, Entry, Long>();
-        
+        EmptyIndexCursor<String> cursor = new EmptyIndexCursor<String>();
+
         cursor.close();
     }
 
@@ -182,7 +182,7 @@ public class EmptyIndexCursorTest
     @Test
     public void testBeforeValue() throws Exception
     {
-        indexCursor.beforeValue( 1L, "test" );
+        indexCursor.beforeValue( Partition.DEFAULT_ID, "test" );
     }
 
 
@@ -196,7 +196,7 @@ public class EmptyIndexCursorTest
     @Test
     public void testAfterValue() throws Exception
     {
-        indexCursor.afterValue( 1L, "test" );
+        indexCursor.afterValue( Partition.DEFAULT_ID, "test" );
     }
 
 

Added: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/IndexEntryTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/IndexEntryTest.java?rev=1389184&view=auto
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/IndexEntryTest.java (added)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/IndexEntryTest.java Mon Sep 24 02:17:13 2012
@@ -0,0 +1,140 @@
+/*
+ *  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 static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import org.apache.directory.shared.ldap.model.cursor.Tuple;
+import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Tests the {@link IndexEntry} class.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class IndexEntryTest
+{
+
+    private IndexEntry<String, Long> indexEntry;
+
+
+    @Before
+    public void setUp()
+    {
+        indexEntry = new IndexEntry<String, Long>();
+    }
+
+
+    @Test
+    public void testSetGetId()
+    {
+        assertNull( indexEntry.getId() );
+
+        indexEntry.setId( 1L );
+        assertEquals( Long.valueOf( 1L ), indexEntry.getId() );
+    }
+
+
+    @Test
+    public void testSetGetValue()
+    {
+        assertNull( indexEntry.getKey() );
+
+        indexEntry.setKey( "test" );
+        assertEquals( "test", indexEntry.getKey() );
+    }
+
+
+    @Test
+    public void testSetGetObject()
+    {
+        assertNull( indexEntry.getEntry() );
+
+        indexEntry.setEntry( new DefaultEntry() );
+        assertEquals( new DefaultEntry(), indexEntry.getEntry() );
+    }
+
+
+    @Test
+    public void testSetGetTuple()
+    {
+        assertNotNull( indexEntry.getTuple() );
+        assertNull( indexEntry.getTuple().getKey() );
+        assertNull( indexEntry.getTuple().getKey() );
+
+        indexEntry.setTuple( new Tuple<String, Long>( "a", 1L ) );
+        assertEquals( new Tuple<String, Long>( "a", 1L ), indexEntry.getTuple() );
+    }
+
+
+    @Test
+    public void testClear()
+    {
+        indexEntry.setTuple( new Tuple<String, Long>( "a", 1L ) );
+        indexEntry.clear();
+
+        assertNull( indexEntry.getId() );
+        assertNull( indexEntry.getKey() );
+        assertNull( indexEntry.getEntry() );
+        assertNotNull( indexEntry.getTuple() );
+        assertNull( indexEntry.getTuple().getKey() );
+        assertNull( indexEntry.getTuple().getKey() );
+    }
+
+
+    @Test
+    public void testCopy()
+    {
+        // prepare index entry
+        indexEntry.setTuple( new Tuple<String, Long>( "a", 1L ) );
+
+        // create empty index entry and assert empty values
+        IndexEntry<String, Long> indexEntry2 = new IndexEntry<String, Long>();
+        assertNull( indexEntry2.getId() );
+        assertNull( indexEntry2.getKey() );
+        assertNull( indexEntry2.getEntry() );
+        assertNotNull( indexEntry2.getTuple() );
+        assertNull( indexEntry2.getTuple().getKey() );
+        assertNull( indexEntry2.getTuple().getKey() );
+
+        // copy values and assert non-empty values
+        indexEntry2.copy( indexEntry );
+        assertEquals( Long.valueOf( 1L ), indexEntry2.getId() );
+        assertEquals( "a", indexEntry2.getKey() );
+        assertEquals( new Tuple<String, Long>( "a", 1L ), indexEntry2.getTuple() );
+    }
+
+
+    @Test
+    public void testToString()
+    {
+        indexEntry.setTuple( new Tuple<String, Long>( "asdfghjkl", 1234567890L ) );
+        assertTrue( indexEntry.toString().contains( "asdfghjkl" ) );
+        assertTrue( indexEntry.toString().contains( "1234567890" ) );
+    }
+
+}

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/ParentIdAndRdnTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/ParentIdAndRdnTest.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/ParentIdAndRdnTest.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/ParentIdAndRdnTest.java Mon Sep 24 02:17:13 2012
@@ -20,9 +20,11 @@
 package org.apache.directory.server.xdbm;
 
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import java.io.File;
+
 import org.apache.directory.server.xdbm.impl.avl.AvlPartitionTest;
 import org.apache.directory.shared.ldap.model.exception.LdapInvalidDnException;
 import org.apache.directory.shared.ldap.model.name.Rdn;
@@ -31,12 +33,12 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
 import org.apache.directory.shared.ldap.schemaloader.LdifSchemaLoader;
 import org.apache.directory.shared.ldap.schemamanager.impl.DefaultSchemaManager;
+import org.apache.directory.shared.util.Strings;
 import org.apache.directory.shared.util.exception.Exceptions;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import static org.junit.Assert.assertEquals;
 
 
 /**
@@ -82,42 +84,43 @@ public class ParentIdAndRdnTest
     @Test
     public void testCompareEquals() throws LdapInvalidDnException
     {
-        ParentIdAndRdn<Long> rdn1 = new ParentIdAndRdn<Long>( 2L, new Rdn( schemaManager, "cn=test" ) );
-        ParentIdAndRdn<Long> rdn2 = new ParentIdAndRdn<Long>( 2L, new Rdn( schemaManager, "CN=test2" ) );
-        ParentIdAndRdn<Long> rdn3 = new ParentIdAndRdn<Long>( 2L, new Rdn( schemaManager, "ou=test" ) );
-        ParentIdAndRdn<Long> rdn4 = new ParentIdAndRdn<Long>( 2L, new Rdn( schemaManager, "2.5.4.11=test2" ) );
-        ParentIdAndRdn<Long> rdn5 = new ParentIdAndRdn<Long>( 1L, new Rdn( schemaManager, "CommonName= Test " ) );
-        ParentIdAndRdn<Long> rdn6 = new ParentIdAndRdn<Long>( 2L, new Rdn( schemaManager, "cn=test+sn=small" ) );
-        ParentIdAndRdn<Long> rdn7 = new ParentIdAndRdn<Long>( 2L, new Rdn( schemaManager, "2.5.4.4= Small + 2.5.4.3 = TEST " ) );
-        
+        ParentIdAndRdn rdn1 = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( schemaManager, "cn=test" ) );
+        ParentIdAndRdn rdn2 = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( schemaManager, "CN=test2" ) );
+        ParentIdAndRdn rdn3 = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( schemaManager, "ou=test" ) );
+        ParentIdAndRdn rdn4 = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( schemaManager, "2.5.4.11=test2" ) );
+        ParentIdAndRdn rdn5 = new ParentIdAndRdn( Strings.getUUID( 1L ), new Rdn( schemaManager, "CommonName= Test " ) );
+        ParentIdAndRdn rdn6 = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( schemaManager, "cn=test+sn=small" ) );
+        ParentIdAndRdn rdn7 = new ParentIdAndRdn( Strings.getUUID( 2L ), new Rdn( schemaManager,
+            "2.5.4.4= Small + 2.5.4.3 = TEST " ) );
+
         // First rdn
         assertEquals( 0, rdn1.compareTo( rdn1 ) );
         assertEquals( -1, rdn1.compareTo( rdn2 ) );
         assertEquals( 2, rdn1.compareTo( rdn3 ) );
         assertEquals( 2, rdn1.compareTo( rdn4 ) );
         assertEquals( 1, rdn1.compareTo( rdn5 ) );
-        
+
         // Second rdn
         assertEquals( 1, rdn2.compareTo( rdn1 ) );
         assertEquals( 0, rdn2.compareTo( rdn2 ) );
         assertEquals( 2, rdn2.compareTo( rdn3 ) );
         assertEquals( 2, rdn2.compareTo( rdn4 ) );
         assertEquals( 1, rdn2.compareTo( rdn5 ) );
-        
+
         // Third rdn
         assertEquals( -2, rdn3.compareTo( rdn1 ) );
         assertEquals( -2, rdn3.compareTo( rdn2 ) );
         assertEquals( 0, rdn3.compareTo( rdn3 ) );
         assertEquals( -1, rdn3.compareTo( rdn4 ) );
         assertEquals( 1, rdn3.compareTo( rdn5 ) );
-        
+
         // Forth rdn
         assertEquals( -2, rdn4.compareTo( rdn1 ) );
         assertEquals( -2, rdn4.compareTo( rdn2 ) );
         assertEquals( 1, rdn4.compareTo( rdn3 ) );
         assertEquals( 0, rdn4.compareTo( rdn4 ) );
         assertEquals( 1, rdn4.compareTo( rdn5 ) );
-        
+
         // Fifth rdn
         assertEquals( -1, rdn5.compareTo( rdn1 ) );
         assertEquals( -1, rdn5.compareTo( rdn2 ) );

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/PartitionTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/PartitionTest.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/PartitionTest.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/PartitionTest.java Mon Sep 24 02:17:13 2012
@@ -154,7 +154,6 @@ public class PartitionTest
         assertEquals( 15, partition.getPresenceIndex().count() );
         assertEquals( 27, partition.getObjectClassIndex().count() );
         assertEquals( 11, partition.getEntryCsnIndex().count() );
-        assertEquals( 11, partition.getEntryUuidIndex().count() );
 
         Iterator<String> userIndices = partition.getUserIndices();
         int count = 0;
@@ -188,7 +187,7 @@ public class PartitionTest
 
         Modification add = new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attrib );
 
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry lookedup = partition.lookup( entryId );
 
         // before modification: no "uidObject" tuple in objectClass index
@@ -218,11 +217,11 @@ public class PartitionTest
 
         Modification add = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrib );
 
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry lookedup = partition.lookup( entryId );
 
         // before modification: expect "sales" tuple in ou index
-        Index<String, Entry, Long> ouIndex = ( Index<String, Entry, Long> ) partition.getUserIndex( OU_AT );
+        Index<String, Entry, String> ouIndex = ( Index<String, Entry, String> ) partition.getUserIndex( OU_AT );
         assertTrue( ouIndex.forward( "sales", entryId ) );
         assertTrue( lookedup.get( "ou" ).contains( "sales" ) );
 
@@ -247,11 +246,11 @@ public class PartitionTest
 
         Modification add = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrib );
 
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry lookedup = partition.lookup( entryId );
 
         // before modification: expect "sales" tuple in ou index
-        Index<String, Entry, Long> ouIndex = ( Index<String, Entry, Long> ) partition.getUserIndex( OU_AT );
+        Index<String, Entry, String> ouIndex = ( Index<String, Entry, String> ) partition.getUserIndex( OU_AT );
         assertTrue( partition.getPresenceIndex().forward( SchemaConstants.OU_AT_OID, entryId ) );
         assertTrue( ouIndex.forward( "sales", entryId ) );
         assertTrue( lookedup.get( "ou" ).contains( "sales" ) );
@@ -282,7 +281,7 @@ public class PartitionTest
 
         Modification add = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrib );
 
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry lookedup = partition.lookup( entryId );
 
         // before modification: expect "person" tuple in objectClass index
@@ -310,7 +309,7 @@ public class PartitionTest
 
         Modification add = new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attrib );
 
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry lookedup = partition.lookup( entryId );
 
         // before modification: expect "person" tuple in objectClass index
@@ -339,7 +338,7 @@ public class PartitionTest
 
         Modification add = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attrib );
 
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry lookedup = partition.lookup( entryId );
 
         assertNotSame( csn, lookedup.get( csnAt ).getString() );
@@ -369,13 +368,13 @@ public class PartitionTest
         Dn dn = new Dn( schemaManager, "cn=user,ou=Sales,o=Good Times Co." );
 
         Entry entry = new DefaultEntry( schemaManager, dn,
-            "objectClass: top", 
+            "objectClass: top",
             "objectClass: person",
             "cn: user",
             "sn: user sn" );
 
         // add
-        StoreUtils.injectEntryInStore( partition, entry );
+        StoreUtils.injectEntryInStore( partition, entry, 12 );
         verifyParentId( dn );
 
         // move
@@ -396,9 +395,9 @@ public class PartitionTest
 
     private Entry verifyParentId( Dn dn ) throws Exception
     {
-        Long entryId = partition.getEntryId( dn );
+        String entryId = partition.getEntryId( dn );
         Entry entry = partition.lookup( entryId );
-        Long parentId = partition.getParentId( entryId );
+        String parentId = partition.getParentId( entryId );
 
         Attribute parentIdAt = entry.get( SchemaConstants.ENTRY_PARENT_ID_AT );
         assertNotNull( parentIdAt );

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/SingletonIndexCursorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/SingletonIndexCursorTest.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/SingletonIndexCursorTest.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/SingletonIndexCursorTest.java Mon Sep 24 02:17:13 2012
@@ -24,6 +24,7 @@ import static junit.framework.Assert.ass
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
+import org.apache.directory.server.core.api.partition.Partition;
 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.DefaultEntry;
@@ -40,21 +41,21 @@ import org.junit.Test;
 public class SingletonIndexCursorTest
 {
 
-    private ForwardIndexEntry<String, Long> indexEntry;
-    private SingletonIndexCursor<String, Long> indexCursor;
+    private IndexEntry<String, String> indexEntry;
+    private SingletonIndexCursor<String> indexCursor;
 
 
     @Before
     public void setUp()
     {
-        indexEntry = new ForwardIndexEntry<String, Long>();
-        indexEntry.setId( 1L );
+        indexEntry = new IndexEntry<String, String>();
+        indexEntry.setId( Partition.DEFAULT_ID );
         indexEntry.setEntry( new DefaultEntry() );
         indexEntry.setKey( "test" );
-        indexCursor = new SingletonIndexCursor<String, Long>( indexEntry );
+        indexCursor = new SingletonIndexCursor<String>( indexEntry );
     }
-    
-    
+
+
     @After
     public void cleanup() throws Exception
     {
@@ -65,8 +66,8 @@ public class SingletonIndexCursorTest
     @Test
     public void testConstructor() throws Exception
     {
-        Cursor cursor = new SingletonIndexCursor<String, Long>( indexEntry );
-        
+        Cursor cursor = new SingletonIndexCursor<String>( indexEntry );
+
         cursor.close();
     }
 
@@ -241,23 +242,8 @@ public class SingletonIndexCursorTest
 
 
     @Test(expected = UnsupportedOperationException.class)
-    public void testBeforeValue() throws Exception
-    {
-        indexCursor.beforeValue( 1L, "test" );
-    }
-
-
-    @Test(expected = UnsupportedOperationException.class)
     public void testAfter() throws Exception
     {
         indexCursor.after( null );
     }
-
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testAfterValue() throws Exception
-    {
-        indexCursor.afterValue( 1L, "test" );
-    }
-
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/StoreUtils.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/StoreUtils.java?rev=1389184&r1=1389183&r2=1389184&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/StoreUtils.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/test/java/org/apache/directory/server/xdbm/StoreUtils.java Mon Sep 24 02:17:13 2012
@@ -20,8 +20,6 @@
 package org.apache.directory.server.xdbm;
 
 
-import java.util.UUID;
-
 import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
 import org.apache.directory.server.core.api.partition.Partition;
 import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
@@ -30,6 +28,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.util.Strings;
 
 
 /**
@@ -55,11 +54,10 @@ public class StoreUtils
      * @param registries oid registries
      * @throws Exception on access exceptions
      */
-    //This will suppress PMD.AvoidUsingHardCodedIP warnings in this class
-    @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
-    public static void loadExampleData( Store<Entry, Long> store, SchemaManager schemaManager ) throws Exception
+    public static void loadExampleData( Store store, SchemaManager schemaManager ) throws Exception
     {
         Dn suffixDn = new Dn( schemaManager, "o=Good Times Co." );
+        long index = 1L;
 
         // Entry #1
         Entry entry = new DefaultEntry( schemaManager, suffixDn,
@@ -67,7 +65,7 @@ public class StoreUtils
             "o: Good Times Co.",
             "postalCode: 1",
             "postOfficeBox: 1" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #2
         Dn dn = new Dn( schemaManager, "ou=Sales,o=Good Times Co." );
@@ -77,7 +75,7 @@ public class StoreUtils
             "ou: Sales",
             "postalCode: 1",
             "postOfficeBox: 1" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #3
         dn = new Dn( schemaManager, "ou=Board of Directors,o=Good Times Co." );
@@ -87,7 +85,7 @@ public class StoreUtils
             "ou: Board of Directors",
             "postalCode: 1",
             "postOfficeBox: 1" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #4
         dn = new Dn( schemaManager, "ou=Engineering,o=Good Times Co." );
@@ -97,7 +95,7 @@ public class StoreUtils
             "ou: Engineering",
             "postalCode: 2",
             "postOfficeBox: 2" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #5
         dn = new Dn( schemaManager, "cn=JOhnny WAlkeR,ou=Sales,o=Good Times Co." );
@@ -110,7 +108,7 @@ public class StoreUtils
             "sn: WAlkeR",
             "postalCode: 3",
             "postOfficeBox: 3" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #6
         dn = new Dn( schemaManager, "cn=JIM BEAN,ou=Sales,o=Good Times Co." );
@@ -123,7 +121,7 @@ public class StoreUtils
             "surName: BEAN",
             "postalCode: 4",
             "postOfficeBox: 4" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #7
         dn = new Dn( schemaManager, "ou=Apache,ou=Board of Directors,o=Good Times Co." );
@@ -133,7 +131,7 @@ public class StoreUtils
             "ou: Apache",
             "postalCode: 5",
             "postOfficeBox: 5" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #8
         dn = new Dn( schemaManager, "cn=Jack Daniels,ou=Engineering,o=Good Times Co." );
@@ -146,7 +144,7 @@ public class StoreUtils
             "SN: Daniels",
             "postalCode: 6",
             "postOfficeBox: 6" );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // aliases -------------
 
@@ -159,7 +157,7 @@ public class StoreUtils
             "ou: Apache",
             "commonName: Jim Bean",
             "aliasedObjectName: cn=Jim Bean,ou=Sales,o=Good Times Co." );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #10
         dn = new Dn( schemaManager, "commonName=Jim Bean,ou=Board of Directors,o=Good Times Co." );
@@ -169,7 +167,7 @@ public class StoreUtils
             "objectClass: extensibleObject",
             "commonName: Jim Bean",
             "aliasedObjectName: cn=Jim Bean,ou=Sales,o=Good Times Co." );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
 
         // Entry #11
         dn = new Dn( schemaManager, "2.5.4.3=Johnny Walker,ou=Engineering,o=Good Times Co." );
@@ -180,7 +178,7 @@ public class StoreUtils
             "ou: Engineering",
             "2.5.4.3: Johnny Walker",
             "aliasedObjectName: cn=Johnny Walker,ou=Sales,o=Good Times Co." );
-        injectEntryInStore( store, entry );
+        injectEntryInStore( store, entry, index++ );
     }
 
 
@@ -192,12 +190,13 @@ public class StoreUtils
      * @param store the store
      * @param dn the normalized Dn
      * @param entry the server entry
+     * @param index the UUID number
      * @throws Exception in case of any problems in adding the entry to the store
      */
-    public static void injectEntryInStore( Store<Entry, Long> store, Entry entry ) throws Exception
+    public static void injectEntryInStore( Store store, Entry entry, long index ) throws Exception
     {
         entry.add( SchemaConstants.ENTRY_CSN_AT, CSN_FACTORY.newInstance().toString() );
-        entry.add( SchemaConstants.ENTRY_UUID_AT, UUID.randomUUID().toString() );
+        entry.add( SchemaConstants.ENTRY_UUID_AT, Strings.getUUID( index ).toString() );
 
         AddOperationContext addContext = new AddOperationContext( null, entry );
         ( ( Partition ) store ).add( addContext );