You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sa...@apache.org on 2011/10/20 14:59:48 UTC

svn commit: r1186778 - in /directory/apacheds/branches/apacheds-txns: core-api/src/main/java/org/apache/directory/server/core/partition/index/ core-api/src/main/java/org/apache/directory/server/core/txn/ core-api/src/main/java/org/apache/directory/serv...

Author: saya
Date: Thu Oct 20 12:59:47 2011
New Revision: 1186778

URL: http://svn.apache.org/viewvc?rev=1186778&view=rev
Log:
added IndexWrapper and completed MasterTableWrapper.

For index cursors,  null values are used skip whole set of values corresponding to a key. Also an index cursor can be created to traverse just over the values corresponding to a key. I changed TxnIndexCursor to account for these cases.

IndexWrapper mostly uses IndexCursorWrapper to do lookups and return cursors.

Master table wrapper used mergeUpdates of the log manager to get the current view of the entry it reads from the wrapped partition.


Added:
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/IndexComparator.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/AbstractDataChange.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/DataChange.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexWrapper.java
Modified:
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ForwardIndexComparator.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ReverseIndexComparator.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/TxnLogManager.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/MasterTableWrapper.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/ReadWriteTxn.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ForwardIndexComparator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ForwardIndexComparator.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ForwardIndexComparator.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ForwardIndexComparator.java Thu Oct 20 12:59:47 2011
@@ -3,10 +3,10 @@ package org.apache.directory.server.core
 
 import java.util.Comparator;
 
-public class ForwardIndexComparator<V, ID> implements Comparator<IndexEntry<V,ID>>
+public class ForwardIndexComparator<V, ID> implements IndexComparator<V,ID>
 {
-    Comparator<V> keyComparator;
-    Comparator<ID> valueComparator;
+    private Comparator<V> keyComparator;
+    private Comparator<ID> valueComparator;
     
     public ForwardIndexComparator( Comparator<V> keyComparator, Comparator<ID> valueComparator )
     {
@@ -45,4 +45,15 @@ public class ForwardIndexComparator<V, I
         
         return result;
     }
+    
+    public Comparator<V> getValueComparator()
+    {
+        return keyComparator;
+    }
+    
+    
+    public Comparator<ID> getIDComparator()
+    {
+        return valueComparator;
+    }
 }

Added: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/IndexComparator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/IndexComparator.java?rev=1186778&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/IndexComparator.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/IndexComparator.java Thu Oct 20 12:59:47 2011
@@ -0,0 +1,12 @@
+
+package org.apache.directory.server.core.partition.index;
+
+import java.util.Comparator;
+
+public interface IndexComparator<V,ID> extends Comparator<IndexEntry<V,ID>>
+{
+    public Comparator<V> getValueComparator();
+    
+    
+    public Comparator<ID> getIDComparator();
+}

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ReverseIndexComparator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ReverseIndexComparator.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ReverseIndexComparator.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/partition/index/ReverseIndexComparator.java Thu Oct 20 12:59:47 2011
@@ -3,7 +3,7 @@ package org.apache.directory.server.core
 
 import java.util.Comparator;
 
-public class ReverseIndexComparator<V, ID> implements Comparator<IndexEntry<V, ID>>
+public class ReverseIndexComparator<V, ID> implements IndexComparator<V,ID>
 {
     Comparator<V> keyComparator;
     Comparator<ID> valueComparator;
@@ -45,4 +45,15 @@ public class ReverseIndexComparator<V, I
         
         return result;
     }
+    
+    public Comparator<V> getValueComparator()
+    {
+        return keyComparator;
+    }
+    
+    
+    public Comparator<ID> getIDComparator()
+    {
+        return valueComparator;
+    }
 }

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/TxnLogManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/TxnLogManager.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/TxnLogManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/TxnLogManager.java Thu Oct 20 12:59:47 2011
@@ -1,6 +1,8 @@
 
 package org.apache.directory.server.core.txn;
 
+import org.apache.directory.server.core.partition.index.IndexCursor;
+import org.apache.directory.server.core.partition.index.IndexComparator;
 import org.apache.directory.server.core.txn.logedit.LogEdit;
 
 import org.apache.directory.server.core.log.UserLogRecord;
@@ -8,6 +10,7 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.name.Dn;
 
 import java.io.IOException;
+import java.util.Comparator;
 
 public interface TxnLogManager<ID>
 {
@@ -16,4 +19,6 @@ public interface TxnLogManager<ID>
     public void log( UserLogRecord logRecord, boolean sync ) throws IOException;
     
     public Entry mergeUpdates(Dn partitionDN, ID entryID,  Entry entry );
+    
+    public IndexCursor<Object, Entry, ID> wrap( Dn partitionDn, IndexCursor<Object, Entry, ID> wrappedCursor, IndexComparator<Object,ID> comparator, String attributeOid, boolean forwardIndex, Object onlyValueKey, ID onlyIDKey ) throws Exception;
 }

Added: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/AbstractDataChange.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/AbstractDataChange.java?rev=1186778&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/AbstractDataChange.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/AbstractDataChange.java Thu Oct 20 12:59:47 2011
@@ -0,0 +1,7 @@
+
+package org.apache.directory.server.core.txn.logedit;
+
+public abstract class AbstractDataChange<ID> implements DataChange<ID>
+{
+
+}

Added: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/DataChange.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/DataChange.java?rev=1186778&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/DataChange.java (added)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/txn/logedit/DataChange.java Thu Oct 20 12:59:47 2011
@@ -0,0 +1,9 @@
+
+package org.apache.directory.server.core.txn.logedit;
+
+import java.io.Externalizable;
+
+public interface DataChange<ID> extends Externalizable
+{
+
+}

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/DefaultTxnLogManager.java Thu Oct 20 12:59:47 2011
@@ -4,10 +4,13 @@ package org.apache.directory.server.core
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
+import java.util.Comparator;
 
 import org.apache.directory.server.core.log.UserLogRecord;
 import org.apache.directory.server.core.log.Log;
 import org.apache.directory.server.core.log.InvalidLogException;
+import org.apache.directory.server.core.partition.index.IndexCursor;
+import org.apache.directory.server.core.partition.index.IndexComparator;
 
 import org.apache.directory.shared.ldap.model.entry.Entry;
 import org.apache.directory.shared.ldap.model.name.Dn;
