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/04/11 14:51:51 UTC

svn commit: r1324744 [4/5] - in /directory/apacheds/trunk: ./ all/ apache-felix/ core-annotations/ core-api/ core-api/src/main/java/org/apache/directory/server/core/api/ core-api/src/main/java/org/apache/directory/server/core/api/filtering/ core-api/sr...

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java Wed Apr 11 12:51:45 2012
@@ -40,6 +40,7 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
 import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.GetRootDseOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.HasEntryOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.ListOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
@@ -52,15 +53,19 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.partition.AbstractPartition;
 import org.apache.directory.server.core.api.partition.Partition;
 import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.server.xdbm.ForwardIndexEntry;
 import org.apache.directory.server.xdbm.Index;
 import org.apache.directory.server.xdbm.IndexCursor;
 import org.apache.directory.server.xdbm.IndexEntry;
 import org.apache.directory.server.xdbm.IndexNotFoundException;
 import org.apache.directory.server.xdbm.MasterTable;
 import org.apache.directory.server.xdbm.ParentIdAndRdn;
+import org.apache.directory.server.xdbm.ReverseIndexEntry;
 import org.apache.directory.server.xdbm.Store;
 import org.apache.directory.server.xdbm.search.Optimizer;
 import org.apache.directory.server.xdbm.search.SearchEngine;
+import org.apache.directory.server.xdbm.search.impl.ChildrenCursor;
+import org.apache.directory.server.xdbm.search.impl.OneLevelScopeCursor;
 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.Attribute;
@@ -145,9 +150,6 @@ public abstract class AbstractBTreeParti
     /** a system index on objectClass attribute*/
     protected Index<String, Entry, ID> objectClassIdx;
 
-    /** the parent child relationship index */
-    protected Index<ID, Entry, ID> oneLevelIdx;
-
     /** a system index on the entries of descendants of root Dn */
     protected Index<ID, Entry, ID> subLevelIdx;
 
@@ -177,6 +179,9 @@ public abstract class AbstractBTreeParti
 
     private static final boolean NO_REVERSE = Boolean.FALSE;
     private static final boolean WITH_REVERSE = Boolean.TRUE;
+    
+    private static final boolean ADD_CHILD = true;
+    private static final boolean REMOVE_CHILD = false;
 
     // ------------------------------------------------------------------------
     // C O N S T R U C T O R S
@@ -291,12 +296,6 @@ public abstract class AbstractBTreeParti
             addIndex( index );
         }
 
-        if ( getOneLevelIndex() == null )
-        {
-            Index<ID, Entry, ID> index = createSystemIndex( ApacheSchemaConstants.APACHE_ONE_LEVEL_AT_OID, partitionPath, WITH_REVERSE );
-            addIndex( index );
-        }
-
         if ( getSubLevelIndex() == null )
         {
             Index<ID, Entry, ID> index = createSystemIndex( ApacheSchemaConstants.APACHE_SUB_LEVEL_AT_OID, partitionPath, WITH_REVERSE );
@@ -356,7 +355,6 @@ public abstract class AbstractBTreeParti
         // set index shortcuts
         rdnIdx = ( Index<ParentIdAndRdn<ID>, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_RDN_AT_OID );
         presenceIdx = ( Index<String, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_PRESENCE_AT_OID );
-        oneLevelIdx = ( Index<ID, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_ONE_LEVEL_AT_OID );
         subLevelIdx = ( Index<ID, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_SUB_LEVEL_AT_OID );
         aliasIdx = ( Index<String, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_ALIAS_AT_OID );
         oneAliasIdx = ( Index<ID, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_ONE_ALIAS_AT_OID );
@@ -531,6 +529,74 @@ public abstract class AbstractBTreeParti
         
     }
 
+    
+    private void dumpAllRdnIdx() throws Exception
+    {
+        if ( LOG.isDebugEnabled() )
+        {
+            dumpRdnIdx( getRootId(), "" );
+            System.out.println( "-----------------------------" );
+        }
+    }
+
+   
+    private void dumpRdnIdx() throws Exception
+    {
+        if ( LOG.isDebugEnabled() )
+        {
+            dumpRdnIdx( getRootId(), 1, "" );
+            System.out.println( "-----------------------------" );
+        }
+    }
+    
+    
+    private void dumpRdnIdx( ID id, String tabs ) throws Exception
+    {
+        // Start with the root
+        IndexCursor<ParentIdAndRdn<ID>,Entry,ID> cursor = rdnIdx.forwardCursor();
+        
+        IndexEntry<ParentIdAndRdn<ID>, ID> startingPos = new ForwardIndexEntry<ParentIdAndRdn<ID>, ID>();
+        startingPos.setValue( new ParentIdAndRdn( id, (Rdn[]) null ) );
+        cursor.before( startingPos );
+        
+        while ( cursor.next() )
+        {
+            IndexEntry<ParentIdAndRdn<ID>, ID> entry = cursor.get();
+            System.out.println( tabs + entry );
+        }
+        
+        cursor.close();
+    }
+    
+    
+    private void dumpRdnIdx( ID id, int nbSibbling, String tabs ) throws Exception
+    {
+        // Start with the root
+        IndexCursor<ParentIdAndRdn<ID>,Entry,ID> cursor = rdnIdx.forwardCursor();
+        
+        IndexEntry<ParentIdAndRdn<ID>, ID> startingPos = new ForwardIndexEntry<ParentIdAndRdn<ID>, ID>();
+        startingPos.setValue( new ParentIdAndRdn( id, (Rdn[]) null ) );
+        cursor.before( startingPos );
+        int countChildren = 0;
+        
+        while ( cursor.next() && ( countChildren < nbSibbling ) )
+        {
+            IndexEntry<ParentIdAndRdn<ID>, ID> entry = cursor.get();
+            System.out.println( tabs + entry );
+            countChildren++;
+            
+            // And now, the children
+            int nbChildren = entry.getValue().getNbChildren();
+            
+            if ( nbChildren > 0 )
+            {
+                dumpRdnIdx( entry.getId(), nbChildren, tabs + "  " );
+            }
+        }
+        
+        cursor.close();
+    }
+
 
     //---------------------------------------------------------------------------------------------
     // The Add operation
@@ -587,6 +653,12 @@ public abstract class AbstractBTreeParti
 
             // Update the RDN index
             rdnIdx.add( key, id );
+            
+            // Update the parent's nbChildren and nbDescendants values
+            if ( parentId != getRootId() )
+            {
+                updateRdnIdx( parentId, ADD_CHILD, 0 );
+            }
 
             // Update the ObjectClass index
             Attribute objectClass = entry.get( OBJECT_CLASS_AT );
@@ -611,9 +683,6 @@ public abstract class AbstractBTreeParti
                 addAliasIndices( id, entryDn, aliasAttr.getString() );
             }
 
-            // Update the OneLevel index
-            oneLevelIdx.add( parentId, id );
-
             // Update the SubLevel index
             ID tempId = parentId;
 
@@ -676,6 +745,8 @@ public abstract class AbstractBTreeParti
 
             // And finally add the entry into the master table
             master.put( id, entry );
+            
+            dumpRdnIdx();
 
             if ( isSyncOnWrite.get() )
             {
@@ -721,6 +792,51 @@ public abstract class AbstractBTreeParti
         // We now defer the deletion to the implementing class
         delete( id );
     }
