directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1334904 [1/3] - in /directory/apacheds/branches/apacheds-txns: core-api/src/main/java/org/apache/directory/server/core/api/ core-api/src/main/java/org/apache/directory/server/core/api/interceptor/ core-api/src/main/java/org/apache/director...
Date Mon, 07 May 2012 07:53:22 GMT
Author: saya
Date: Mon May  7 07:53:21 2012
New Revision: 1334904

URL: http://svn.apache.org/viewvc?rev=1334904&view=rev
Log:
-Changes to handle logical data(or logical caches)
   - While a cursor is built or ReadWrite txn is in progress, the thread hold a shared lock. If it needs to change logical data derived from transactional data, it escalates its lock to exclusive lock. This escalation might throw TxnConflictException
   - Multiple locks to manage different caches is replaced with one single lock at the txn manager layer.
   - If a txn fails (conflict or any other exception) all logical caches are rebuilt from underlying transactionally managed data. Here many optimizations are possible.

-Added TxnConflictIT to MigratedStockCoreISuite(more basic multithreaded tests would be good)

This completes the forward going changes in the transactional layer. Tests are passing. This would be a good checkpoint.
 

Modified:
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/DirectoryService.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/ReferralManager.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/BaseInterceptor.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/Interceptor.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/schema/SchemaPartition.java
    directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/txn/TxnManager.java
    directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockDirectoryService.java
    directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/schema/AbstractMetaSchemaObjectHandler.java
    directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/suites/MigratedStockCoreISuite.java
    directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultOperationExecutionManager.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/AbstractTransaction.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadOnlyTxn.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadWriteTxn.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/Transaction.java
    directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/TxnManagerInternal.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
    directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
    directory/apacheds/branches/apacheds-txns/interceptors/admin/src/main/java/org/apache/directory/server/core/admin/AdministrativePointInterceptor.java
    directory/apacheds/branches/apacheds-txns/interceptors/authz/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java
    directory/apacheds/branches/apacheds-txns/interceptors/authz/src/main/java/org/apache/directory/server/core/authz/GroupCache.java
    directory/apacheds/branches/apacheds-txns/interceptors/authz/src/main/java/org/apache/directory/server/core/authz/TupleCache.java
    directory/apacheds/branches/apacheds-txns/interceptors/exception/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
    directory/apacheds/branches/apacheds-txns/interceptors/referral/src/main/java/org/apache/directory/server/core/referral/ReferralInterceptor.java
    directory/apacheds/branches/apacheds-txns/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/DirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/DirectoryService.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/DirectoryService.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/DirectoryService.java Mon May  7 07:53:21 2012
@@ -603,7 +603,12 @@ public interface DirectoryService extend
      * @return The TriggerExecution AdministrativePoint cache
      */
     DnNode<TriggerExecutionAdministrativePoint> getTriggerExecutionAPCache();
-
+    
+    
+    /**
+     * Reset all the caches to their initial state
+     */
+    void resetCaches();
 
     /**
      * @return true if the password policy is enabled, false otherwise

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/ReferralManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/ReferralManager.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/ReferralManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/ReferralManager.java Mon May  7 07:53:21 2012
@@ -111,6 +111,15 @@ public interface ReferralManager
      * @exception If the initialization failed
      */
     void init( DirectoryService directoryService, String... suffixes ) throws Exception;
+    
+    /** Reinitalize the referrals 
+     * 
+     * Rereads the referalls
+     *
+     * @param directoryService  The associated LDAP service
+     * @throws LdapException
+     */
+    void reinitialize( DirectoryService directoryService ) throws LdapException;
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/BaseInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/BaseInterceptor.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/BaseInterceptor.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/BaseInterceptor.java Mon May  7 07:53:21 2012
@@ -151,6 +151,15 @@ public abstract class BaseInterceptor im
         {
             // unused
         }
+        
+        
+        /**
+         * {@inheritDoc}
+         */
+        public void reinitLogicalData( DirectoryService directoryService ) throws LdapException
+        {
+            // Do nothing by default
+        }
 
 
         /**
@@ -375,6 +384,15 @@ public abstract class BaseInterceptor im
     public void destroy()
     {
     }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void reinitLogicalData( DirectoryService directoryService ) throws LdapException
+    {
+        // Do nothing by default
+    }
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/Interceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/Interceptor.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/Interceptor.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/Interceptor.java Mon May  7 07:53:21 2012
@@ -124,6 +124,15 @@ public interface Interceptor
      * when this intercepter is unloaded from interceptor chain.
      */
     void destroy();