@@ -108,5 +111,11 @@ public class DefaultTxnLogManager<ID> im
        return curTxn.mergeUpdates( partitionDn, entryID, entry );
    }
    
-   
+   /**
+    * {@inheritDoc}
+    */
+   public IndexCursor<Object, Entry, ID> wrap( Dn partitionDn, IndexCursor<Object, Entry, ID> wrappedCursor, IndexComparator<Object,ID> comparator, String attributeOid, boolean forwardIndex, Object onlyValueKey, ID onlyIDKey ) throws Exception
+   {
+       return new IndexCursorWrapper<ID>( partitionDn, wrappedCursor, comparator, attributeOid, forwardIndex, onlyValueKey, onlyIDKey );
+   }
 }

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexCursorWrapper.java Thu Oct 20 12:59:47 2011
@@ -3,23 +3,26 @@ package org.apache.directory.server.core
 
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.List;
 
 import org.apache.directory.server.core.partition.index.AbstractIndexCursor;
 import org.apache.directory.server.core.partition.index.ForwardIndexEntry;
 import org.apache.directory.server.core.partition.index.IndexCursor;
 import org.apache.directory.server.core.partition.index.IndexEntry;
+import org.apache.directory.server.core.partition.index.IndexComparator;
 import org.apache.directory.server.i18n.I18n;
 
 import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
 import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.entry.Entry;;
 
-public class IndexCursorWrapper<V, E, ID> extends AbstractIndexCursor<V, E, ID>
+public class IndexCursorWrapper<ID> extends AbstractIndexCursor<Object, Entry, ID>
 {
     /** Cursors to merge */
-    private ArrayList<IndexCursor<V,E,ID>> cursors;
+    private ArrayList<IndexCursor<Object, Entry, ID>> cursors;
     
     /** list of values available per cursor */
-    private ArrayList<IndexEntry<V,ID>> values;
+    private ArrayList<IndexEntry<Object,ID>> values;
     
     /** index get should get the value from */
     private int getIndex = -1;
@@ -43,21 +46,61 @@ public class IndexCursorWrapper<V, E, ID
     boolean movingNext = true;
     
     /** Comparator used to order the index entries */
-    private Comparator<IndexEntry<V,ID>> comparator;
+    private IndexComparator<Object,ID> comparator;
     
     /** unsupported operation message */
     private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_722 );
     
     
+    public IndexCursorWrapper( Dn partitionDn, IndexCursor<Object, Entry, ID> wrappedCursor, IndexComparator<Object,ID> comparator, String attributeOid, boolean forwardIndex, Object onlyValueKey, ID onlyIDKey )
+    {
+        
+        this.partitionDn = partitionDn;
+        this.forwardIndex = forwardIndex;
+        this.attributeOid = attributeOid;
+        this.comparator = comparator;
+        
+        
+        TxnManagerInternal<ID> txnManager = TxnManagerFactory.<ID>txnManagerInternalInstance();      
+        Transaction<ID> curTxn = txnManager.getCurTxn();  
+        List<ReadWriteTxn<ID>> toCheck = curTxn.getTxnsToCheck(); 
+        
+        cursors = new ArrayList<IndexCursor<Object, Entry, ID>>( toCheck.size() + 1 );
+        cursors.add( ( IndexCursor<Object, Entry, ID> )wrappedCursor );
+        
+        if ( toCheck.size() > 0 )
+        {
+            txns = new ArrayList<ReadWriteTxn<ID>>( toCheck.size() );
+            
+            ReadWriteTxn<ID> dependentTxn;
+            
+            for ( int idx = 0; idx < toCheck.size(); idx++ )
+            {
+                dependentTxn = toCheck.get( idx );
+                
+                if ( dependentTxn.hasDeletesFor( partitionDn, attributeOid ) )
+                {
+                    txns.add( dependentTxn );
+                }
+                else
+                {
+                    txns.add( null );
+                }
+                
+                cursors.add( dependentTxn.getCursorFor( partitionDn, attributeOid, forwardIndex, onlyValueKey, onlyIDKey, comparator ) );
+            }
+        }
+    }
+    
     /**
      * {@inheritDoc}
      */