+    
+    
+    private void updateRdnIdx( ID parentId, boolean addRemove, int nbDescendant ) throws Exception
+    {
+        boolean isFirst = true;
+        
+        if ( parentId.equals( getRootId() ) )
+        {
+            return;
+        }
+        
+        ParentIdAndRdn<ID> parent = rdnIdx.reverseLookup( parentId );
+        
+        while ( parent != null )
+        {
+            if ( isFirst )
+            {
+                if ( addRemove == ADD_CHILD )
+                {
+                    parent.setNbChildren( parent.getNbChildren() + 1 );
+                }
+                else
+                {
+                    parent.setNbChildren( parent.getNbChildren() - 1 );
+                }
+                
+                isFirst = false;
+            }
+            
+            if ( addRemove == ADD_CHILD )
+            {
+                parent.setNbDescendants( parent.getNbDescendants() + ( nbDescendant + 1 ) );
+            }
+            else
+            {
+                parent.setNbDescendants( parent.getNbDescendants() - ( nbDescendant + 1 ) );
+            }
+
+            // Inject the modified element into the index
+            rdnIdx.add( parent, parentId );
+            
+            parentId = parent.getParentId();
+            parent = rdnIdx.reverseLookup( parentId );
+        }
+    }
 
 
     /**
@@ -754,9 +870,15 @@ public abstract class AbstractBTreeParti
                 objectClassIdx.drop( value.getString(), id );
             }
 
+            // Update the parent's nbChildren and nbDescendants values
+            ParentIdAndRdn<ID> parent = rdnIdx.reverseLookup( id );
+            updateRdnIdx( parent.getParentId(), REMOVE_CHILD, 0 );
+
             // Update the rdn, oneLevel, subLevel, entryCsn and entryUuid indexes
             rdnIdx.drop( id );
-            oneLevelIdx.drop( id );
+            
+            dumpRdnIdx();
+
             subLevelIdx.drop( id );
             entryCsnIdx.drop( entry.get( ENTRY_CSN_AT ).getString(), id );
             entryUuidIdx.drop( entry.get( ENTRY_UUID_AT ).getString(), id );
@@ -824,11 +946,16 @@ public abstract class AbstractBTreeParti
         try
         {
             // We use the OneLevel index to get all the entries from a starting point
-            // and below
-            IndexCursor<ID, Entry, ID> cursor = oneLevelIdx.forwardCursor( id );
-            cursor.beforeValue( id, null );
+            // and below up to the number of children
+            IndexCursor<ParentIdAndRdn<ID>,Entry, ID> cursor = rdnIdx.forwardCursor();
+            
+            IndexEntry<ParentIdAndRdn<ID>, ID> startingPos = new ForwardIndexEntry<ParentIdAndRdn<ID>, ID>();
+            startingPos.setValue( new ParentIdAndRdn( id, (Rdn[]) null ) );
+            cursor.before( startingPos );
 
-            return cursor;
+            dumpRdnIdx();
+
+            return new ChildrenCursor( this, id, cursor );
         }
         catch ( Exception e )
         {
@@ -1403,15 +1530,21 @@ public abstract class AbstractBTreeParti
          * Drop the old parent child relationship and add the new one
          * Set the new parent id for the child replacing the old parent id
          */
-        oneLevelIdx.drop( oldParentId, entryId );
-        oneLevelIdx.add( newParentId, entryId );
-
         updateSubLevelIndex( entryId, oldParentId, newParentId );
 
         // Update the Rdn index
+        // First drop the old entry
+        ParentIdAndRdn<ID> movedEntry = rdnIdx.reverseLookup( entryId );
+        
+        updateRdnIdx( oldParentId, REMOVE_CHILD, movedEntry.getNbDescendants() );
+
         rdnIdx.drop( entryId );
-        ParentIdAndRdn<ID> key = new ParentIdAndRdn<ID>( newParentId, oldDn.getRdn() );
-        rdnIdx.add( key, entryId );
+
+        // Now, add the new entry at the right position
+        movedEntry.setParentId( newParentId );
+        rdnIdx.add( movedEntry, entryId );
+
+        updateRdnIdx( newParentId, ADD_CHILD, movedEntry.getNbDescendants() );
 
         /*
          * Read Alias Index Tuples
@@ -1528,7 +1661,14 @@ public abstract class AbstractBTreeParti
             throw ne;
         }
 
-        rename( oldDn, newRdn, deleteOldRdn, modifiedEntry );
+        // First, rename
+        // Get the old ID
+        if ( modifiedEntry == null )
+        {
+            modifiedEntry = master.get( oldId );
+        }
+
+        rename( oldId, newRdn, deleteOldRdn, modifiedEntry );
         moveAndRename( oldDn, oldId, newSuperiorDn, newRdn, modifiedEntry );
 
         if ( isSyncOnWrite.get() )
@@ -1553,12 +1693,12 @@ public abstract class AbstractBTreeParti
      * @param modifiedEntry the modified entry
      * @throws Exception if something goes wrong
      */
-    private void moveAndRename( Dn oldDn, ID childId, Dn newSuperior, Rdn newRdn, Entry modifiedEntry )
+    private void moveAndRename( Dn oldDn, ID entryId, Dn newSuperior, Rdn newRdn, Entry modifiedEntry )
         throws Exception
     {
         // Get the child and the new parent to be entries and Ids
         ID newParentId = getEntryId( newSuperior );
-        ID oldParentId = getParentId( childId );
+        ID oldParentId = getParentId( entryId );
 
         /*
          * All aliases including and below oldChildDn, will be affected by
@@ -1574,17 +1714,27 @@ public abstract class AbstractBTreeParti
          * Drop the old parent child relationship and add the new one
          * Set the new parent id for the child replacing the old parent id
          */
-        oneLevelIdx.drop( oldParentId, childId );
-        oneLevelIdx.add( newParentId, childId );
-
-        updateSubLevelIndex( childId, oldParentId, newParentId );
+        updateSubLevelIndex( entryId, oldParentId, newParentId );
 
         /*
          * Update the Rdn index
          */
-        rdnIdx.drop( childId );
-        ParentIdAndRdn<ID> key = new ParentIdAndRdn<ID>( newParentId, newRdn );
-        rdnIdx.add( key, childId );
+        // First drop the old entry
+        ParentIdAndRdn<ID> movedEntry = rdnIdx.reverseLookup( entryId );
+        
+        updateRdnIdx( oldParentId, REMOVE_CHILD, movedEntry.getNbDescendants() );
+
+        rdnIdx.drop( entryId );
+        
+
+        // Now, add the new entry at the right position
+        movedEntry.setParentId( newParentId );
+        movedEntry.setRdns( new Rdn[]{ newRdn } );
+        rdnIdx.add( movedEntry, entryId );
+
+        updateRdnIdx( newParentId, ADD_CHILD, movedEntry.getNbDescendants() );
+
+        dumpRdnIdx();
 
         /*
          * Read Alias Index Tuples
@@ -1596,22 +1746,11 @@ public abstract class AbstractBTreeParti
          * aliasTarget is used as a marker to tell us if we're moving an
          * alias.  If it is null then the moved entry is not an alias.
          */
-        String aliasTarget = aliasIdx.reverseLookup( childId );
+        String aliasTarget = aliasIdx.reverseLookup( entryId );
 
         if ( null != aliasTarget )
         {
-            addAliasIndices( childId, buildEntryDn( childId ), aliasTarget );
-        }
-
-        // Update the master table with the modified entry
-        // Warning : this test is an hack. As we may call the Store API directly
-        // we may not have a modified entry to update. For instance, if the ModifierName
-        // or ModifyTimeStamp AT are not updated, there is no reason we want to update the
-        // master table.
-        if ( modifiedEntry != null )
-        {
-            modifiedEntry.put( SchemaConstants.ENTRY_PARENT_ID_AT, newParentId.toString() );
-            master.put( childId, modifiedEntry );
+            addAliasIndices( entryId, buildEntryDn( entryId ), aliasTarget );
         }
     }
 
@@ -1645,19 +1784,13 @@ public abstract class AbstractBTreeParti
             throw new LdapOperationErrorException( e.getMessage(), e );
         }
     }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @SuppressWarnings("unchecked")
-    public synchronized final void rename( Dn dn, Rdn newRdn, boolean deleteOldRdn, Entry entry ) throws Exception
+    
+    
+    private void rename( ID oldId, Rdn newRdn, boolean deleteOldRdn, Entry entry ) throws Exception
     {
-        ID id = getEntryId( dn );
-
         if ( entry == null )
         {
-            entry = master.get( id );
+            entry = master.get( oldId );
         }
 
         Dn updn = entry.getDn();
@@ -1672,7 +1805,6 @@ public abstract class AbstractBTreeParti
          * Also we make sure that the presence index shows the existence of the
          * new Rdn attribute within this entry.
          */
-
         for ( Ava newAtav : newRdn )
         {
             String newNormType = newAtav.getNormType();
@@ -1685,16 +1817,16 @@ public abstract class AbstractBTreeParti
             if ( hasUserIndexOn( newRdnAttrType ) )
             {
                 Index<?, Entry, ID> index = getUserIndex( newRdnAttrType );
-                ( ( Index ) index ).add( newNormValue, id );
+                ( ( Index ) index ).add( newNormValue, oldId );
 
                 // Make sure the altered entry shows the existence of the new attrib
-                if ( !presenceIdx.forward( newNormType, id ) )
+                if ( !presenceIdx.forward( newNormType, oldId ) )
                 {
-                    presenceIdx.add( newNormType, id );
+                    presenceIdx.add( newNormType, oldId );
                 }
             }
         }
-
+        
         /*
          * H A N D L E   O L D   R D N
          * ====================================================================
@@ -1747,28 +1879,40 @@ public abstract class AbstractBTreeParti
                          * If there is no value for id in this index due to our
                          * drop above we remove the oldRdnAttr from the presence idx
                          */
-                        if ( null == index.reverseLookup( id ) )
+                        if ( null == index.reverseLookup( oldId ) )
                         {
-                            presenceIdx.drop( oldNormType, id );
+                            presenceIdx.drop( oldNormType, oldId );
                         }
                     }
                 }
             }
         }
 