+    
+    
+    /**
+     * Reintializes the logical data from the data managed by txn layer
+     *
+     * @param directoryService
+     * @throws LdapException
+     */
+    void reinitLogicalData( DirectoryService directoryService ) throws LdapException;
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ModifyOperationContext.java Mon May  7 07:53:21 2012
@@ -124,9 +124,14 @@ public class ModifyOperationContext exte
     {
         super.saveOriginalContext();
       
-        for ( Modification mod : getModItems() )
+        List<Modification> items = getModItems();
+        
+        if ( items != null )
         {
-            originalModItems.add( mod.clone() );
+            for ( Modification mod : items )
+            {
+                originalModItems.add( mod.clone() );
+            }
         }
     }
     
@@ -138,8 +143,13 @@ public class ModifyOperationContext exte
     {
         super.resetContext();
         alteredEntry = null;
-        modItems.clear();
-        modItems.addAll( originalModItems );
+        
+        if ( modItems != null )
+        {
+         modItems.clear();
+         modItems.addAll( originalModItems );
+        }
+        
         originalModItems.clear();
     }
     

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/schema/SchemaPartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/schema/SchemaPartition.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/schema/SchemaPartition.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/schema/SchemaPartition.java Mon May  7 07:53:21 2012
@@ -263,6 +263,9 @@ public final class SchemaPartition exten
      */
     public void add( AddOperationContext addContext ) throws LdapException
     {
+        // Ensure logical data in registries is consistent
+        addContext.getSession().getDirectoryService().getTxnManager().startLogicalDataChange();
+        
         // At this point, the added SchemaObject does not exist in the partition
         // We have to check if it's enabled and then inject it into the registries
         // but only if it does not break the server.
@@ -324,6 +327,9 @@ public final class SchemaPartition exten
             throw new LdapUnwillingToPerformException();
         }
         
+        // Ensure logical data in registries is consistent
+        deleteContext.getSession().getDirectoryService().getTxnManager().startLogicalDataChange();
+        
         // The SchemaObject always exist when we reach this method.
         synchronizer.delete( deleteContext, cascade );
 
@@ -367,6 +373,9 @@ public final class SchemaPartition exten
 
         boolean cascade = modifyContext.hasRequestControl( Cascade.OID );
 
+        // Ensure logical data in registries is consistent
+        modifyContext.getSession().getDirectoryService().getTxnManager().startLogicalDataChange();
+        
         synchronizer.modify( modifyContext, targetEntry, cascade );
 
         if ( !modifyContext.getDn().equals( SCHEMA_MODIFICATION_DN ) )
@@ -386,6 +395,10 @@ public final class SchemaPartition exten
         CoreSession session = moveContext.getSession();
         LookupOperationContext lookupContext = new LookupOperationContext( session, moveContext.getDn(), SchemaConstants.ALL_ATTRIBUTES_ARRAY );
         Entry entry = session.getDirectoryService().getPartitionNexus().lookup( lookupContext );
+        
+        // Ensure logical data in registries is consistent
+        session.getDirectoryService().getTxnManager().startLogicalDataChange();
+        
         synchronizer.move( moveContext, entry, cascade );
         updateSchemaModificationAttributes( moveContext );
     }
@@ -400,6 +413,10 @@ public final class SchemaPartition exten
         CoreSession session = moveAndRenameContext.getSession();
         LookupOperationContext lookupContext = new LookupOperationContext( session, moveAndRenameContext.getDn(), SchemaConstants.ALL_ATTRIBUTES_ARRAY );
         Entry entry = session.getDirectoryService().getPartitionNexus().lookup( lookupContext );
+        
+        // Ensure logical data in registries is consistent
+        session.getDirectoryService().getTxnManager().startLogicalDataChange();
+        
         synchronizer.moveAndRename( moveAndRenameContext, entry, cascade );
         updateSchemaModificationAttributes( moveAndRenameContext );
     }
