Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 50239 invoked from network); 11 Jan 2011 15:58:27 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 11 Jan 2011 15:58:27 -0000 Received: (qmail 50342 invoked by uid 500); 11 Jan 2011 15:58:26 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 50287 invoked by uid 500); 11 Jan 2011 15:58:26 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 50280 invoked by uid 99); 11 Jan 2011 15:58:26 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Jan 2011 15:58:26 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Jan 2011 15:58:23 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 63E0423889D5; Tue, 11 Jan 2011 15:57:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1057707 - /directory/apacheds/branches/apacheds-AP/core-api/src/main/java/org/apache/directory/server/core/administrative/SubentryCache.java Date: Tue, 11 Jan 2011 15:57:56 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110111155756.63E0423889D5@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Tue Jan 11 15:57:56 2011 New Revision: 1057707 URL: http://svn.apache.org/viewvc?rev=1057707&view=rev Log: Added synchronization around the cache Modified: directory/apacheds/branches/apacheds-AP/core-api/src/main/java/org/apache/directory/server/core/administrative/SubentryCache.java Modified: directory/apacheds/branches/apacheds-AP/core-api/src/main/java/org/apache/directory/server/core/administrative/SubentryCache.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-AP/core-api/src/main/java/org/apache/directory/server/core/administrative/SubentryCache.java?rev=1057707&r1=1057706&r2=1057707&view=diff ============================================================================== --- directory/apacheds/branches/apacheds-AP/core-api/src/main/java/org/apache/directory/server/core/administrative/SubentryCache.java (original) +++ directory/apacheds/branches/apacheds-AP/core-api/src/main/java/org/apache/directory/server/core/administrative/SubentryCache.java Tue Jan 11 15:57:56 2011 @@ -23,6 +23,7 @@ package org.apache.directory.server.core import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.directory.shared.ldap.exception.LdapException; import org.apache.directory.shared.ldap.name.DN; @@ -44,6 +45,49 @@ public class SubentryCache implements It /** The Subentry DN cache */ private final DnNode dnCache; + /** A lock to guarantee the Subentry cache consistency */ + private ReentrantReadWriteLock mutex = new ReentrantReadWriteLock(); + + /** + * Get a read-lock on the Subentry cache. + * No read operation can be done on the AP cache if this + * method is not called before. + */ + public void lockRead() + { + mutex.readLock().lock(); + } + + + /** + * Get a write-lock on the Subentry cache. + * No write operation can be done on the apCache if this + * method is not called before. + */ + public void lockWrite() + { + mutex.writeLock().lock(); + } + + + /** + * Release the read-write lock on the AP cache. + * This method must be called after having read or modified the + * AP cache + */ + public void unlock() + { + if ( mutex.isWriteLockedByCurrentThread() ) + { + mutex.writeLock().unlock(); + } + else + { + mutex.readLock().unlock(); + } + } + + /** * Creates a new instance of SubentryCache with a default maximum size. */ @@ -63,10 +107,18 @@ public class SubentryCache implements It */ public final Subentry getSubentry( String uuid, AdministrativeRoleEnum role ) { - Subentry[] subentries = uuidCache.get( uuid ); - Subentry subentry = subentries[role.getValue()]; - - return subentry; + try + { + lockRead(); + Subentry[] subentries = uuidCache.get( uuid ); + Subentry subentry = subentries[role.getValue()]; + + return subentry; + } + finally + { + unlock(); + } } @@ -78,9 +130,17 @@ public class SubentryCache implements It */ public final Subentry[] getSubentries( String uuid ) { - Subentry[] subentries = uuidCache.get( uuid ); - - return subentries; + try + { + lockRead(); + Subentry[] subentries = uuidCache.get( uuid ); + + return subentries; + } + finally + { + unlock(); + } } @@ -93,10 +153,18 @@ public class SubentryCache implements It */ public final Subentry getSubentry( DN dn, AdministrativeRoleEnum role ) { - Subentry[] subentries = dnCache.getElement( dn ); - Subentry subentry = subentries[role.getValue()]; - - return subentry; + try + { + lockRead(); + Subentry[] subentries = dnCache.getElement( dn ); + Subentry subentry = subentries[role.getValue()]; + + return subentry; + } + finally + { + unlock(); + } } @@ -108,9 +176,17 @@ public class SubentryCache implements It */ public final Subentry[] getSubentries( DN dn ) { - Subentry[] subentries = dnCache.getElement( dn ); - - return subentries; + try + { + lockRead(); + Subentry[] subentries = dnCache.getElement( dn ); + + return subentries; + } + finally + { + unlock(); + } } @@ -123,9 +199,17 @@ public class SubentryCache implements It */ public final Subentry[] removeSubentry( String uuid ) { - Subentry[] oldSubentry = uuidCache.remove( uuid ); - - return oldSubentry; + try + { + lockWrite(); + Subentry[] oldSubentry = uuidCache.remove( uuid ); + + return oldSubentry; + } + finally + { + unlock(); + } } @@ -138,22 +222,30 @@ public class SubentryCache implements It */ public final Subentry[] removeSubentry( DN dn ) throws LdapException { - Subentry[] oldSubentry = dnCache.getElement( dn ); - dnCache.remove( dn ); - - // Update the UUID cache - if ( oldSubentry != null ) - { - for ( Subentry subentry : oldSubentry ) - { - if ( subentry != null ) + try + { + lockWrite(); + Subentry[] oldSubentry = dnCache.getElement( dn ); + dnCache.remove( dn ); + + // Update the UUID cache + if ( oldSubentry != null ) + { + for ( Subentry subentry : oldSubentry ) { - uuidCache.remove( subentry.getUuid() ); + if ( subentry != null ) + { + uuidCache.remove( subentry.getUuid() ); + } } } + + return oldSubentry; + } + finally + { + unlock(); } - - return oldSubentry; } @@ -166,28 +258,36 @@ public class SubentryCache implements It */ public Subentry[] addSubentry( DN dn, Subentry subentry ) throws LdapException { - Subentry[] subentries = uuidCache.get( subentry.getUuid() ); - - if ( subentries == null ) - { - subentries = new Subentry[4]; - } - - subentries[subentry.getAdministrativeRole().getValue()] = subentry; - Subentry[] oldSubentry = uuidCache.put( subentry.getUuid(), subentries ); - - Subentry[] dnSubentries = dnCache.getElement( dn ); - - if ( dnSubentries != null ) + try { - dnSubentries[subentry.getAdministrativeRole().getValue()] = subentry; + lockWrite(); + Subentry[] subentries = uuidCache.get( subentry.getUuid() ); + + if ( subentries == null ) + { + subentries = new Subentry[4]; + } + + subentries[subentry.getAdministrativeRole().getValue()] = subentry; + Subentry[] oldSubentry = uuidCache.put( subentry.getUuid(), subentries ); + + Subentry[] dnSubentries = dnCache.getElement( dn ); + + if ( dnSubentries != null ) + { + dnSubentries[subentry.getAdministrativeRole().getValue()] = subentry; + } + else + { + dnCache.add( dn, subentries ); + } + + return oldSubentry; } - else + finally { - dnCache.add( dn, subentries ); + unlock(); } - - return oldSubentry; } @@ -198,7 +298,15 @@ public class SubentryCache implements It */ public boolean hasSubentry( String uuid ) { - return uuidCache.containsKey( uuid ); + try + { + lockRead(); + return uuidCache.containsKey( uuid ); + } + finally + { + unlock(); + } } @@ -209,7 +317,15 @@ public class SubentryCache implements It */ public boolean hasSubentry( DN dn ) { - return dnCache.hasElement( dn ); + try + { + lockRead(); + return dnCache.hasElement( dn ); + } + finally + { + unlock(); + } } @@ -222,15 +338,23 @@ public class SubentryCache implements It */ public boolean hasSubentry( String uuid, AdministrativeRoleEnum role ) { - Subentry[] subentries = uuidCache.get( uuid ); - - if ( subentries == null ) + try { - return false; + lockRead(); + Subentry[] subentries = uuidCache.get( uuid ); + + if ( subentries == null ) + { + return false; + } + else + { + return subentries[ role.getValue() ] != null; + } } - else + finally { - return subentries[ role.getValue() ] != null; + unlock(); } } @@ -243,15 +367,23 @@ public class SubentryCache implements It */ public boolean hasSubentry( DN dn, AdministrativeRoleEnum role ) { - Subentry[] subentries = dnCache.getElement( dn ); - - if ( subentries == null ) + try { - return false; + lockRead(); + Subentry[] subentries = dnCache.getElement( dn ); + + if ( subentries == null ) + { + return false; + } + else + { + return subentries[ role.getValue() ] != null; + } } - else + finally { - return subentries[ role.getValue() ] != null; + unlock(); } } @@ -261,6 +393,14 @@ public class SubentryCache implements It */ public Iterator iterator() { - return uuidCache.keySet().iterator(); + try + { + lockRead(); + return uuidCache.keySet().iterator(); + } + finally + { + unlock(); + } } }