+        // And save the modified entry
+        master.put( oldId, entry );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    public synchronized final void rename( Dn dn, Rdn newRdn, boolean deleteOldRdn, Entry entry ) throws Exception
+    {
+        ID oldId = getEntryId( dn );
+
+        rename ( oldId, newRdn, deleteOldRdn, entry );
+
         /*
          * H A N D L E   D N   C H A N G E
          * ====================================================================
          * We only need to update the Rdn index.
          * No need to calculate the new Dn.
          */
-
-        ID parentId = getParentId( id );
-        rdnIdx.drop( id );
+        ID parentId = getParentId( oldId );
+        rdnIdx.drop( oldId );
         ParentIdAndRdn<ID> key = new ParentIdAndRdn<ID>( parentId, newRdn );
-        rdnIdx.add( key, id );
-
-        master.put( id, entry );
+        rdnIdx.add( key, oldId );
 
         if ( isSyncOnWrite.get() )
         {
@@ -1955,7 +2099,9 @@ public abstract class AbstractBTreeParti
     {
         try
         {
-            return oneLevelIdx.count( id );
+            ParentIdAndRdn<ID> parentIdAndRdn = rdnIdx.reverseLookup( id );
+            
+            return parentIdAndRdn.getNbChildren();
         }
         catch ( Exception e )
         {
@@ -2197,16 +2343,6 @@ public abstract class AbstractBTreeParti
      * {@inheritDoc}
      */
     @SuppressWarnings("unchecked")
-    public Index<ID, Entry, ID> getOneLevelIndex()
-    {
-        return ( Index<ID, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_ONE_LEVEL_AT_OID );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @SuppressWarnings("unchecked")
     public Index<ID, Entry, ID> getSubLevelIndex()
     {
         return ( Index<ID, Entry, ID> ) systemIndices.get( ApacheSchemaConstants.APACHE_SUB_LEVEL_AT_OID );

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/EntryCursorAdaptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/EntryCursorAdaptor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/EntryCursorAdaptor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/EntryCursorAdaptor.java Wed Apr 11 12:51:45 2012
@@ -29,6 +29,8 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.cursor.Cursor;
 import org.apache.directory.shared.ldap.model.cursor.CursorIterator;
 import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -38,12 +40,16 @@ import org.apache.directory.shared.ldap.
  */
 public class EntryCursorAdaptor<ID extends Comparable<ID>> implements Cursor<Entry>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private final AbstractBTreePartition<ID> db;
     private final IndexCursor<ID, Entry, ID> indexCursor;
 
 
     public EntryCursorAdaptor( AbstractBTreePartition<ID> db, IndexCursor<ID, Entry, ID> indexCursor )
     {
+        LOG_CURSOR.debug( "Creating EntryCursorAdaptor {}", this );
         this.db = db;
         this.indexCursor = indexCursor;
     }
@@ -100,21 +106,23 @@ public class EntryCursorAdaptor<ID exten
     }
 
 
-    /* 
-     * @see Cursor#close()
+    /**
+     * {@inheritDoc}}
      */
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing EntryCursorAdaptor {}", this );
         indexCursor.close();
     }
 
 
-    /* 
-     * @see Cursor#close()
+    /**
+     * {@inheritDoc}
      */
-    public void close( Exception e ) throws Exception
+    public void close( Exception cause ) throws Exception
     {
-        indexCursor.close( e );
+        LOG_CURSOR.debug( "Closing EntryCursorAdaptor {}", this );
+        indexCursor.close( cause );
     }
 
 

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/IndexCursorAdaptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/IndexCursorAdaptor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/IndexCursorAdaptor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/IndexCursorAdaptor.java Wed Apr 11 12:51:45 2012
@@ -24,7 +24,6 @@ import java.util.Iterator;
 
 import org.apache.directory.server.xdbm.AbstractIndexCursor;
 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.ReverseIndexEntry;
 import org.apache.directory.shared.i18n.I18n;
@@ -32,6 +31,8 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.cursor.Cursor;
 import org.apache.directory.shared.ldap.model.cursor.CursorIterator;
 import org.apache.directory.shared.ldap.model.cursor.Tuple;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -42,6 +43,9 @@ import org.apache.directory.shared.ldap.
  */
 public class IndexCursorAdaptor<K, O, ID> extends AbstractIndexCursor<K, O, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     @SuppressWarnings("unchecked")
     final Cursor<Tuple> wrappedCursor;
     final ForwardIndexEntry<K, ID> forwardEntry;
@@ -59,6 +63,7 @@ public class IndexCursorAdaptor<K, O, ID
     @SuppressWarnings("unchecked")
     public IndexCursorAdaptor( Cursor<Tuple> wrappedCursor, boolean forwardIndex )
     {
+        LOG_CURSOR.debug( "Creating IndexCursorAdaptor {}", this );
         this.wrappedCursor = wrappedCursor;
 
         if ( forwardIndex )
@@ -80,26 +85,6 @@ public class IndexCursorAdaptor<K, O, ID
     }
 
 
-    @SuppressWarnings("unchecked")
-    public void beforeValue( ID id, K key ) throws Exception
-    {
-        if ( wrappedCursor instanceof IndexCursor )
-        {
-            ( ( IndexCursor ) wrappedCursor ).beforeValue( key, id );
-        }
-    }
-
-
-    @SuppressWarnings("unchecked")
-    public void afterValue( ID id, K key ) throws Exception
-    {
-        if ( wrappedCursor instanceof IndexCursor )
-        {
-            ( ( IndexCursor ) wrappedCursor ).afterValue( key, id );
-        }
-    }
-
-
     public void before( IndexEntry<K, ID> element ) throws Exception
     {
         wrappedCursor.before( element.getTuple() );
@@ -180,12 +165,14 @@ public class IndexCursorAdaptor<K, O, ID
 
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing IndexCursorAdaptor {}", this );
         wrappedCursor.close();
     }
 
 
     public void close( Exception reason ) throws Exception
     {
+        LOG_CURSOR.debug( "Closing IndexCursorAdaptor {}", this );
         wrappedCursor.close( reason );
     }
 

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/ValueArrayCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/ValueArrayCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/ValueArrayCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/ValueArrayCursor.java Wed Apr 11 12:51:45 2012
@@ -27,6 +27,8 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
 import org.apache.directory.shared.ldap.model.cursor.Tuple;
 import org.apache.directory.shared.util.exception.NotImplementedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -36,6 +38,9 @@ import org.apache.directory.shared.util.
  */
 public class ValueArrayCursor<K, V> extends AbstractCursor<Tuple<K, V>>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private static final int BEFORE_FIRST = -1;
 
     private final K key;
@@ -47,6 +52,7 @@ public class ValueArrayCursor<K, V> exte
 
     public ValueArrayCursor( final K key, final V[] values )
     {
+        LOG_CURSOR.debug( "Creating ValueArrayCursor {}", this );
         this.key = key;
         this.tuple.setKey( key );
         this.values = Arrays.asList( values );
@@ -55,6 +61,7 @@ public class ValueArrayCursor<K, V> exte
 
     public ValueArrayCursor( final K key, final List<V> values )
     {
+        LOG_CURSOR.debug( "Creating ValueArrayCursor {}", this );
         this.key = key;
         this.tuple.setKey( key );
         this.values = values;
@@ -199,4 +206,26 @@ public class ValueArrayCursor<K, V> exte
 
         throw new InvalidCursorPositionException( I18n.err( I18n.ERR_701, pos, ( values.size() - 1 ) ) );
     }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws Exception
+    {
+        LOG_CURSOR.debug( "Closing ValueArrayCursor {}", this );
+        super.close();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing ValueArrayCursor {}", this );
+        super.close( cause );
+    }
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractIndexCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractIndexCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractIndexCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractIndexCursor.java Wed Apr 11 12:51:45 2012
@@ -20,11 +20,7 @@
 package org.apache.directory.server.xdbm;
 
 
-import java.util.Iterator;
-
-import org.apache.directory.shared.i18n.I18n;
 import org.apache.directory.shared.ldap.model.cursor.AbstractCursor;
-import org.apache.directory.shared.ldap.model.cursor.CursorIterator;
 
 
 /**

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractTable.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractTable.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/AbstractTable.java Wed Apr 11 12:51:45 2012
@@ -52,6 +52,8 @@ public abstract class AbstractTable<K, V
     /** the current count of entries in this Table */
     protected int count;
 
+    /** whether or not this table allows for duplicates */
+    protected boolean allowsDuplicates;
 
     /**
      * Create an instance of Table

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/EmptyIndexCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/EmptyIndexCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/EmptyIndexCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/EmptyIndexCursor.java Wed Apr 11 12:51:45 2012
@@ -21,6 +21,8 @@ package org.apache.directory.server.xdbm
 
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -30,6 +32,15 @@ import org.apache.directory.shared.ldap.
  */
 public class EmptyIndexCursor<K, E, ID> extends AbstractIndexCursor<K, E, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
+    public EmptyIndexCursor()
+    {
+        LOG_CURSOR.debug( "Creating EmptyIndexCursor {}", this );
+    }
+    
+    
     /**
      * {@inheritDoc}
      */
@@ -120,4 +131,24 @@ public class EmptyIndexCursor<K, E, ID> 
     {
         checkNotClosed( "after()" );
     }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void close( ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing EmptyIndexCursor {}", this );
+        super.close();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing EmptyIndexCursor {}", this );
+        super.close( cause );
+    }
 }

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=1324744&r1=1324743&r2=1324744&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 Wed Apr 11 12:51:45 2012
@@ -45,6 +45,11 @@ public class ParentIdAndRdn<ID extends C
     /** The list of Rdn for this instance */
     protected Rdn[] rdns;
 
+    /** Number of direct children */
+    protected int nbChildren;
+
+    /** Number of global descendant */
+    protected int nbDescendants;
 
     /**
      * Serializable constructor.
@@ -77,6 +82,8 @@ public class ParentIdAndRdn<ID extends C
     {
         this.parentId = parentId;
         this.rdns = rdns.toArray( new Rdn[rdns.size()] );
+        nbChildren = 0;
+        nbDescendants = 0;
     }
 
 
@@ -183,13 +190,50 @@ public class ParentIdAndRdn<ID extends C
      */
     public int compareTo( ParentIdAndRdn<ID> that )
     {
-        int val = rdns.length - that.rdns.length;
+        // 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;
+            }
+            else
+            {
+                // The current value is necessarily superior
+                return 1;
+            }
+        }
+
+        if ( rdns == null )
+        {
+            int res = parentId.compareTo( that.parentId );
+            
+            if ( res == 0 )
+            {
+                return -1;
+            }
+            else
+            {
+                return res;
+            }
+        }
+        
+        int val = parentId.compareTo( that.getParentId() );
 
         if ( val != 0 )
         {
             return val;
         }
 
+        val = rdns.length - that.rdns.length;
+
+        if ( val != 0 )
+        {
+            return val;
+        }
+        
         StringBuilder sb = new StringBuilder();
         boolean isFirst = true;
         
@@ -230,11 +274,6 @@ public class ParentIdAndRdn<ID extends C
         
         val = ( thisString.compareTo( thatString ) );
         
-        if ( val == 0 )
-        {
-            val = this.getParentId().compareTo( that.getParentId() );
-        }
-
         return val;
     }
 
@@ -242,6 +281,8 @@ public class ParentIdAndRdn<ID extends C
     public void writeExternal( ObjectOutput out ) throws IOException
     {
         out.writeObject( parentId );
+        out.writeInt( nbChildren );
+        out.writeInt( nbDescendants );
         out.writeInt( rdns.length );
 
         for ( Rdn rdn : rdns )
@@ -255,6 +296,8 @@ public class ParentIdAndRdn<ID extends C
     public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
     {
         parentId = ( ID ) in.readObject();
+        nbChildren = in.readInt();
+        nbDescendants = in.readInt();
         int size = in.readInt();
         rdns = new Rdn[size];
 
@@ -268,6 +311,46 @@ public class ParentIdAndRdn<ID extends C
 
 
     /**
+     * @return The number of children this entry has
+     */
+    public int getNbChildren()
+    {
+        return nbChildren;
+    }
+
+
+    /**
+     * Sets the number of children this entry has
+     * @param nbChildren The number of children
+     */
+    public void setNbChildren( int nbChildren )
+    {
+        this.nbChildren = nbChildren;
+    }
+
+
+    /**
+     * @return The number of descendants this entry has
+     */
+    public int getNbDescendants()
+    {
+        return nbDescendants;
+    }
+
+
+    /**
+     * Sets the number of descendants this entry has
+     * @param nbChildren The number of descendants
+     */
+    public void setNbDescendants( int nbDescendants )
+    {
+        this.nbDescendants = nbDescendants;
+    }
+
+
+
+
+    /**
      * {@inheritDoc}
      */
     public String toString()
@@ -277,23 +360,33 @@ public class ParentIdAndRdn<ID extends C
         sb.append( "ParentIdAndRdn<" );
         sb.append( parentId ).append( ", '" );
 
-        boolean isFirst = true;
-
-        for ( Rdn rdn : rdns )
+        if ( rdns == null )
         {
-            if ( isFirst )
-            {
-                isFirst = false;
-            }
-            else
+            sb.append( "*'>" );
+        }
+        else
+        {
+            boolean isFirst = true;
+    
+            for ( Rdn rdn : rdns )
             {
-                sb.append( "," );
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    sb.append( "," );
+                }
+    
+                sb.append( rdn );
             }
 
-            sb.append( rdn );
+            sb.append( "'>" );
+            
+            sb.append( "[nbC:" ).append( nbChildren ).append( ", nbD:" ).append( nbDescendants ).append( "]" );
         }
 
-        sb.append( "'>" );
 
         return sb.toString();
     }

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=1324744&r1=1324743&r2=1324744&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 Wed Apr 11 12:51:45 2012
@@ -22,6 +22,8 @@ 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,6 +33,9 @@ import org.apache.directory.shared.ldap.
  */
 public class SingletonIndexCursor<V, ID> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private boolean beforeFirst = true;
     private boolean afterLast;
     private boolean onSingleton;
@@ -39,6 +44,7 @@ public class SingletonIndexCursor<V, ID>
 
     public SingletonIndexCursor( IndexEntry<V, ID> singleton )
     {
+        LOG_CURSOR.debug( "Creating SingletonIndexCursor {}", this );
         this.singleton = singleton;
     }
 
@@ -190,4 +196,18 @@ public class SingletonIndexCursor<V, ID>
             throw new InvalidCursorPositionException( I18n.err( I18n.ERR_706 ) );
         }
     }