@@ -412,6 +429,9 @@ public final class SchemaPartition exten
     {
         boolean cascade = renameContext.hasRequestControl( Cascade.OID );
 
+        // Ensure logical data in registries is consistent
+        renameContext.getSession().getDirectoryService().getTxnManager().startLogicalDataChange();
+        
         // First update the registries
         synchronizer.rename( renameContext, cascade );
 

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/txn/TxnManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/txn/TxnManager.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/txn/TxnManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/main/java/org/apache/directory/server/core/api/txn/TxnManager.java Mon May  7 07:53:21 2012
@@ -19,6 +19,8 @@
  */
 package org.apache.directory.server.core.api.txn;
 
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+
 
 /**
  * The transaction manager interface.
@@ -103,4 +105,31 @@ public interface TxnManager
      * Flushes the committed txns to partitions.
      */
     void applyPendingTxns();
+    
+    
+    /**
+     * Called when data derived from the underlying
+     * data managed by the txn manager is about to be
+     * changed. Ensures Every txn sees a consistent
+     * version of the data. 
+     *
+     * @throws LdapException with a root cause as TxnConflictException
+     */
+    void startLogicalDataChange() throws LdapException;
+    
+    
+    /**
+     * Called when txn manager wont need data derived from  
+     * data managed by the txn layer is not needed any more.  
+     */
+    void endLogicalDataRead();
+    
+    
+    /**
+     * Prepares the current txn for logical data reinit
+     *
+     * @return TRUE if txn needs to do logical data reinit
+     */
+    boolean prepareForLogicalDataReinit();
+
 }

Modified: directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockDirectoryService.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockDirectoryService.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-api/src/test/java/org/apache/directory/server/core/api/MockDirectoryService.java Mon May  7 07:53:21 2012
@@ -77,6 +77,13 @@ public class MockDirectoryService implem
     {
         this.count = count;
     }
+    
+    
+    public void resetCaches()
+    {
+        // do nothing
+    }
+    
 
     public Hashtable<String, Object> getEnvironment()
     {

Modified: directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/schema/AbstractMetaSchemaObjectHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/schema/AbstractMetaSchemaObjectHandler.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/schema/AbstractMetaSchemaObjectHandler.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/schema/AbstractMetaSchemaObjectHandler.java Mon May  7 07:53:21 2012
@@ -77,6 +77,9 @@ public abstract class AbstractMetaSchema
      */
     protected boolean isOnDisk( Dn dn )
     {
+        
+        getService().getTxnManager().applyPendingTxns();
+        
         // do not change the value of getSchemaPath to lowercase
         // on Linux this gives a wrong path
         String schemaObjectFileName = getSchemaPath( dn );

Modified: directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/suites/MigratedStockCoreISuite.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/suites/MigratedStockCoreISuite.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/suites/MigratedStockCoreISuite.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/suites/MigratedStockCoreISuite.java Mon May  7 07:53:21 2012
@@ -35,6 +35,7 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.authz.MoveRenameAuthorizationIT;
 import org.apache.directory.server.core.authz.SearchAuthorizationIT;
 import org.apache.directory.server.core.exception.ExceptionServiceIT;
+import org.apache.directory.server.core.txn.TxnConflictIT;
 import org.apache.directory.server.core.integ.FrameworkSuite;
 import org.apache.directory.server.core.operations.add.PasswordHashingInterceptorTest;
 import org.junit.runner.RunWith;
@@ -70,7 +71,10 @@ import org.junit.runners.Suite;
         SearchAuthorizationIT.class,
 
         // exception
-        ExceptionServiceIT.class
+        ExceptionServiceIT.class,
+        
+        // Txn Conflict/Serialization
+        TxnConflictIT.class
 
         } )
 public class MigratedStockCoreISuite

Modified: directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-integ/src/test/java/org/apache/directory/server/core/txn/TxnConflictIT.java Mon May  7 07:53:21 2012
@@ -32,7 +32,7 @@ import org.apache.directory.shared.ldap.
 
 
 @RunWith ( FrameworkRunner.class )