-    public void after( IndexEntry<V, ID> element ) throws Exception
+    public void after( IndexEntry<Object, ID> element ) throws Exception
     {
         int idx;
         positioned = true;
         movingNext = true;
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         
         checkNotClosed( "after()" );
         
@@ -77,12 +120,12 @@ public class IndexCursorWrapper<V, E, ID
     /**
      * {@inheritDoc}
      */
-    public void before( IndexEntry<V, ID> element ) throws Exception
+    public void before( IndexEntry<Object, ID> element ) throws Exception
     {
         int idx;
         positioned = true;
         movingNext = true;
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         
         checkNotClosed( "before()" );
         
@@ -103,12 +146,12 @@ public class IndexCursorWrapper<V, E, ID
     /**
      * {@inheritDoc}
      */
-    public void afterValue( ID id, V value ) throws Exception
+    public void afterValue( ID id, Object value ) throws Exception
     {
         int idx;
         positioned = true;
         movingNext = true;
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         
         checkNotClosed( "afterValue()" );
         
@@ -129,12 +172,12 @@ public class IndexCursorWrapper<V, E, ID
     /**
      * {@inheritDoc}
      */
-    public void beforeValue( ID id, V value ) throws Exception
+    public void beforeValue( ID id, Object value ) throws Exception
     {
         int idx;
         positioned = true;
         movingNext = true;
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         
         checkNotClosed( "beforeValue()" );
         
@@ -160,7 +203,7 @@ public class IndexCursorWrapper<V, E, ID
         int idx;
         positioned = true;
         movingNext = true;
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         
         checkNotClosed( "beforeFirst()" );
         
@@ -186,7 +229,7 @@ public class IndexCursorWrapper<V, E, ID
         int idx;
         positioned = true;
         movingNext = false;
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         
         checkNotClosed( "afterLast()" );
         
@@ -227,13 +270,13 @@ public class IndexCursorWrapper<V, E, ID
      */
     public boolean next() throws Exception
     {
-        IndexCursor<V,E,ID> cursor;
-        IndexEntry<V,ID> minValue;
-        IndexEntry<V,ID> value;
+        IndexCursor<Object,Entry,ID> cursor;
+        IndexEntry<Object,ID> minValue;
+        IndexEntry<Object,ID> value;
         
         checkNotClosed( "next()" );
         
-        IndexEntry<V,ID> lastValue = null;
+        IndexEntry<Object,ID> lastValue = null;
         if ( getIndex >= 0 )
         {
             lastValue = values.get( getIndex );
@@ -327,13 +370,13 @@ public class IndexCursorWrapper<V, E, ID
      */
     public boolean previous() throws Exception
     {
-        IndexCursor<V,E,ID> cursor;
-        IndexEntry<V,ID> maxValue;
-        IndexEntry<V,ID> value;
+        IndexCursor<Object,Entry,ID> cursor;
+        IndexEntry<Object,ID> maxValue;
+        IndexEntry<Object,ID> value;
         
         checkNotClosed( "previous()" );
         
-        IndexEntry<V,ID> lastValue = null;
+        IndexEntry<Object,ID> lastValue = null;
         if ( getIndex >= 0 )
         {
             lastValue = values.get( getIndex );
@@ -426,13 +469,13 @@ public class IndexCursorWrapper<V, E, ID
     /**
      * {@inheritDoc}
      */
-    public IndexEntry<V, ID> get() throws Exception
+    public IndexEntry<Object, ID> get() throws Exception
     {
         checkNotClosed( "get()" );
         
         if ( getIndex >= 0 )
         {
-            IndexEntry<V,ID> value = values.get( getIndex );
+            IndexEntry<Object,ID> value = values.get( getIndex );
             
             if ( value == null )
             {
@@ -455,7 +498,7 @@ public class IndexCursorWrapper<V, E, ID
         
         super.close();
         
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         int idx;
         
         for ( idx = 0; idx < cursors.size(); idx++ )
@@ -477,7 +520,7 @@ public class IndexCursorWrapper<V, E, ID
     {
         super.close( cause );
         
-        IndexCursor<V,E,ID> cursor;
+        IndexCursor<Object,Entry,ID> cursor;
         int idx;
         
         for ( idx = 0; idx < cursors.size(); idx++ )
@@ -501,9 +544,9 @@ public class IndexCursorWrapper<V, E, ID
     
     private void recomputeMinimum() throws Exception
     {
-        IndexCursor<V,E,ID> cursor;
-        IndexEntry<V,ID> minValue;
-        IndexEntry<V,ID> value;
+        IndexCursor<Object,Entry,ID> cursor;
+        IndexEntry<Object,ID> minValue;
+        IndexEntry<Object,ID> value;
         int idx;
         
         cursor = cursors.get( getIndex );
@@ -535,9 +578,9 @@ public class IndexCursorWrapper<V, E, ID
     
     private void recomputeMaximum() throws Exception
     {
-        IndexCursor<V,E,ID> cursor;
-        IndexEntry<V,ID> maxValue;
-        IndexEntry<V,ID> value;
+        IndexCursor<Object,Entry,ID> cursor;
+        IndexEntry<Object,ID> maxValue;
+        IndexEntry<Object,ID> value;
         int idx;
         
         cursor = cursors.get( getIndex );

Added: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexWrapper.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexWrapper.java?rev=1186778&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexWrapper.java (added)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/IndexWrapper.java Thu Oct 20 12:59:47 2011
@@ -0,0 +1,633 @@
+
+package org.apache.directory.server.core.txn;
+
+
+import java.net.URI;
+import java.util.Comparator;
+
+import org.apache.directory.server.core.partition.index.ForwardIndexComparator;
+import org.apache.directory.server.core.partition.index.Index;
+import org.apache.directory.server.core.partition.index.IndexCursor;
+import org.apache.directory.server.core.partition.index.ReverseIndexComparator;
+
+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.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+
+public class IndexWrapper<ID> implements Index<Object, Entry, ID>
+{
+    /** wrapped index */ 
+    Index<Object,Entry,ID> wrappedIndex;
+    
+    /** partition the table belongs to */
+    private Dn partitionDn;
+   
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getAttributeId()
+    {
+        return wrappedIndex.getAttributeId();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setAttributeId( String attributeId )
+    {
+        wrappedIndex.setAttributeId( attributeId );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getCacheSize()
+    {
+        return wrappedIndex.getCacheSize();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setCacheSize( int cacheSize )
+    {
+        wrappedIndex.setCacheSize( cacheSize );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setWkDirPath( URI wkDirPath )
+    {
+        wrappedIndex.setWkDirPath( wkDirPath );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public URI getWkDirPath()
+    {
+        return wrappedIndex.getWkDirPath();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public AttributeType getAttribute()
+    {
+        return wrappedIndex.getAttribute();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getNormalized( Object attrVal ) throws Exception
+    {
+        return wrappedIndex.getNormalized( attrVal );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int count() throws Exception
+    {
+        return wrappedIndex.count();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int count( Object attrVal ) throws Exception
+    {
+        return wrappedIndex.count( attrVal );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int greaterThanCount( Object attrVal ) throws Exception
+    {
+        return wrappedIndex.greaterThanCount( attrVal );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public int lessThanCount( Object attrVal ) throws Exception
+    {
+        return wrappedIndex.lessThanCount( attrVal );
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public ID forwardLookup( Object attrVal ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor( attrVal );
+        
+        try
+        {
+            cursor.beforeValue( null, attrVal );
+            if ( cursor.next() )
+            {
+                return cursor.get().getId();
+            }
+            
+            return null;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object reverseLookup( ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor( id );
+        
+        try
+        {
+            cursor.beforeValue( id, null );
+            if ( cursor.next() )
+            {
+                return cursor.get().getValue();
+            }
+            
+            return null;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void add( Object attrVal, ID id ) throws Exception
+    {
+        wrappedIndex.add( attrVal, id );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void drop( ID entryId ) throws Exception
+    {
+        wrappedIndex.drop( entryId );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void drop( Object attrVal, ID id ) throws Exception
+    {
+        wrappedIndex.drop( attrVal, id );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public IndexCursor<Object, Entry, ID> reverseCursor() throws Exception
+    {
+        IndexCursor<Object, Entry, ID> wrappedCursor;
+        IndexCursor<Object, Entry, ID> cursor = wrappedIndex.reverseCursor();
+        TxnLogManager<ID> logManager = TxnManagerFactory.<ID>txnLogManagerInstance();
+        
+        try
+        {
+            wrappedCursor = logManager.wrap( partitionDn, cursor, wrappedIndex.getReverseIndexEntryComparator(), 
+                wrappedIndex.getAttribute().getOid(), false, null, null );
+        } catch (Exception e)
+        {
+            cursor.close( e );
+            throw e;
+        }
+        
+        return wrappedCursor;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public IndexCursor<Object, Entry, ID> forwardCursor() throws Exception
+    {
+        IndexCursor<Object, Entry, ID> wrappedCursor;
+        IndexCursor<Object, Entry, ID> cursor = wrappedIndex.reverseCursor();
+        TxnLogManager<ID> logManager = TxnManagerFactory.<ID>txnLogManagerInstance();
+        
+        try
+        {
+            wrappedCursor = logManager.wrap( partitionDn, cursor, wrappedIndex.getForwardIndexEntryComparator(), 
+                wrappedIndex.getAttribute().getOid(), true, null, null );
+        } catch (Exception e)
+        {
+            cursor.close( e );
+            throw e;
+        }
+        
+        return wrappedCursor;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public IndexCursor<Object, Entry, ID> reverseCursor( ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> wrappedCursor;
+        IndexCursor<Object, Entry, ID> cursor = wrappedIndex.reverseCursor();
+        TxnLogManager<ID> logManager = TxnManagerFactory.<ID>txnLogManagerInstance();
+        
+        try
+        {
+            wrappedCursor = logManager.wrap( partitionDn, cursor, wrappedIndex.getReverseIndexEntryComparator(), 
+                wrappedIndex.getAttribute().getOid(), false, null, id );
+        } catch (Exception e)
+        {
+            cursor.close( e );
+            throw e;
+        }
+        
+        return wrappedCursor;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public IndexCursor<Object, Entry, ID> forwardCursor( Object key ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> wrappedCursor;
+        IndexCursor<Object, Entry, ID> cursor = wrappedIndex.reverseCursor();
+        TxnLogManager<ID> logManager = TxnManagerFactory.<ID>txnLogManagerInstance();
+        
+        try
+        {
+            wrappedCursor = logManager.wrap( partitionDn, cursor, wrappedIndex.getForwardIndexEntryComparator(), 
+                wrappedIndex.getAttribute().getOid(), true, key, null );
+        } catch (Exception e)
+        {
+            cursor.close( e );
+            throw e;
+        }
+        
+        return wrappedCursor;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Cursor<Object> reverseValueCursor( ID id ) throws Exception
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Cursor<ID> forwardValueCursor( Object key ) throws Exception
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean forward( Object attrVal ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor( attrVal );
+        
+        try
+        {
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean forward( Object attrVal, ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor( attrVal );
+        Comparator<ID> idComp = wrappedIndex.getForwardIndexEntryComparator().getIDComparator();
+        
+        try
+        {
+            cursor.beforeValue( id, attrVal );
+            if ( cursor.next() && ( idComp.compare( cursor.get().getId(), id ) == 0 ) )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }   
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean reverse( ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor( id );
+        
+        try
+        {
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean reverse( ID id, Object attrVal ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor( id );
+        Comparator<Object> valueComp = wrappedIndex.getForwardIndexEntryComparator().getValueComparator();
+        
+        try
+        {
+            cursor.beforeValue( id, attrVal );
+            if ( cursor.next() && ( valueComp.compare( cursor.get().getValue(), attrVal ) == 0 ))
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean forwardGreaterOrEq( Object attrVal ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor();
+        
+        try
+        {
+            cursor.beforeValue( null, attrVal );
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean forwardGreaterOrEq( Object attrVal, ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor();
+        
+        try
+        {
+            cursor.beforeValue( id, attrVal );
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean reverseGreaterOrEq( ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor();
+        
+        try
+        {
+            cursor.beforeValue( id, null );
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean reverseGreaterOrEq( ID id, Object attrVal ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor();
+        
+        try
+        {
+            cursor.beforeValue( id, attrVal );
+            if ( cursor.next() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean forwardLessOrEq( Object attrVal ) throws Exception
+    {
+
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor();
+        
+        try
+        {
+            cursor.afterValue( null, attrVal );
+            if ( cursor.previous() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean forwardLessOrEq( Object attrVal, ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.forwardCursor();
+        
+        try
+        {
+            cursor.afterValue( id, attrVal );
+            if ( cursor.previous() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean reverseLessOrEq( ID id ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor();
+        
+        try
+        {
+            cursor.afterValue( id, null );
+            if ( cursor.previous() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean reverseLessOrEq( ID id, Object attrVal ) throws Exception
+    {
+        IndexCursor<Object, Entry, ID> cursor = this.reverseCursor();
+        
+        try
+        {
+            cursor.afterValue( id, attrVal );
+            if ( cursor.previous() )
+            {
+                return true;
+            }
+            
+            return false;
+        }
+        finally
+        {
+            cursor.close();
+        }
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    public ForwardIndexComparator<Object,ID> getForwardIndexEntryComparator()
+    {
+        return wrappedIndex.getForwardIndexEntryComparator();
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public ReverseIndexComparator<Object,ID> getReverseIndexEntryComparator()
+    {
+        return wrappedIndex.getReverseIndexEntryComparator();
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void close() throws Exception
+    {
+        wrappedIndex.close();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void sync() throws Exception
+    {
+        wrappedIndex.sync();
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isDupsEnabled()
+    {
+        return wrappedIndex.isDupsEnabled();
+    }
+}

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/MasterTableWrapper.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/MasterTableWrapper.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/MasterTableWrapper.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/MasterTableWrapper.java Thu Oct 20 12:59:47 2011
@@ -8,11 +8,16 @@ import org.apache.directory.shared.ldap.
 import org.apache.directory.shared.ldap.model.cursor.Tuple;
 
 import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.apache.directory.shared.ldap.model.name.Dn;
 
-public class MasterTableWrapper<ID, Entry> implements MasterTable<ID, Entry>
+public class MasterTableWrapper<ID> implements MasterTable<ID, Entry>
 {
+    /** Wrapped master table */
     private MasterTable<ID, Entry> wrappedTable;
     
+    /** partition the table belongs to */
+    private Dn partitionDn;
+    
     /**
      * {@inheritDoc}
      */
@@ -66,246 +71,175 @@ public class MasterTableWrapper<ID, Entr
     }
 
 
-    // ------------------------------------------------------------------------
-    // Simple Table Key/Value Assertions 
-    // ------------------------------------------------------------------------
-
+   
     /**
-     * Checks to see if this table has one or more tuples with a specific key:
-     * this is exactly the same as a get call with a check to see if the
-     * returned value is null or not.
-     *
-     * @param key the Object of the key to check for
-     * @return true if the key exists, false otherwise
-     * @throws Exception if there is a failure to read the underlying Db
+     * {@inheritDoc}
      */
-    boolean has( K key ) throws Exception;
+    public boolean has( ID key ) throws Exception
+    {
+        return ( this.get( key ) != null );
+    }
 
 
     /**
-     * Checks to see if this table has a key with a specific value.
-     *
-     * @param key the key to check for
-     * @param value the value to check for
-     * @return true if a record with the key and value exists, false otherwise
-     * @throws Exception if there is a failure to read the underlying Db
+     * {@inheritDoc}
      */
-    boolean has( K key, V value ) throws Exception;
+    public boolean has( ID key, Entry value ) throws Exception
+    {
+        Entry stored = this.get( key );
+        
+        return ( stored != null && stored.equals( value ) );
+    }
 
 
     /**
-     * Checks to see if this table has a record with a key greater than or
-     * equal to the key argument.  The key argument need not exist for this
-     * call to return true.  The underlying database must sort keys based on a
-     * key comparator because this method depends on key ordering.
-     *
-     * @param key the key to compare keys to
-     * @return true if a Tuple with a key greater than or equal to the key
-     * argument exists, false otherwise
-     * @throws Exception if there is a failure to read the underlying Db
+     * {@inheritDoc}
      */
-    boolean hasGreaterOrEqual( K key ) throws Exception;
+    public boolean hasGreaterOrEqual( ID key ) throws Exception
+    {
+        return wrappedTable.hasGreaterOrEqual( key );
+    }
 
 
     /**
-     * Checks to see if this table has a record with a key less than or
-     * equal to the key argument.  The key argument need not exist for this
-     * call to return true.  The underlying database must sort keys based on a
-     * key comparator because this method depends on key ordering.
-     *
-     * @param key the key to compare keys to
-     * @return true if a Tuple with a key less than or equal to the key
-     * argument exists, false otherwise
-     * @throws Exception if there is a failure to read the underlying Db
+     * {@inheritDoc}
      */
-    boolean hasLessOrEqual( K key ) throws Exception;
+    public boolean hasLessOrEqual( ID key ) throws Exception
+    {
+        return wrappedTable.hasLessOrEqual( key );
+    }
 
 
     /**
-     * Checks to see if this table has a Tuple with a key equal to the key
-     * argument, yet with a value greater than or equal to the value argument
-     * provided.  The key argument <strong>MUST</strong> exist for this call
-     * to return true and the underlying Db must allow for values of duplicate
-     * keys to be sorted.  The entire basis to this method depends on the fact
-     * that tuples of the same key have values sorted according to a valid
-     * value comparator.
-     *
-     * If the table does not support duplicates then an
-     * UnsupportedOperationException is thrown.
-     *
-     * @param key the key
-     * @param val the value to compare values to
-     * @return true if a Tuple with a key equal to the key argument and a
-     * value greater than the value argument exists, false otherwise
-     * @throws Exception if there is a failure to read the underlying Db
-     * or if the underlying Db is not of the Btree type that allows sorted
-     * duplicate values.
+     * {@inheritDoc}
      */
-    boolean hasGreaterOrEqual( K key, V val ) throws Exception;
+    public boolean hasGreaterOrEqual( ID key, Entry val ) throws Exception
+    {
+        return wrappedTable.hasGreaterOrEqual( key, val );
+    }
 
 
     /**
-     * Checks to see if this table has a Tuple with a key equal to the key
-     * argument, yet with a value less than or equal to the value argument
-     * provided.  The key argument <strong>MUST</strong> exist for this call
-     * to return true and the underlying Db must allow for values of duplicate
-     * keys to be sorted.  The entire basis to this method depends on the fact
-     * that tuples of the same key have values sorted according to a valid
-     * value comparator.
-     *
-     * If the table does not support duplicates then an
-     * UnsupportedOperationException is thrown.
-     *
-     * @param key the key
-     * @param val the value to compare values to
-     * @return true if a Tuple with a key equal to the key argument and a
-     * value less than the value argument exists, false otherwise
-     * @throws Exception if there is a failure to read the underlying Db
-     * or if the underlying Db is not of the Btree type that allows sorted
-     * duplicate values.
+     * {@inheritDoc}
      */
-    boolean hasLessOrEqual( K key, V val ) throws Exception;
+    public boolean hasLessOrEqual( ID key, Entry val ) throws Exception
+    {
+        return wrappedTable.hasLessOrEqual( key, val );
+    }
 
 
     /**
      * {@inheritDoc}
      */
-    Entry get( ID key ) throws Exception
+    public Entry get( ID key ) throws Exception
     {
-        Entry entry = wrappedTable.get( key ); 
+        
+        if ( key == null )
+        {
+            return null;
+        }
+        
+        TxnLogManager<ID> logManager = TxnManagerFactory.<ID>txnLogManagerInstance();
+        Entry entry = wrappedTable.get( key );
+        entry = logManager.mergeUpdates( partitionDn, key, entry );
+        return entry;
     }
 
 
     /**
-     * Puts a record into this Table.  Null is not allowed for keys or values
-     * and should result in an IllegalArgumentException.
-     *
-     * @param key the key of the record
-     * @param value the value of the record.
-     * @throws Exception if there is a failure to read or write to the
-     * underlying Db
-     * @throws IllegalArgumentException if a null key or value is used
+     * {@inheritDoc}
      */
-    void put( K key, V value ) throws Exception;
+    public void put( ID key, Entry value ) throws Exception
+    {
+      wrappedTable.put( key, value ); 
+    }
 
 
     /**
-     * Removes all records with a specified key from this Table.
-     *
-     * @param key the key of the records to remove
-     * @throws Exception if there is a failure to read or write to
-     * the underlying Db
+     * {@inheritDoc}
      */
-    void remove( K key ) throws Exception;
+    public void remove( ID key ) throws Exception
+    {
+       wrappedTable.remove( key ); 
+    }
 
 
     /**
-     * Removes a single key value pair with a specified key and value from
-     * this Table.
-     *
-     * @param key the key of the record to remove
-     * @param value the value of the record to remove
-     * @throws Exception if there is a failure to read or write to
-     * the underlying Db
+     * {@inheritDoc}
      */
-    void remove( K key, V value ) throws Exception;
+    public void remove( ID key, Entry value ) throws Exception
+    {
+        wrappedTable.remove( key, value );
+    }
 
 
     /**
-     * Creates a Cursor that traverses Tuples in a Table.
-     *
-     * @return a Cursor over Tuples containing the key value pairs
-     * @throws Exception if there are failures accessing underlying stores
+     * {@inheritDoc}
      */
-    Cursor<Tuple<K, V>> cursor() throws Exception;
-
+    public Cursor<Tuple<ID, Entry>> cursor() throws Exception
+    {
+        return wrappedTable.cursor();
+    }
 
     /**
-     * Creates a Cursor that traverses Table Tuples for the same key. Only
-     * Tuples with the provided key will be returned if the key exists at
-     * all.  If the key does not exist an empty Cursor is returned.  The
-     * motivation behind this method is to minimize the need for callers to
-     * actively constrain Cursor operations based on the Tuples they return
-     * to a specific key.  This Cursor is naturally limited to return only
-     * the tuples for the same key.
-     *
-     * @param key the duplicate key to return the Tuples of
-     * @return a Cursor over Tuples containing the same key
-     * @throws Exception if there are failures accessing underlying stores
+     * {@inheritDoc}
      */
-    Cursor<Tuple<K, V>> cursor( K key ) throws Exception;
+    public Cursor<Tuple<ID, Entry>> cursor( ID key ) throws Exception
+    {
+        return wrappedTable.cursor( key );
+    }
 
 
     /**
-     * Creates a Cursor that traverses Table values for the same key. Only
-     * Tuples with the provided key will have their values returned if the key
-     * exists at all.  If the key does not exist an empty Cursor is returned.
-     * The motivation behind this method is to minimize the need for callers
-     * to actively constrain Cursor operations to a specific key while
-     * removing overheads in creating new Tuples or population one that is
-     * reused to return key value pairs.  This Cursor is naturally limited to
-     * return only the values for the same key.
-     *
-     * @param key the duplicate key to return the values of
-     * @return a Cursor over values of a key
-     * @throws Exception if there are failures accessing underlying stores
+     * {@inheritDoc}
      */
-    Cursor<V> valueCursor( K key ) throws Exception;
-
+    public Cursor<Entry> valueCursor( ID key ) throws Exception
+    {
+        return wrappedTable.valueCursor( key );
+    }
 
-    // ------------------------------------------------------------------------
-    // Table Record Count Methods
-    // ------------------------------------------------------------------------
 
     /**
-     * Gets the count of the number of records in this Table.
-     *
-     * @return the number of records
-     * @throws Exception if there is a failure to read the underlying Db
+     * {@inheritDoc}
      */
-    int count() throws Exception;
+    public int count() throws Exception
+    {
+        return wrappedTable.count();
+    }
 
 
     /**
-     * Gets the count of the number of records in this Table with a specific
-     * key: returns the number of duplicates for a key.
-     *
-     * @param key the Object key to count.
-     * @return the number of duplicate records for a key.
-     * @throws Exception if there is a failure to read the underlying Db
+     * {@inheritDoc}
      */
-    int count( K key ) throws Exception;
-
+    public int count( ID key ) throws Exception
+    {
+        return wrappedTable.count( key );
+    }
 
     /**
-     * Gets the number of records greater than or equal to a key value.  The 
-     * specific key argument provided need not exist for this call to return 
-     * a non-zero value.
-     *
-     * @param key the key to use in comparisons
-     * @return the number of keys greater than or equal to the key
-     * @throws Exception if there is a failure to read the underlying db
+     * {@inheritDoc}
      */
-    int greaterThanCount( K key ) throws Exception;
+    public int greaterThanCount( ID key ) throws Exception
+    {
+        return wrappedTable.greaterThanCount( key );
+    }
 
 
     /**
-     * Gets the number of records less than or equal to a key value.  The 
-     * specific key argument provided need not exist for this call to return 
-     * a non-zero value.
-     *
-     * @param key the key to use in comparisons
-     * @return the number of keys less than or equal to the key
-     * @throws Exception if there is a failure to read the underlying db
+     * {@inheritDoc}
      */
-    int lessThanCount( K key ) throws Exception;
+    public int lessThanCount( ID key ) throws Exception
+    {
+        return wrappedTable.lessThanCount( key );
+    }
 
 
     /**
-     * Closes the underlying Db of this Table.
-     *
-     * @throws Exception on any failures
+     * {@inheritDoc}
      */
-    void close() throws Exception;
+    public void close() throws Exception
+    {
+        wrappedTable.close();
+    }
     
 }

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/ReadWriteTxn.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/ReadWriteTxn.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/ReadWriteTxn.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/ReadWriteTxn.java Thu Oct 20 12:59:47 2011
@@ -21,9 +21,11 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.log.UserLogRecord;
 
 import org.apache.directory.server.core.partition.index.ForwardIndexEntry;
+import org.apache.directory.server.core.partition.index.IndexComparator;
 import org.apache.directory.server.core.partition.index.IndexEntry;
 import org.apache.directory.server.core.partition.index.Index;
 import org.apache.directory.server.core.partition.index.Serializer;
+import org.apache.directory.server.core.partition.index.IndexCursor;
 
 import org.apache.directory.shared.ldap.model.name.Dn;
 import org.apache.directory.shared.ldap.model.entry.AttributeUtils;
@@ -290,4 +292,43 @@ class ReadWriteTxn<ID> extends AbstractT
         
     }
     
+    
+    public boolean hasDeletesFor( Dn partitionDn, String attributeOid )
+    {
+        Map<String, TreeSet< IndexEntry<Object,ID>>> deletedIndices = 
+            indexDeletes.get( partitionDn ); 
+
+        
+        if ( deletedIndices != null )
+        {
+            return ( deletedIndices.get( attributeOid ) != null );
+        }
+       
+        return false;
+
+        
+    }
+    
+    
+    public IndexCursor<Object,Entry,ID> getCursorFor( Dn partitionDn, String attributeOid, boolean forwardIndex, Object onlyValueKey, ID onlyIDKey, IndexComparator<Object,ID> comparator )
+    {
+        TxnIndexCursor<ID> txnIndexCursor = null;
+        
+        Map<String, TreeSet<IndexEntry<Object,ID>>> forwardIndices = 
+            forwardIndexAdds.get( partitionDn );
+        
+        if ( forwardIndices != null )
+        {
+            TreeSet<IndexEntry<Object, ID>> sortedSet = forwardIndices.get( attributeOid );
+            
+            if ( sortedSet != null )
+            {
+                txnIndexCursor = new TxnIndexCursor<ID>( sortedSet, forwardIndex, onlyValueKey, onlyIDKey, comparator );
+            }
+        }
+        
+        return txnIndexCursor;
+        
+    }
+    
 }

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnIndexCursor.java Thu Oct 20 12:59:47 2011
@@ -1,23 +1,22 @@
 
 package org.apache.directory.server.core.txn;
 
-import org.apache.directory.server.core.partition.index.IndexCursor;
 import org.apache.directory.server.core.partition.index.AbstractIndexCursor;
+import org.apache.directory.server.core.partition.index.IndexComparator;
 import org.apache.directory.server.core.partition.index.IndexEntry;
 
 import org.apache.directory.server.core.partition.index.ForwardIndexEntry;
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException;
-import org.apache.directory.shared.ldap.model.cursor.Tuple;
+import org.apache.directory.shared.ldap.model.entry.Entry;
 
 import java.util.Iterator;
-import java.util.SortedSet;
 import java.util.NavigableSet;
 
-public class TxnIndexCursor <V, O, ID> extends AbstractIndexCursor<V, O, ID>
+public class TxnIndexCursor <ID> extends AbstractIndexCursor<Object, Entry, ID>
 {
     /** list of changed index entries */
-    private NavigableSet<IndexEntry<V,ID>> changedEntries;
+    private NavigableSet<IndexEntry<Object,ID>> changedEntries;
     
     /** forward or reverse index */
     private boolean forwardIndex;
@@ -29,19 +28,45 @@ public class TxnIndexCursor <V, O, ID> e
     private boolean movingNext = true;
     
     /** Iterator to move over the set */
-    private Iterator<IndexEntry<V,ID>> it;
+    private Iterator<IndexEntry<Object,ID>> it;
     
     /** currently available value */
-    IndexEntry<V,ID> availableValue;
+    IndexEntry<Object,ID> availableValue;
     
     /** unsupported operation message */
     private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_722 );
+    
+    /** true if the index is locked down for a key */
+    private boolean onlyKey;
+    
+    /** Lock down key in case of forward index */
+    private Object onlyValueKey;
+    
+    /** Lock down key in case of reverse index */
+    private ID onlyIDKey;
+    
+    /** index entry comparator */
+    private IndexComparator<Object,ID> comparator;
    
     
-    public TxnIndexCursor( NavigableSet<IndexEntry<V,ID>> changedEntries, boolean forwardIndex )
+    public TxnIndexCursor( NavigableSet<IndexEntry<Object,ID>> changedEntries, boolean forwardIndex, Object onlyValueKey, ID onlyIDKey, IndexComparator<Object,ID> comparator )
     {
         this.changedEntries = changedEntries;
         this.forwardIndex = forwardIndex;
+        this.comparator = comparator;
+        
+        if ( onlyValueKey != null )
+        {
+            this.onlyValueKey = onlyValueKey;
+            onlyKey = true;
+        }
+        
+        
+        if ( onlyValueKey != null )
+        {
+            this.onlyValueKey = onlyValueKey;
+            onlyKey = true;
+        }
         
         if ( changedEntries.size()  < 1 )
         {
@@ -53,22 +78,118 @@ public class TxnIndexCursor <V, O, ID> e
     /**
      * {@inheritDoc}
      */
-    public void after( IndexEntry<V, ID> element ) throws Exception
+    public void after( IndexEntry<Object, ID> element ) throws Exception
     {
         positioned = true;
         availableValue = null;
         movingNext = true;
-        it = changedEntries.tailSet( element, false ).iterator();
+        
+        if ( onlyKey )
+        {
+            if ( forwardIndex )
+            {
+                if ( comparator.getValueComparator().compare( element.getValue(), onlyValueKey ) != 0 )
+                {
+                    throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+                }
+            }
+            else
+            {
+                if ( comparator.getIDComparator().compare( element.getId(), onlyIDKey ) != 0 )
+                {
+                    throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+                }
+            }
+        }
+        
+        boolean skipKey = false;
+        if  ( forwardIndex )
+        {
+            if ( element.getId() == null )
+            {
+                skipKey = true;
+            }
+        }
+        else
+        {
+            if ( element.getValue() == null )
+            {
+                skipKey = true;
+            }
+        }
+    
+        if ( skipKey )
+        { 
+            it = changedEntries.tailSet( element, false ).iterator();
+            
+            
+            boolean useLastEntry = false;
+            IndexEntry<Object,ID> indexEntry = null;
+            while ( it.hasNext() )
+            {
+                indexEntry = it.next();
+                
+                if ( forwardIndex )
+                {
+                    if ( comparator.getValueComparator().compare( indexEntry.getValue(), element.getValue() )  != 0 )
+                    {
+                        useLastEntry = true;
+                        break;
+                    }
+                }
+                else
+                {
+                    if ( comparator.getIDComparator().compare( indexEntry.getId(), element.getId() )  != 0 )
+                    {
+                        useLastEntry = true;
+                        break;
+                    }
+                }
+            }
+            
+            if ( useLastEntry )
+            {
+                it = changedEntries.tailSet( indexEntry, true ).descendingIterator();
+            }
+            else
+            {
+                movingNext = false;
+                it = changedEntries.descendingIterator();
+            }
+        }
+        else
+        {
+            it = changedEntries.tailSet( element, false ).iterator();
+        }
     }
     
     /**
      * {@inheritDoc}
      */
-    public void before( IndexEntry<V, ID> element ) throws Exception
+    public void before( IndexEntry<Object, ID> element ) throws Exception
     {
         positioned = true;
         availableValue = null;
         movingNext = true;
+        
+        if ( onlyKey )
+        {
+            if ( forwardIndex )
+            {
+                if ( comparator.getValueComparator().compare(element.getValue(), onlyValueKey ) != 0 )
+                {
+                    throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+                }
+            }
+            else
+            {
+                if ( comparator.getIDComparator().compare( element.getId(), onlyIDKey ) != 0 )
+                {
+                    throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
+                }
+            }
+        }
+        
         it = changedEntries.tailSet( element, true ).iterator();
     }
     
@@ -76,9 +197,9 @@ public class TxnIndexCursor <V, O, ID> e
     /**
      * {@inheritDoc}
      */
-    public void afterValue( ID id, V value ) throws Exception
+    public void afterValue( ID id, Object value ) throws Exception
     {
-        ForwardIndexEntry<V,ID> indexEntry = new ForwardIndexEntry();
+        ForwardIndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
         indexEntry.setId( id );
         indexEntry.setValue( value );
         this.after( indexEntry );
@@ -88,9 +209,9 @@ public class TxnIndexCursor <V, O, ID> e
     /**
      * {@inheritDoc}
      */
-    public void beforeValue( ID id, V value ) throws Exception
+    public void beforeValue( ID id, Object value ) throws Exception
     {
-        ForwardIndexEntry<V,ID> indexEntry = new ForwardIndexEntry();
+        ForwardIndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
         indexEntry.setId( id );
         indexEntry.setValue( value );
         this.before( indexEntry );
@@ -105,7 +226,26 @@ public class TxnIndexCursor <V, O, ID> e
         positioned = true;
         availableValue = null;
         movingNext = true;
-        it = changedEntries.iterator();
+        
+        if ( onlyKey )
+        {
+            ForwardIndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
+            if ( forwardIndex )
+            {
+                indexEntry.setValue( onlyValueKey );
+            }
+            else
+            {
+                indexEntry.setId( onlyIDKey );
+            }
+            
+            it = changedEntries.tailSet( indexEntry, false ).iterator();
+        }
+        else
+        {
+            it = changedEntries.iterator();
+        }
+        
     }
 
 
@@ -117,7 +257,59 @@ public class TxnIndexCursor <V, O, ID> e
         positioned = true;
         availableValue = null;
         movingNext = false;
-        it = changedEntries.descendingIterator();
+        
+        
+        if ( onlyKey )
+        {
+            IndexEntry<Object,ID> indexEntry = new ForwardIndexEntry<Object,ID>();
+            if ( forwardIndex )
+            {
+                indexEntry.setValue( onlyValueKey );
+            }
+            else
+            {
+                indexEntry.setId( onlyIDKey );
+            }
+            
+            it = changedEntries.tailSet( indexEntry, false ).iterator();
+            
+            
+            boolean useLastEntry = false;
+            while ( it.hasNext() )
+            {
+                indexEntry = it.next();
+                
+                if ( forwardIndex )
+                {
+                    if ( comparator.getValueComparator().compare( indexEntry.getValue(), onlyValueKey )  != 0 )
+                    {
+                        useLastEntry = true;
+                        break;
+                    }
+                }
+                else
+                {
+                    if ( comparator.getIDComparator().compare( indexEntry.getId(), onlyIDKey )  != 0 )
+                    {
+                        useLastEntry = true;
+                        break;
+                    }
+                }
+            }
+            
+            if ( useLastEntry )
+            {
+                it = changedEntries.headSet( indexEntry, false ).descendingIterator();
+            }
+            else
+            {
+                it = changedEntries.descendingIterator();
+            }
+        }
+        else
+        {
+            it = changedEntries.descendingIterator();
+        }
     }
 
     /**
@@ -174,6 +366,27 @@ public class TxnIndexCursor <V, O, ID> e
         if ( it.hasNext() )
         {
             availableValue = it.next();
+            
+            if ( onlyKey )
+            {
+                if ( forwardIndex )
+                {
+                    if ( comparator.getValueComparator().compare( availableValue.getValue(), onlyValueKey ) != 0 )
+                    {
+                        availableValue = null;
+                        return false;
+                    }
+                }
+                else
+                {
+                    if ( comparator.getIDComparator().compare( availableValue.getId(), onlyIDKey ) != 0 )
+                    {
+                        availableValue = null;
+                        return false;
+                    }
+                }
+            }
+            
             return true;
         }
         else
@@ -219,6 +432,28 @@ public class TxnIndexCursor <V, O, ID> e
         if ( it.hasNext() )
         {
             availableValue = it.next();
+            
+
+            if ( onlyKey )
+            {
+                if ( forwardIndex )
+                {
+                    if ( comparator.getValueComparator().compare( availableValue.getValue(), onlyValueKey ) != 0 )
+                    {
+                        availableValue = null;
+                        return false;
+                    }
+                }
+                else
+                {
+                    if ( comparator.getIDComparator().compare( availableValue.getId(), onlyIDKey ) != 0 )
+                    {
+                        availableValue = null;
+                        return false;
+                    }
+                }
+            }
+            
             return true;
         }
         else
@@ -231,7 +466,7 @@ public class TxnIndexCursor <V, O, ID> e
     /**
      * {@inheritDoc}
      */
-    public IndexEntry<V, ID> get() throws Exception
+    public IndexEntry<Object, ID> get() throws Exception
     {
         if ( availableValue != null )
         {

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java?rev=1186778&r1=1186777&r2=1186778&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/txn/TxnManagerFactory.java Thu Oct 20 12:59:47 2011
@@ -7,7 +7,7 @@ import org.apache.directory.server.core.
 
 public class TxnManagerFactory
 {
-    private static TxnManager<?> txnManager;
+    private static TxnManagerInternal<?> txnManager;
     
     private static TxnLogManager<?> txnLogManager;
     
@@ -37,4 +37,9 @@ public class TxnManagerFactory
     {
         return ( (TxnLogManager<ID>) txnLogManager );
     }
+    
+    static <ID> TxnManagerInternal<ID> txnManagerInternalInstance()
+    {
+        return ( (TxnManagerInternal<ID>) txnManager );
+    }
 }