+
+
+    public void close() throws Exception
+    {
+        LOG_CURSOR.debug( "Closing SingletonIndexCursor {}", this );
+        super.close();
+    }
+
+
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing SingletonIndexCursor {}", this );
+        super.close( cause );
+    }
 }

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=1324744&r1=1324743&r2=1324744&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 Wed Apr 11 12:51:45 2012
@@ -91,7 +91,6 @@ public interface Store<E, ID extends Com
     public static final String[] SYS_INDEX_OID_ARRAY =
         {
             ApacheSchemaConstants.APACHE_PRESENCE_AT_OID,
-            ApacheSchemaConstants.APACHE_ONE_LEVEL_AT_OID,
             ApacheSchemaConstants.APACHE_SUB_LEVEL_AT_OID,
             ApacheSchemaConstants.APACHE_RDN_AT_OID,
             ApacheSchemaConstants.APACHE_ALIAS_AT_OID,
@@ -180,12 +179,6 @@ public interface Store<E, ID extends Com
 
 
     /**
-     * @return The OneLevel system index
-     */
-    Index<ID, E, ID> getOneLevelIndex();
-
-
-    /**
      * @return The SubLevel system index
      */
     Index<ID, E, ID> getSubLevelIndex();

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=1324744&r1=1324743&r2=1324744&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 Wed Apr 11 12:51:45 2012
@@ -180,6 +180,8 @@ public class AvlIndex<K, O> extends Abst
                 Tuple<Long, K> tuple = cursor.get();
                 forward.remove( tuple.getValue(), id );
             }