-@CreateDS(name = "TxnConflictIT")
+@CreateDS(enableChangeLog = false, name = "TxnConflictIT")
 @ApplyLdifs(
     {
         "dn: cn=test1, ou=system",
@@ -242,13 +242,23 @@ public class TxnConflictIT extends Abstr
             connection.add( entry );
         }
         
+        private void doModifyConfclictingWithDelete() throws Exception
+        {
+            LdapContext sysRoot = getSystemContext( getService() );
+            
+            // The added value
+            Attributes attrs = new BasicAttributes( "telephoneNumber", "1 650 300 6070", true );
+
+            // Add the Ava
+            sysRoot.modifyAttributes( "cn=test3,ou=users", DirContext.ADD_ATTRIBUTE, attrs );
+        }
         
         private void doModifyConfclictingWithRename() throws Exception
         {
             LdapContext sysRoot = getSystemContext( getService() );
             
             // The added value
-            Attributes attrs = new BasicAttributes( "telephoneNumber", "1 650 300 6088", true );
+            Attributes attrs = new BasicAttributes( "telephoneNumber", "1 650 300 6071", true );
 
             // Add the Ava
             sysRoot.modifyAttributes( "cn=test3,ou=users", DirContext.ADD_ATTRIBUTE, attrs );
@@ -267,7 +277,7 @@ public class TxnConflictIT extends Abstr
                 {
                     try
                     {
-                        doConflictingModify();
+                        doModifyConfclictingWithDelete();
                     }
                     catch ( NameNotFoundException e )
                     {

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/ReferralManagerImpl.java Mon May  7 07:53:21 2012
@@ -73,8 +73,6 @@ public class ReferralManagerImpl impleme
      */
     public ReferralManagerImpl( DirectoryService directoryService ) throws LdapException
     {
-        lockWrite();
-
         referrals = new DnNode<Entry>();
         PartitionNexus nexus = directoryService.getPartitionNexus();
 
@@ -83,8 +81,18 @@ public class ReferralManagerImpl impleme
 
         init( directoryService, suffixes.toArray( new String[]
             {} ) );
-
-        unlock();
+    }
+    
+    
+    public void reinitialize( DirectoryService directoryService ) throws LdapException
+    {
+        referrals = new DnNode<Entry>();
+        
+        PartitionNexus nexus = directoryService.getPartitionNexus();
+        Set<String> suffixes = nexus.listSuffixes();
+        
+        init( directoryService, suffixes.toArray( new String[]
+            {} ) );
     }
 
 
@@ -181,14 +189,8 @@ public class ReferralManagerImpl impleme
                 {
                     Entry entry = cursor.get();
 
-                    // Lock the referralManager
-                    lockWrite();
-
                     // Add it at the right place
                     addReferral( entry );
-
-                    // Unlock the referralManager
-                    unlock();
                 }
 
                 cursor.close();

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultOperationExecutionManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultOperationExecutionManager.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultOperationExecutionManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultOperationExecutionManager.java Mon May  7 07:53:21 2012
@@ -277,7 +277,7 @@ public class DefaultOperationExecutionMa
             // log the change
             txnLogManager.log( changeContainer, false );
 
-            //TODO TODO TODO REMOVE THIS
+            // Mostly for schema partition
             partition.add( addContext );
         }
         catch ( LdapException le )
@@ -301,7 +301,7 @@ public class DefaultOperationExecutionMa
     {
         Dn dn = deleteContext.getDn();
 
-        //TODO TODO TODO REMOVE THIS
+        // Mostly for schema partition
         partition.delete( deleteContext );
 
         // Add write dependency on the dn
@@ -498,7 +498,7 @@ public class DefaultOperationExecutionMa
                     {} ) );
             modifyContext.setAlteredEntry( modifiedEntry );
 
-            //TODO TODO TODO REMOVE THIS
+            // Mostly for schema partition
             partition.modify( modifyContext );
 
         }
@@ -1022,7 +1022,7 @@ public class DefaultOperationExecutionMa
                 rename( partition, oldDn, newRdn, deleteOldRdn, null, originalEntry );
             }
 
-            //TODO TODO TODO REMOVE THIS
+            // Mostly for schema partition
             partition.rename( renameContext );
         }
         catch ( Exception e )
@@ -1346,7 +1346,7 @@ public class DefaultOperationExecutionMa
 
             move( partition, oldDn, newSuperior, newDn, modifiedEntry, originalEntry );
 
-            //TODO TODO TODO REMOVE THIS
+            // Mostly for schema partition
             partition.move( moveContext );
 
         }

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/AbstractTransaction.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/AbstractTransaction.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/AbstractTransaction.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/AbstractTransaction.java Mon May  7 07:53:21 2012
@@ -51,26 +51,43 @@ abstract class AbstractTransaction imple
     /** List of txns that this txn depends on */
     private List<ReadWriteTxn> txnsToCheck = new ArrayList<ReadWriteTxn>();
 
-    /** The number of operations using this transaction */
-    private int nbRef;
-
     protected long id;
 
     private static AtomicLong counter = new AtomicLong( 0 );
     
-    /** Trus if this is the only running txn */
-    private boolean isExclusive = false;
-
+    /** True optimistic lock is held by the txn */
+    private boolean isOptimisticLockHeld = false;
+    
+    /** version of the logical data vseen by this txn */
+    private long myLogicalDataVersion;
 
-    public boolean isExclusive()
+    public boolean isOptimisticLockHeld()
+    {
+        return isOptimisticLockHeld;
+    }
+    
+    
+    public void setOptimisticLockHeld()
+    {
+        isOptimisticLockHeld = true;
+    }
+    
+    
+    public void clearOptimisticLockHeld()
     {
-        return isExclusive;
+        isOptimisticLockHeld = false;
     }
     
     
-    public void setExclusive()
+    public long getLogicalDataVersion()
     {
-        isExclusive = true;
+        return myLogicalDataVersion;
+    }
+    
+    
+    public void setLogicalDataVersion( long logicalDataVersion )
+    {
+        myLogicalDataVersion = logicalDataVersion;
     }
 
 
@@ -80,7 +97,6 @@ abstract class AbstractTransaction imple
     public AbstractTransaction()
     {
         txnState = State.INITIAL;
-        nbRef = 0;
         id = counter.getAndIncrement();
     }
 
@@ -88,20 +104,12 @@ abstract class AbstractTransaction imple
     /**
      * {@inheritDoc}
      */
-    protected void startTxn( long startTime )
+    public void startTxn( long startTime, long logicalDataVerion  )
     {
         this.startTime = startTime;
         txnState = State.READ;
-        nbRef++;
     }
 
-
-    public void reuseTxn()
-    {
-        nbRef++;
-    }
-
-
     /**
      * {@inheritDoc}
      */
@@ -117,12 +125,7 @@ abstract class AbstractTransaction imple
     public void commitTxn( long commitTime )
     {
         this.commitTime = commitTime;
-        nbRef--;
-
-        if ( nbRef == 0 )
-        {
-            txnState = State.COMMIT;
-        }
+        txnState = State.COMMIT;
     }
 
 

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/DefaultTxnManager.java Mon May  7 07:53:21 2012
@@ -43,6 +43,7 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.txn.TxnLogManager;
 import org.apache.directory.server.core.api.txn.logedit.LogEdit;
 import org.apache.directory.server.core.shared.txn.logedit.TxnStateChange;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
 
 
 /**
@@ -65,7 +66,7 @@ class DefaultTxnManager implements TxnMa
     private Lock writeTxnsLock = new ReentrantLock();
 
     /** Used to order txns in case of conflicts */
-    private ReadWriteLock optimisticLock = new ReentrantReadWriteLock();
+    private ReentrantReadWriteLock optimisticLock = new ReentrantReadWriteLock();
 
     /** Latest committed txn on which read only txns can depend */
     private AtomicReference<ReadWriteTxn> latestCommittedTxn = new AtomicReference<ReadWriteTxn>();
@@ -105,6 +106,9 @@ class DefaultTxnManager implements TxnMa
 
     private AtomicInteger pending = new AtomicInteger();
 
+    /** Logical data version number */
+    private long logicalDataVersion = 0;
+
     /** Per thread txn context */
     static final ThreadLocal<Transaction> txnVar =
         new ThreadLocal<Transaction>()
@@ -178,6 +182,24 @@ class DefaultTxnManager implements TxnMa
     /**
      * {@inheritDoc}
      */