+            
+            cursor.close();
     
             reverse.remove( id );
         }

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=1324744&r1=1324743&r2=1324744&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 Wed Apr 11 12:51:45 2012
@@ -37,7 +37,6 @@ import org.apache.directory.shared.ldap.
  */
 public class AvlRdnIndex<E> extends AvlIndex<ParentIdAndRdn<Long>, E>
 {
-
     public AvlRdnIndex()
     {
         super();
@@ -107,6 +106,7 @@ public class AvlRdnIndex<E> extends AvlI
     public void drop( ParentIdAndRdn<Long> rdn, Long id ) throws Exception
     {
         long val = forward.get( rdn );
+        
         if ( val == id )
         {
             forward.remove( rdn );

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTable.java Wed Apr 11 12:51:45 2012
@@ -48,12 +48,12 @@ public class AvlTable<K, V> extends Abst
     private final AvlTreeMap<K, V> avl;
     private final Comparator<Tuple<K, V>> keyOnlytupleComparator;
 
-
     public AvlTable( String name, final Comparator<K> keyComparator, final Comparator<V> valueComparator,
         boolean dupsEnabled )
     {
         super( null, name, keyComparator, valueComparator );
         this.avl = new AvlTreeMapImpl<K, V>( keyComparator, valueComparator, dupsEnabled );
+        allowsDuplicates = this.avl.isDupsAllowed();
         this.keyOnlytupleComparator = new Comparator<Tuple<K, V>>()
         {
             public int compare( Tuple<K, V> t0, Tuple<K, V> t1 )
@@ -253,7 +253,7 @@ public class AvlTable<K, V> extends Abst
      */
     public boolean isDupsEnabled()
     {
-        return avl.isDupsAllowed();
+        return allowsDuplicates;
     }
 
 
@@ -271,7 +271,7 @@ public class AvlTable<K, V> extends Abst
      */
     public void put( K key, V value ) throws Exception
     {
-        if ( key == null || value == null )
+        if ( ( key == null ) || ( value == null ) )
         {
             return;
         }
@@ -328,9 +328,10 @@ public class AvlTable<K, V> extends Abst
      */
     public Cursor<Tuple<K, V>> cursor() throws Exception
     {
-        if ( !avl.isDupsAllowed() )
+        if ( !allowsDuplicates )
         {
-            return new AvlTreeMapNoDupsWrapperCursor<K, V>( new AvlSingletonOrOrderedSetCursor<K, V>( avl ) );
+            return new AvlTreeMapNoDupsWrapperCursor<K, V>( 
+                new AvlSingletonOrOrderedSetCursor<K, V>( avl ) );
         }
 
         return new AvlTableDupsCursor<K, V>( this );

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/impl/avl/AvlTableDupsCursor.java Wed Apr 11 12:51:45 2012
@@ -44,6 +44,9 @@ public class AvlTableDupsCursor<K, V> ex
 {
     private static final Logger LOG = LoggerFactory.getLogger( AvlTableDupsCursor.class.getSimpleName() );
 
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     /** The AVL backed table this Cursor traverses over. */
     private final AvlTable<K, V> table;
 
@@ -83,6 +86,7 @@ public class AvlTableDupsCursor<K, V> ex
      */
     public AvlTableDupsCursor( AvlTable<K, V> table )
     {
+        LOG_CURSOR.debug( "Creating AvlTableDupsCursor {}", this );
         this.table = table;
         this.wrappedCursor = new AvlSingletonOrOrderedSetCursor<K, V>( table.getAvlTreeMap() );
         LOG.debug( "Created on table {}", table.getName() );
@@ -114,6 +118,11 @@ public class AvlTableDupsCursor<K, V> ex
     {
         checkNotClosed( "beforeValue()" );
         wrappedCursor.beforeKey( key );
+        
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
 
         if ( wrappedCursor.next() )
         {
@@ -172,6 +181,12 @@ public class AvlTableDupsCursor<K, V> ex
     public void afterValue( K key, V value ) throws Exception
     {
         checkNotClosed( "afterValue()" );
+
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+
         /*
          * There is a subtle difference between after and before handling
          * with dupicate key values.  Say we have the following tuples:
@@ -220,6 +235,7 @@ public class AvlTableDupsCursor<K, V> ex
             if ( value == null )
             {
                 clearValue();
+                
                 return;
             }
 
@@ -258,6 +274,12 @@ public class AvlTableDupsCursor<K, V> ex
         wrappedCursor.afterLast();
         wrappedTuple.setKey( null );
         wrappedTuple.setValue( null );
+
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+
         dupsCursor = null;
     }
 
@@ -281,6 +303,12 @@ public class AvlTableDupsCursor<K, V> ex
         wrappedCursor.beforeFirst();
         wrappedTuple.setKey( null );
         wrappedTuple.setValue( null );
+
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+
         dupsCursor = null;
     }
 
@@ -292,6 +320,12 @@ public class AvlTableDupsCursor<K, V> ex
     {
         checkNotClosed( "first()" );
         clearValue();
+
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+
         dupsCursor = null;
 
         if ( wrappedCursor.first() )
@@ -317,6 +351,7 @@ public class AvlTableDupsCursor<K, V> ex
             valueAvailable = true;
             returnedTuple.setKey( wrappedTuple.getKey() );
             returnedTuple.setValue( dupsCursor.get() );
+            
             return true;
         }
 
@@ -347,8 +382,12 @@ public class AvlTableDupsCursor<K, V> ex
     {
         checkNotClosed( "last()" );
         clearValue();
-        dupsCursor = null;
-
+        
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+        
         if ( wrappedCursor.last() )
         {
             wrappedTuple.setBoth( wrappedCursor.get() );
@@ -372,6 +411,7 @@ public class AvlTableDupsCursor<K, V> ex
             valueAvailable = true;
             returnedTuple.setKey( wrappedTuple.getKey() );
             returnedTuple.setValue( dupsCursor.get() );
+            
             return true;
         }
 
@@ -385,12 +425,18 @@ public class AvlTableDupsCursor<K, V> ex
     public boolean next() throws Exception
     {
         checkNotClosed( "next()" );
+        
         /*
          * If the cursor over the values of the current key is null or is
          * extinguished then we need to advance to the next key.
          */
         if ( null == dupsCursor || !dupsCursor.next() )
         {
+            if ( dupsCursor != null )
+            {
+                dupsCursor.close();
+            }
+            
             /*
              * If the wrappedCursor cursor has more elements we get the next
              * key/AvlTree Tuple to work with and get a cursor over it.
@@ -421,6 +467,7 @@ public class AvlTableDupsCursor<K, V> ex
             else
             {
                 dupsCursor = null;
+                
                 return false;
             }
         }
@@ -434,6 +481,7 @@ public class AvlTableDupsCursor<K, V> ex
          */
         returnedTuple.setKey( wrappedTuple.getKey() );
         returnedTuple.setValue( dupsCursor.get() );
+        
         return valueAvailable = true;
     }
 
@@ -448,8 +496,13 @@ public class AvlTableDupsCursor<K, V> ex
          * If the cursor over the values of the current key is null or is
          * extinguished then we need to advance to the previous key.
          */
-        if ( null == dupsCursor || !dupsCursor.previous() )
+        if ( ( null == dupsCursor ) || !dupsCursor.previous() )
         {
+            if ( dupsCursor != null )
+            {
+                dupsCursor.close();
+            }
+            
             /*
              * If the wrappedCursor cursor has more elements we get the previous
              * key/AvlTree Tuple to work with and get a cursor over it's
@@ -481,15 +534,44 @@ public class AvlTableDupsCursor<K, V> ex
             else
             {
                 dupsCursor = null;
+                
                 return false;
             }
         }
 
         returnedTuple.setKey( wrappedTuple.getKey() );
         returnedTuple.setValue( dupsCursor.get() );
+        
         return valueAvailable = true;
     }
 
+    
+    public void close() throws Exception
+    {
+        LOG_CURSOR.debug( "Closing AvlTableDupsCursor {}", this );
+        
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+        
+        wrappedCursor.close();
+    }
+
+
+    public void close( Exception reason ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing AvlTableDupsCursor {}", this );
+
+        if ( dupsCursor != null )
+        {
+            dupsCursor.close();
+        }
+
+        wrappedCursor.close();
+    }
+
+
 
     /**
      * Clears the returned Tuple and makes sure valueAvailable returns false.

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AllEntriesCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AllEntriesCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AllEntriesCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AllEntriesCursor.java Wed Apr 11 12:51:45 2012
@@ -26,6 +26,8 @@ import org.apache.directory.server.xdbm.
 import org.apache.directory.server.xdbm.IndexEntry;
 import org.apache.directory.server.xdbm.Store;
 import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -35,6 +37,9 @@ import org.apache.directory.shared.ldap.
  */
 public class AllEntriesCursor<ID extends Comparable<ID>> extends AbstractIndexCursor<ID, Entry, ID>
 {
+    /** 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<ID, ID> indexEntry = new ForwardIndexEntry<ID, ID>();
 
@@ -58,6 +63,7 @@ public class AllEntriesCursor<ID extends
      */
     public AllEntriesCursor( Store<Entry, ID> db ) throws Exception
     {
+        LOG_CURSOR.debug( "Creating AllEntriesCursor {}", this );
         // Get a reverse cursor because we want to sort by ID
         wrapped = db.getEntryUuidIndex().reverseCursor();
     }
@@ -205,6 +211,7 @@ public class AllEntriesCursor<ID extends
     @Override
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing AllEntriesCursor {}", this );
         wrapped.close();
     }
 
@@ -215,6 +222,7 @@ public class AllEntriesCursor<ID extends
     @Override
     public void close( Exception cause ) throws Exception
     {
+        LOG_CURSOR.debug( "Closing AllEntriesCursor {}", this );
         wrapped.close( cause );
     }
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AndCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AndCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AndCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/AndCursor.java Wed Apr 11 12:51:45 2012
@@ -32,6 +32,8 @@ import org.apache.directory.server.xdbm.
 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.filter.ExprNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -41,6 +43,9 @@ import org.apache.directory.shared.ldap.
  */
 public class AndCursor<V, ID> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** 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 );
 
@@ -61,6 +66,7 @@ public class AndCursor<V, ID> extends Ab
     public AndCursor( IndexCursor<V, Entry, ID> wrapped,
         List<Evaluator<? extends ExprNode, Entry, ID>> evaluators )
     {
+        LOG_CURSOR.debug( "Creating AndCursor {}", this );
         this.wrapped = wrapped;
         this.evaluators = optimize( evaluators );
     }
@@ -175,18 +181,30 @@ public class AndCursor<V, ID> extends Ab
         throw new InvalidCursorPositionException( I18n.err( I18n.ERR_708 ) );
     }
 
-
+    
     /**
      * {@inheritDoc}
      */
-    public void close() throws Exception
+    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

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ApproximateCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ApproximateCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ApproximateCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/ApproximateCursor.java Wed Apr 11 12:51:45 2012
@@ -30,6 +30,8 @@ import org.apache.directory.shared.ldap.
 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;
 
 
 /**
@@ -45,6 +47,9 @@ import org.apache.directory.shared.ldap.
  */
 public class ApproximateCursor<V, ID extends Comparable<ID>> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** 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.";
 
@@ -67,6 +72,7 @@ public class ApproximateCursor<V, ID ext
     @SuppressWarnings("unchecked")
     public ApproximateCursor( Store<Entry, ID> db, ApproximateEvaluator<V, ID> approximateEvaluator ) throws Exception
     {
+        LOG_CURSOR.debug( "Creating ApproximateCursor {}", this );
         this.approximateEvaluator = approximateEvaluator;
 
         AttributeType attributeType = approximateEvaluator.getExpression().getAttributeType();
@@ -318,6 +324,7 @@ public class ApproximateCursor<V, ID ext
      */
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing ApproximateCursor {}", this );
         super.close();
 
         if ( userIdxCursor != null )
@@ -329,4 +336,25 @@ public class ApproximateCursor<V, ID ext
             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 );
+        }
+    }
+
+
 }
\ No newline at end of file

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=1324744&r1=1324743&r2=1324744&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 Wed Apr 11 12:51:45 2012
@@ -54,6 +54,7 @@ public class DefaultSearchEngine<ID exte
 {
     /** the Optimizer used by this DefaultSearchEngine */
     private final Optimizer optimizer;
+    
     /** the Database this DefaultSearchEngine operates on */
     private final Store<Entry, ID> db;
     /** creates Cursors over entries satisfying filter expressions */

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EqualityCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EqualityCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EqualityCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/EqualityCursor.java Wed Apr 11 12:51:45 2012
@@ -30,6 +30,8 @@ import org.apache.directory.shared.ldap.
 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;
 
 
 /**
@@ -43,6 +45,9 @@ import org.apache.directory.shared.ldap.
  */
 public class EqualityCursor<V, ID extends Comparable<ID>> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** 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_714 );
 
@@ -65,6 +70,7 @@ public class EqualityCursor<V, ID extend
     @SuppressWarnings("unchecked")
     public EqualityCursor( Store<Entry, ID> db, EqualityEvaluator<V, ID> equalityEvaluator ) throws Exception
     {
+        LOG_CURSOR.debug( "Creating EqualityCursor {}", this );
         this.equalityEvaluator = equalityEvaluator;
 
         AttributeType attributeType = equalityEvaluator.getExpression().getAttributeType();
@@ -319,6 +325,7 @@ public class EqualityCursor<V, ID extend
      */
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing EqualityCursor {}", this );
         super.close();
 
         if ( userIdxCursor != null )
@@ -330,4 +337,23 @@ public class EqualityCursor<V, ID extend
             uuidIdxCursor.close();
         }
     }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing EqualityCursor {}", this );
+        super.close( cause );
+        
+        if ( userIdxCursor != null )
+        {
+            userIdxCursor.close( cause );
+        }
+        else
+        {
+            uuidIdxCursor.close( cause );
+        }
+    }
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/GreaterEqCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/GreaterEqCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/GreaterEqCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/GreaterEqCursor.java Wed Apr 11 12:51:45 2012
@@ -30,6 +30,8 @@ import org.apache.directory.server.xdbm.
 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.schema.AttributeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -43,6 +45,9 @@ import org.apache.directory.shared.ldap.
  */
 public class GreaterEqCursor<V, ID extends Comparable<ID>> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private static final String UNSUPPORTED_MSG = "GreaterEqCursors only support positioning by element when a user index exists on the asserted attribute.";
 
     /** An greater eq evaluator for candidates */
@@ -52,14 +57,14 @@ public class GreaterEqCursor<V, ID exten
     private final IndexCursor<V, Entry, ID> userIdxCursor;
 
     /** NDN Cursor on all entries in  (set when no index on user attribute) */
-    private final IndexCursor<String, Entry, ID> ndnIdxCursor;
+    private final IndexCursor<String, Entry, ID> uuidIdxCursor;
 
     /**
-     * Used to store indexEntry from ndnCandidate so it can be saved after
+     * Used to store indexEntry from uuidCandidate so it can be saved after
      * call to evaluate() which changes the value so it's not referring to
      * the NDN but to the value of the attribute instead.
      */
-    IndexEntry<String, ID> ndnCandidate;
+    private IndexEntry<String, ID> uuidCandidate;
 
 
     /**
@@ -71,6 +76,7 @@ public class GreaterEqCursor<V, ID exten
     @SuppressWarnings("unchecked")
     public GreaterEqCursor( Store<Entry, ID> db, GreaterEqEvaluator<V, ID> greaterEqEvaluator ) throws Exception
     {
+        LOG_CURSOR.debug( "Creating GreaterEqCursor {}", this );
         this.greaterEqEvaluator = greaterEqEvaluator;
 
         AttributeType attributeType = greaterEqEvaluator.getExpression().getAttributeType();
@@ -78,11 +84,11 @@ public class GreaterEqCursor<V, ID exten
         if ( db.hasIndexOn( attributeType ) )
         {
             userIdxCursor = ( ( Index<V, Entry, ID> ) db.getIndex( attributeType ) ).forwardCursor();
-            ndnIdxCursor = null;
+            uuidIdxCursor = null;
         }
         else
         {
-            ndnIdxCursor = db.getEntryUuidIndex().forwardCursor();
+            uuidIdxCursor = db.getEntryUuidIndex().forwardCursor();
             userIdxCursor = null;
         }
     }
@@ -272,8 +278,8 @@ public class GreaterEqCursor<V, ID exten
         }
         else
         {
-            ndnIdxCursor.beforeFirst();
-            ndnCandidate = null;
+            uuidIdxCursor.beforeFirst();
+            uuidCandidate = null;
         }
 
         setAvailable( false );
@@ -293,8 +299,8 @@ public class GreaterEqCursor<V, ID exten
         }
         else
         {
-            ndnIdxCursor.afterLast();
-            ndnCandidate = null;
+            uuidIdxCursor.afterLast();
+            uuidCandidate = null;
         }
 
         setAvailable( false );
@@ -351,12 +357,12 @@ public class GreaterEqCursor<V, ID exten
             return setAvailable( false );
         }
 
-        while ( ndnIdxCursor.previous() )
+        while ( uuidIdxCursor.previous() )
         {
             checkNotClosed( "previous()" );
-            ndnCandidate = ndnIdxCursor.get();
+            uuidCandidate = uuidIdxCursor.get();
 
-            if ( greaterEqEvaluator.evaluate( ndnCandidate ) )
+            if ( greaterEqEvaluator.evaluate( uuidCandidate ) )
             {
                 return setAvailable( true );
             }
@@ -382,12 +388,12 @@ public class GreaterEqCursor<V, ID exten
             return setAvailable( userIdxCursor.next() );
         }
 
-        while ( ndnIdxCursor.next() )
+        while ( uuidIdxCursor.next() )
         {
             checkNotClosed( "next()" );
-            ndnCandidate = ndnIdxCursor.get();
+            uuidCandidate = uuidIdxCursor.get();
 
-            if ( greaterEqEvaluator.evaluate( ndnCandidate ) )
+            if ( greaterEqEvaluator.evaluate( uuidCandidate ) )
             {
                 return setAvailable( true );
             }
@@ -417,7 +423,7 @@ public class GreaterEqCursor<V, ID exten
 
         if ( available() )
         {
-            return ( IndexEntry<V, ID> ) ndnCandidate;
+            return ( IndexEntry<V, ID> ) uuidCandidate;
         }
 
         throw new InvalidCursorPositionException( I18n.err( I18n.ERR_708 ) );
@@ -429,6 +435,7 @@ public class GreaterEqCursor<V, ID exten
      */
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing GreaterEqCursor {}", this );
         super.close();
 
         if ( userIdxCursor != null )
@@ -437,7 +444,28 @@ public class GreaterEqCursor<V, ID exten
         }
         else
         {
-            ndnIdxCursor.close();
+            uuidIdxCursor.close();
+            uuidCandidate = null;
+        }
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing GreaterEqCursor {}", this );
+        super.close( cause );
+        
+        if ( userIdxCursor != null )
+        {
+            userIdxCursor.close( cause );
+        }
+        else
+        {
+            uuidIdxCursor.close( cause );
+            uuidCandidate = null;
         }
     }
 }
\ No newline at end of file

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/LessEqCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/LessEqCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/LessEqCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/LessEqCursor.java Wed Apr 11 12:51:45 2012
@@ -30,6 +30,8 @@ import org.apache.directory.server.xdbm.
 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.schema.AttributeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -43,6 +45,9 @@ import org.apache.directory.shared.ldap.
  */
 public class LessEqCursor<V, ID extends Comparable<ID>> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_716 );
 
     /** An less eq evaluator for candidates */
@@ -55,16 +60,17 @@ public class LessEqCursor<V, ID extends 
     private final IndexCursor<V, Entry, ID> uuidIdxCursor;
 
     /**
-     * Used to store indexEntry from ndnCandidate so it can be saved after
+     * Used to store indexEntry from uudCandidate so it can be saved after
      * call to evaluate() which changes the value so it's not referring to
-     * the NDN but to the value of the attribute instead.
+     * the UUID but to the value of the attribute instead.
      */
-    IndexEntry<V, ID> ndnCandidate;
+    private IndexEntry<V, ID> uuidCandidate;
 
 
     @SuppressWarnings("unchecked")
     public LessEqCursor( Store<Entry, ID> db, LessEqEvaluator<V, ID> lessEqEvaluator ) throws Exception
     {
+        LOG_CURSOR.debug( "Creating LessEqCursor {}", this );
         this.lessEqEvaluator = lessEqEvaluator;
 
         AttributeType attributeType = lessEqEvaluator.getExpression().getAttributeType();
@@ -281,7 +287,7 @@ public class LessEqCursor<V, ID extends 
         else
         {
             uuidIdxCursor.beforeFirst();
-            ndnCandidate = null;
+            uuidCandidate = null;
         }
 
         setAvailable( false );
@@ -301,7 +307,7 @@ public class LessEqCursor<V, ID extends 
         else
         {
             uuidIdxCursor.afterLast();
-            ndnCandidate = null;
+            uuidCandidate = null;
         }
 
         setAvailable( false );
@@ -339,14 +345,14 @@ public class LessEqCursor<V, ID extends 
         while ( uuidIdxCursor.previous() )
         {
             checkNotClosed( "previous()" );
-            ndnCandidate = uuidIdxCursor.get();
-            if ( lessEqEvaluator.evaluate( ndnCandidate ) )
+            uuidCandidate = uuidIdxCursor.get();
+            if ( lessEqEvaluator.evaluate( uuidCandidate ) )
             {
                 return setAvailable( true );
             }
             else
             {
-                ndnCandidate = null;
+                uuidCandidate = null;
             }
         }
 
@@ -384,15 +390,15 @@ public class LessEqCursor<V, ID extends 
         while ( uuidIdxCursor.next() )
         {
             checkNotClosed( "next()" );
-            ndnCandidate = uuidIdxCursor.get();
+            uuidCandidate = uuidIdxCursor.get();
 
-            if ( lessEqEvaluator.evaluate( ndnCandidate ) )
+            if ( lessEqEvaluator.evaluate( uuidCandidate ) )
             {
                 return setAvailable( true );
             }
             else
             {
-                ndnCandidate = null;
+                uuidCandidate = null;
             }
         }
 
@@ -416,7 +422,7 @@ public class LessEqCursor<V, ID extends 
 
         if ( available() )
         {
-            return ndnCandidate;
+            return uuidCandidate;
         }
 
         throw new InvalidCursorPositionException( I18n.err( I18n.ERR_708 ) );
@@ -425,6 +431,7 @@ public class LessEqCursor<V, ID extends 
 
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing LessEqCursor {}", this );
         super.close();
 
         if ( userIdxCursor != null )
@@ -434,7 +441,27 @@ public class LessEqCursor<V, ID extends 
         else
         {
             uuidIdxCursor.close();
-            ndnCandidate = null;
+            uuidCandidate = null;
+        }
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing LessEqCursor {}", this );
+        super.close( cause );
+        
+        if ( userIdxCursor != null )
+        {
+            userIdxCursor.close( cause );
+        }
+        else
+        {
+            uuidIdxCursor.close( cause );
+            uuidCandidate = null;
         }
     }
 }
\ No newline at end of file

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/NotCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/NotCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/NotCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/NotCursor.java Wed Apr 11 12:51:45 2012
@@ -29,6 +29,8 @@ import org.apache.directory.server.xdbm.
 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.filter.ExprNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -38,6 +40,9 @@ import org.apache.directory.shared.ldap.
  */
 public class NotCursor<V, ID extends Comparable<ID>> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_718 );
     private final IndexCursor<V, Entry, ID> uuidCursor;
     private final Evaluator<? extends ExprNode, Entry, ID> childEvaluator;
@@ -47,6 +52,7 @@ public class NotCursor<V, ID extends Com
     public NotCursor( Store<Entry, ID> store, Evaluator<? extends ExprNode, Entry, ID> childEvaluator )
         throws Exception
     {
+        LOG_CURSOR.debug( "Creating NotCursor {}", this );
         this.childEvaluator = childEvaluator;
         this.uuidCursor = ( IndexCursor<V, Entry, ID> ) store.getEntryUuidIndex().forwardCursor();
     }
@@ -142,7 +148,16 @@ public class NotCursor<V, ID extends Com
 
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing NotCursor {}", this );
         super.close();
         uuidCursor.close();
     }
+
+
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing NotCursor {}", this );
+        super.close( cause );
+        uuidCursor.close( cause );
+    }
 }

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeCursor.java Wed Apr 11 12:51:45 2012
@@ -22,12 +22,17 @@ package org.apache.directory.server.xdbm
 
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.server.xdbm.AbstractIndexCursor;
+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.ParentIdAndRdn;
 import org.apache.directory.server.xdbm.Store;
 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.name.Rdn;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -38,6 +43,9 @@ import org.apache.directory.shared.ldap.
  */
 public class OneLevelScopeCursor<ID extends Comparable<ID>> extends AbstractIndexCursor<ID, Entry, ID>
 {
+    /** 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 );
 
@@ -49,7 +57,7 @@ public class OneLevelScopeCursor<ID exte
     private final OneLevelScopeEvaluator evaluator;
 
     /** A Cursor over the entries in the scope of the search base */
-    private final IndexCursor<ID, Entry, ID> scopeCursor;
+    private final IndexCursor scopeCursor;
 
     /** A Cursor over entries brought into scope by alias dereferencing */
     private final Cursor<IndexEntry<ID, ID>> dereferencedCursor;
@@ -69,9 +77,19 @@ public class OneLevelScopeCursor<ID exte
     public OneLevelScopeCursor( Store<Entry, ID> db, OneLevelScopeEvaluator<Entry, ID> evaluator )
         throws Exception
     {
+        LOG_CURSOR.debug( "Creating OneLevelScopeCursor {}", this );
         this.db = db;
         this.evaluator = evaluator;
-        scopeCursor = db.getOneLevelIndex().forwardCursor( evaluator.getBaseId() );
+
+        // We use the RdnIndex to get all the entries from a starting point
+        // and below up to the number of children
+        IndexCursor<ParentIdAndRdn<ID>,Entry, ID> cursor = db.getRdnIndex().forwardCursor();
+        
+        IndexEntry<ParentIdAndRdn<ID>, ID> startingPos = new ForwardIndexEntry<ParentIdAndRdn<ID>, ID>();
+        startingPos.setValue( new ParentIdAndRdn( evaluator.getBaseId(), (Rdn[]) null ) );
+        cursor.before( startingPos );
+
+        scopeCursor = new ChildrenCursor( db, evaluator.getBaseId(), cursor );
 
         if ( evaluator.isDereferencing() )
         {
@@ -282,6 +300,13 @@ public class OneLevelScopeCursor<ID exte
     @Override
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing OneLevelScopeCursor {}", this );
+        
+        if ( cursor != null )
+        {
+            cursor.close();
+        }
+        
         scopeCursor.close();
 
         if ( dereferencedCursor != null )
@@ -296,6 +321,13 @@ public class OneLevelScopeCursor<ID exte
     @Override
     public void close( Exception cause ) throws Exception
     {
+        LOG_CURSOR.debug( "Closing OneLevelScopeCursor {}", this );
+        
+        if ( cursor != null )
+        {
+            cursor.close( cause );
+        }
+
         scopeCursor.close( cause );
 
         if ( dereferencedCursor != null )

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeEvaluator.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeEvaluator.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OneLevelScopeEvaluator.java Wed Apr 11 12:51:45 2012
@@ -22,6 +22,7 @@ package org.apache.directory.server.xdbm
 
 import org.apache.directory.server.i18n.I18n;
 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.server.xdbm.search.Evaluator;
 import org.apache.directory.shared.ldap.model.filter.ScopeNode;
@@ -81,7 +82,8 @@ public class OneLevelScopeEvaluator<E, I
      */
     public boolean evaluateId( ID candidate ) throws Exception
     {
-        boolean isChild = db.getOneLevelIndex().forward( baseId, candidate );
+        ParentIdAndRdn<ID> parent = db.getRdnIndex().reverseLookup( candidate );
+        boolean isChild = parent.getParentId().equals( baseId );
 
         /*
          * The candidate id could be any entry in the db.  If search
@@ -152,7 +154,8 @@ public class OneLevelScopeEvaluator<E, I
      */
     public boolean evaluate( IndexEntry<?, ID> candidate ) throws Exception
     {
-        boolean isChild = db.getOneLevelIndex().forward( baseId, candidate.getId() );
+        ParentIdAndRdn<ID> parent = db.getRdnIndex().reverseLookup( candidate.getId() );
+        boolean isChild = parent.getParentId().equals( baseId );
 
         /*
          * The candidate id could be any entry in the db.  If search

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OrCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OrCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OrCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/OrCursor.java Wed Apr 11 12:51:45 2012
@@ -34,6 +34,8 @@ import org.apache.directory.shared.ldap.
 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.filter.ExprNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -43,6 +45,9 @@ import org.apache.directory.shared.ldap.
  */
 public class OrCursor<V, ID> extends AbstractIndexCursor<V, Entry, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_722 );
     private final List<IndexCursor<V, Entry, ID>> cursors;
     private final List<Evaluator<? extends ExprNode, Entry, ID>> evaluators;
@@ -54,6 +59,8 @@ public class OrCursor<V, ID> extends Abs
     public OrCursor( List<IndexCursor<V, Entry, ID>> cursors,
         List<Evaluator<? extends ExprNode, Entry, ID>> evaluators )
     {
+        LOG_CURSOR.debug( "Creating OrCursor {}", this );
+        
         if ( cursors.size() <= 1 )
         {
             throw new IllegalArgumentException( I18n.err( I18n.ERR_723 ) );
@@ -63,10 +70,11 @@ public class OrCursor<V, ID> extends Abs
         this.evaluators = evaluators;
         this.blacklists = new ArrayList<Set<ID>>();
 
-        for ( int ii = 0; ii < cursors.size(); ii++ )
+        for ( int i = 0; i < cursors.size(); i++ )
         {
             this.blacklists.add( new HashSet<ID>() );
         }
+        
         this.cursorIndex = 0;
     }
 
@@ -235,10 +243,24 @@ public class OrCursor<V, ID> extends Abs
 
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing OrCursor {}", this );
         super.close();
+        
         for ( Cursor<?> cursor : cursors )
         {
             cursor.close();
         }
     }
+
+
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing OrCursor {}", this );
+        super.close( cause );
+        
+        for ( Cursor<?> cursor : cursors )
+        {
+            cursor.close( cause );
+        }
+    }
 }
\ No newline at end of file

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/PresenceCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/PresenceCursor.java?rev=1324744&r1=1324743&r2=1324744&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/PresenceCursor.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/xdbm/search/impl/PresenceCursor.java Wed Apr 11 12:51:45 2012
@@ -28,6 +28,8 @@ import org.apache.directory.server.xdbm.
 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.schema.AttributeType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -37,6 +39,9 @@ import org.apache.directory.shared.ldap.
  */
 public class PresenceCursor<ID extends Comparable<ID>> extends AbstractIndexCursor<String, Entry, ID>
 {
+    /** A dedicated log for cursors */
+    private static final Logger LOG_CURSOR = LoggerFactory.getLogger( "CURSOR" );
+
     private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_724 );
     private final IndexCursor<String, Entry, ID> uuidCursor;
     private final IndexCursor<String, Entry, ID> presenceCursor;
@@ -45,6 +50,7 @@ public class PresenceCursor<ID extends C
 
     public PresenceCursor( Store<Entry, ID> store, PresenceEvaluator<ID> presenceEvaluator ) throws Exception
     {
+        LOG_CURSOR.debug( "Creating PresenceCursor {}", this );
         this.presenceEvaluator = presenceEvaluator;
         AttributeType type = presenceEvaluator.getAttributeType();
 
@@ -295,6 +301,7 @@ public class PresenceCursor<ID extends C
 
     public void close() throws Exception
     {
+        LOG_CURSOR.debug( "Closing PresenceCursor {}", this );
         super.close();
 
         if ( presenceCursor != null )
@@ -306,4 +313,20 @@ public class PresenceCursor<ID extends C
             uuidCursor.close();
         }
     }
+
+
+    public void close( Exception cause ) throws Exception
+    {
+        LOG_CURSOR.debug( "Closing PresenceCursor {}", this );
+        super.close( cause );
+
+        if ( presenceCursor != null )
+        {
+            presenceCursor.close( cause );
+        }
+        else
+        {
+            uuidCursor.close( cause );
+        }
+    }
 }