+    public long getLogicalDataVersion()
+    {
+        return logicalDataVersion;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void bumpLogicalDataVersion()
+    {
+        logicalDataVersion++;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
     public TxnHandle retryTransaction() throws Exception
     {
         Transaction curTxn = getCurTxn();
@@ -193,7 +215,6 @@ class DefaultTxnManager implements TxnMa
 
         // abort current txn and start a new read write txn
 
-      
         abortReadWriteTxn( ( ReadWriteTxn ) curTxn );
         curTxn.abortTxn();
         return beginReadWriteTxn( true );
@@ -239,17 +260,15 @@ class DefaultTxnManager implements TxnMa
             throw new IllegalStateException( " trying to commit non existent txn " );
         }
 
-        boolean isExclusive = txn.isExclusive();
-
         try
-        {        
+        {
             if ( flushFailed )
             {
                 throw new IOException( "Flushing of txns failed" );
             }
-            
+
             prepareForEndingTxn( txn );
-    
+
             if ( txn instanceof ReadOnlyTxn )
             {
                 txn.commitTxn( txn.getStartTime() );
@@ -261,14 +280,8 @@ class DefaultTxnManager implements TxnMa
         }
         finally
         {
-            if ( !isExclusive )
-            {
-                optimisticLock.readLock().unlock();
-            }
-            else
-            {
-                optimisticLock.writeLock().unlock();
-            }
+            // Release optimistic lock if it is held
+            releaseOptimisticLock();
         }
 
         setCurTxn( null );
@@ -289,8 +302,6 @@ class DefaultTxnManager implements TxnMa
             throw new IllegalStateException( "Trying to abort while there is not txn " );
         }
 
-        boolean isExclusive = txn.isExclusive();
-
         try
         {
             prepareForEndingTxn( txn );
@@ -301,18 +312,12 @@ class DefaultTxnManager implements TxnMa
             }
 
             txn.abortTxn();
-            setCurTxn( null );
         }
         finally
         {
-            if ( !isExclusive )
-            {
-                optimisticLock.readLock().unlock();
-            }
-            else
-            {
-                optimisticLock.writeLock().unlock();
-            }
+            // Release optimistic lock if it is held
+            releaseOptimisticLock();
+            setCurTxn( null );
         }
 
         //System.out.println( "TRAN: Aborted " + txn );
@@ -402,6 +407,127 @@ class DefaultTxnManager implements TxnMa
 
 
     /**
+     * {@inheritDoc}
+     */
+    public void startLogicalDataChange() throws LdapException
+    {
+        Transaction curTxn = getCurTxn();
+
+        if (curTxn == null)
+        {
+            return;
+        }
+        // Should have a rw txn
+        if ( !( curTxn instanceof ReadWriteTxn ) )
+        {
+            // Cannot start a TXN when a RW txn is ongoing 
+            throw new IllegalStateException( "Unexpected txn state when starting logical data change txn: " +
+                curTxn );
+        }
+
+        // If txn is already exclusive then it can start logical data change immediately
+
+        if ( !curTxn.isOptimisticLockHeld() )
+        {
+            throw new IllegalStateException( "Unexpected txn state when starting logical data change txn: " +
+                " txn is not holding optimistic lock:"+
+                curTxn );
+        }
+        
+        // If lock is already held exclusively by the txn, then return
+        if ( optimisticLock.isWriteLockedByCurrentThread() )
+        {
+            return;
+        }
+
+        long txnLogicalDataVersion = curTxn.getLogicalDataVersion();
+
+        // Get operations lock in exclusive mode
+        optimisticLock.readLock().unlock();
+        optimisticLock.writeLock().lock();
+
+        // If somebody raced and changed logical data, then bail out
+        if ( getLogicalDataVersion() != txnLogicalDataVersion )
+        {
+            
+            TxnConflictException e = new TxnConflictException();
+            throw new LdapException(e);
+        }
+
+        // Finally bump of logical data version number
+        bumpLogicalDataVersion();
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void endLogicalDataRead()
+    {
+        // Should only be called for read only txns
+        Transaction curTxn = getCurTxn();
+
+        if (curTxn == null || !( curTxn instanceof ReadOnlyTxn ))
+        {
+            throw new IllegalStateException( "Unexpected txn state when ending logical data read:" + curTxn );
+        }
+        
+        if ( !curTxn.isOptimisticLockHeld() )
+        {
+            throw new IllegalStateException( "Unexpected txn state when ending logical data read, optimistic lock not held:" + 
+                curTxn );
+        }
+        
+        releaseOptimisticLock();
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    public boolean prepareForLogicalDataReinit()
+    {
+        Transaction curTxn = getCurTxn();
+
+        if (curTxn == null || !( curTxn instanceof ReadWriteTxn ))
+        {
+            throw new IllegalStateException( "Unexpected txn state when preparing for logical data reinit:" + curTxn );
+        }
+        
+        if ( optimisticLock.isWriteLockedByCurrentThread() )
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    
+    /**
+     * If the thread holds optimistic lock, release it
+     */
+    private void releaseOptimisticLock()
+    {
+        Transaction curTxn = getCurTxn();
+        
+        if ( curTxn.isOptimisticLockHeld() )
+        {
+            if ( optimisticLock.isWriteLockedByCurrentThread() )
+            {
+                optimisticLock.writeLock().unlock();
+            }
+            else
+            {
+                optimisticLock.readLock().unlock();
+            }
+            
+            curTxn.clearOptimisticLockHeld();
+        }
+    }
+
+    /**
      * Begins a read only txn. A read only txn does not put any log edits
      * to the txn log.Its start time is the latest committed txn's commit time. 
      */
@@ -410,7 +536,9 @@ class DefaultTxnManager implements TxnMa
         ReadOnlyTxn txn = new ReadOnlyTxn();
         ReadWriteTxn lastTxnToCheck = null;
 
-        optimisticLock.readLock().lock(); 
+        optimisticLock.readLock().lock();
+        txn.setOptimisticLockHeld();
+        txn.setLogicalDataVersion( logicalDataVersion );
         
         /*
          * Set the start time as the latest committed txn's commit time. We need to make sure that
@@ -436,7 +564,7 @@ class DefaultTxnManager implements TxnMa
         long startTime;
 
         startTime = lastTxnToCheck.getCommitTime();
-        txn.startTxn( startTime );
+        txn.startTxn( startTime, logicalDataVersion );
 
         buildCheckList( txn, lastTxnToCheck );
 
@@ -471,8 +599,10 @@ class DefaultTxnManager implements TxnMa
         else
         {
             optimisticLock.writeLock().lock();
-            txn.setExclusive();
         }
+        
+        txn.setOptimisticLockHeld();
+        txn.setLogicalDataVersion( logicalDataVersion );
 
         /*
          * Get the start time and last txn to depend on
@@ -485,7 +615,7 @@ class DefaultTxnManager implements TxnMa
         try
         {
             txnLogManager.log( logRecord, false );
-            txn.startTxn( logRecord.getLogAnchor().getLogLSN() );
+            txn.startTxn( logRecord.getLogAnchor().getLogLSN(), logicalDataVersion );
 
             do
             {
@@ -502,14 +632,10 @@ class DefaultTxnManager implements TxnMa
         }
         catch ( Exception e )
         {
-            if ( txn.isExclusive() == false )
-            {
-                optimisticLock.readLock().unlock();
-            }
-            else
-            {
-                optimisticLock.writeLock().unlock();
-            }
+            // Release optimistic lock if held
+            setCurTxn(txn);
+            releaseOptimisticLock();
+            
         }
         finally
         {
@@ -604,7 +730,7 @@ class DefaultTxnManager implements TxnMa
                 throw new IllegalStateException( " prepareForEndingTxn: txn has unpexptected start time " +
                     txn + " expected: " + lastTxnToCheck );
             }
-            
+
             if ( lastTxnToCheck.getRefCount().get() <= 0 )
             {
                 throw new IllegalStateException( " prepareForEndingTxn: lastTxnToCheck has unexpected ref cnt " +

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadOnlyTxn.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadOnlyTxn.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadOnlyTxn.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadOnlyTxn.java Mon May  7 07:53:21 2012
@@ -27,23 +27,5 @@ package org.apache.directory.server.core
 /** Package protected */
 class ReadOnlyTxn extends AbstractTransaction
 {
-    private int nbRef = 0;
-
-
-    public void releaseTxn()
-    {
-        nbRef--;
-    }
-
-
-    public void acquireTxn()
-    {
-        nbRef++;
-    }
-
-
-    public boolean isReused()
-    {
-        return nbRef > 1;
-    }
+   
 }

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadWriteTxn.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadWriteTxn.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadWriteTxn.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/ReadWriteTxn.java Mon May  7 07:53:21 2012
@@ -670,6 +670,22 @@ class ReadWriteTxn extends AbstractTrans
             }
         }
     }
+    
+    
+    public void clearLogEdits()
+    {
+        LogEdit txnStartMarker = logEdits.get( 0 );
+        
+        logEdits.clear();
+        logEdits.add( txnStartMarker );
+        
+        forwardIndexAdds.clear();
+        reverseIndexAdds.clear();
+        indexDeletes.clear();
+        
+        readDns.clear();
+        writeDns.clear();
+    }
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/Transaction.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/Transaction.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/Transaction.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/Transaction.java Mon May  7 07:53:21 2012
@@ -37,10 +37,34 @@ import org.apache.directory.shared.ldap.
 /** Package protected */
 interface Transaction extends TxnHandle
 {
-    boolean isExclusive();
+    /**
+     * returns TRUE if optimisticLock held, false otherwise
+     *
+     * @return  TRUE if optimisticLock held, false otherwise
+     */
+    boolean isOptimisticLockHeld();
+    
+    
+    /**
+     * Called after txn gets the optimistic lock
+     *
+     */
+    void setOptimisticLockHeld();
     
     
-    void setExclusive();
+    /**
+     * Called after txn release the optimistic lock
+     */
+    void clearOptimisticLockHeld();
+    
+    
+    /**
+     * 
+     * Returns the version of the logical data this txn sees.
+     *
+     * @return version of the logical data this txn sees.
+     */
+    long getLogicalDataVersion();
     
     
     /**
@@ -65,10 +89,9 @@ interface Transaction extends TxnHandle
      * is updated accordingly.
      *
      * @param startTime start time of the txn
+     * @param version of the logical data this txn sees
      */
-    //void startTxn( long startTime );
-
-    void reuseTxn();
+    void startTxn( long startTime, long logicalDataVerion  );
 
 
     /**

Modified: directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/TxnManagerInternal.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/TxnManagerInternal.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/TxnManagerInternal.java (original)
+++ directory/apacheds/branches/apacheds-txns/core-shared/src/main/java/org/apache/directory/server/core/shared/txn/TxnManagerInternal.java Mon May  7 07:53:21 2012
@@ -37,4 +37,19 @@ interface TxnManagerInternal extends Txn
      * @return current txn
      */
     Transaction getCurTxn();
+    
+    
+    /**
+     *  Returns the current version of logical data
+     *
+     * @return the current version of logical data
+     */
+    long getLogicalDataVersion();
+    
+    
+    /**
+     * Bumps the current version of logical data. Caller is 
+     * assumed to provide synchronization.
+     */
+    void bumpLogicalDataVersion();
 }

Modified: directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=1334904&r1=1334903&r2=1334904&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/branches/apacheds-txns/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Mon May  7 07:53:21 2012
@@ -300,7 +300,7 @@ public class DefaultDirectoryService imp
     private DnFactory dnFactory;
 
     /** The Subentry cache */
-    SubentryCache subentryCache = new SubentryCache();
+    SubentryCache subentryCache;
 
     /** The Subtree evaluator instance */
     private SubtreeEvaluator evaluator;
@@ -1263,7 +1263,8 @@ public class DefaultDirectoryService imp
                 }
                 catch ( LdapException e )
                 {
-                    //e.printStackTrace();
+                    e.printStackTrace();
+                    throw e;
                 }
                 catch ( Exception e )
                 {
@@ -1901,6 +1902,19 @@ public class DefaultDirectoryService imp
         }
     }
 
+    
+    private void initializeCaches()
+    {   
+        // Initialize the AP caches
+        accessControlAPCache = new DnNode<AccessControlAdministrativePoint>();
+        collectiveAttributeAPCache = new DnNode<CollectiveAttributeAdministrativePoint>();
+        subschemaAPCache = new DnNode<SubschemaAdministrativePoint>();
+        triggerExecutionAPCache = new DnNode<TriggerExecutionAdministrativePoint>();
+        
+        // Reinit the subentry cache as well
+        subentryCache = new SubentryCache();
+    }
+    
 
     /**
      * Kicks off the initialization of the entire system.
@@ -1919,15 +1933,12 @@ public class DefaultDirectoryService imp
         {
             setDefaultInterceptorConfigurations();
         }
-
+        
         cacheService = new CacheService();
         cacheService.initialize( this );
 
-        // Initialize the AP caches
-        accessControlAPCache = new DnNode<AccessControlAdministrativePoint>();
-        collectiveAttributeAPCache = new DnNode<CollectiveAttributeAdministrativePoint>();
-        subschemaAPCache = new DnNode<SubschemaAdministrativePoint>();
-        triggerExecutionAPCache = new DnNode<TriggerExecutionAdministrativePoint>();
+        // prepare caches
+        initializeCaches();
 
         dnFactory = new DefaultDnFactory( schemaManager, cacheService.getCache( "dnCache" ) );
 
@@ -2390,6 +2401,14 @@ public class DefaultDirectoryService imp
         return triggerExecutionAPCache;
     }
 
+    
+    /**
+     * {@inheritDoc}
+     */
+    public void resetCaches()
+    {
+        initializeCaches();
+    }
 
     /**
      * {@inheritDoc}



Mime
View raw message