You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/07/08 02:22:13 UTC

svn commit: r961543 - in /directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree: SubentryCache.java SubentryInterceptor.java

Author: elecharny
Date: Thu Jul  8 00:22:12 2010
New Revision: 961543

URL: http://svn.apache.org/viewvc?rev=961543&view=rev
Log:
o Reworked the Subentry cache :
- added a max size
- used DN instead of String as parameters
- added Javadoc
o Cleaned and improved a bit the subentry interceptor

Modified:
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java?rev=961543&r1=961542&r2=961543&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java Thu Jul  8 00:22:12 2010
@@ -24,51 +24,116 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.directory.shared.ldap.name.DN;
 import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;
 
 
 /**
- * A cache for subtree specifications. It associates a 
+ * A cache for subtree specifications. It associates a Subentry with a DN,
+ * representing its position in the DIT.<br>
+ * This cache has a size limit set to 1000 at the moment. We should add a configuration
+ * parameter to manage its size.
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 public class SubentryCache
 {
-    private final Map<String, Subentry> name2subentry = new HashMap<String, Subentry>();
+    /** The default cache size limit */
+    private static final int DEFAULT_CACHE_MAX_SIZE = 1000;
     
+    /** The cache size limit */
+    private int cacheMaxSize = DEFAULT_CACHE_MAX_SIZE;
     
-    final Subentry getSubentry( String normalizedName )
+    /** The current cache size */
+    private AtomicInteger cacheSize;
+    
+    /** The Subentry cache */
+    private final Map<String, Subentry> cache;
+    
+    /**
+     * Creates a new instance of SubentryCache with a default maximum size.
+     */
+    public SubentryCache()
+    {
+        cache = new HashMap<String, Subentry>();
+        cacheSize = new AtomicInteger( 0 );
+    }
+    
+    
+    /**
+     * Creates a new instance of SubentryCache with a specific maximum size.
+     */
+    public SubentryCache( int maxSize )
+    {
+        cache = new HashMap<String, Subentry>();
+        cacheSize = new AtomicInteger( 0 );
+        cacheMaxSize = maxSize;
+    }
+    
+    
+    /**
+     * Retrieve a Subentry given a AP DN. If there is none, null will be returned.
+     *
+     * @param apDn The AdministrativePoint we want to get the Subentry for 
+     * @return The found Subentry, or null
+     */
+    final Subentry getSubentry( DN apDn )
     {
-        return name2subentry.get( normalizedName );
+        return cache.get( apDn.getNormName() );
     }
     
     
-    final Subentry removeSubentry( String normalizedName )
+    /**
+     * Remove a Subentry for a given AdministrativePoint 
+     *
+     * @param apDn The administrativePoint for which we want to remove the 
+     * associated Subentry
+     * @return The removed Subentry, if any
+     */
+    final Subentry removeSubentry( DN apDn )
     {
-        return  name2subentry.remove( normalizedName );
+        return  cache.remove( apDn.getNormName() );
     }
     
     
-    final Subentry setSubentry( String normalizedName, SubtreeSpecification ss, Set<AdministrativeRole> adminRoles )
+    /**
+     * Stores a new Subentry into the cache, associated with an AdministrativePoint
+     *
+     * @param apDn The administrativePoint DN
+     * @param ss The SubtreeSpecification
+     * @param adminRoles The administrative roles for this Subentry
+     * @return The old Subentry, if any
+     */
+    final Subentry addSubentry( DN apDn, SubtreeSpecification ss, Set<AdministrativeRole> adminRoles )
     {
-        Subentry old = name2subentry.get( normalizedName );
+        Subentry oldSubentry = cache.get( apDn.getNormName() );
         Subentry subentry = new Subentry();
         subentry.setSubtreeSpecification( ss );
         subentry.setAdministrativeRoles( adminRoles );
-        name2subentry.put( normalizedName, subentry );
-        return old;
+        cache.put( apDn.getNormName(), subentry );
+        
+        return oldSubentry;
     }
     
     
-    final boolean hasSubentry( String normalizedName )
+    /**
+     * Tells if there is a Subentry associated with an administrativePoint
+     * @param apDn The administrativePoint DN
+     * @return True if a Subentry is found
+     */
+    final boolean hasSubentry( DN apDn )
     {
-        return name2subentry.containsKey( normalizedName );
+        return cache.containsKey( apDn.getNormName() );
     }
     
     
+    /**
+     * @return An Iterator over the AdministartivePoints normalized DNs 
+     */
     final Iterator<String> nameIterator()
     {
-        return name2subentry.keySet().iterator();
+        return cache.keySet().iterator();
     }
 }

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java?rev=961543&r1=961542&r2=961543&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java Thu Jul  8 00:22:12 2010
@@ -187,7 +187,7 @@ public class SubentryInterceptor extends
                     }
     
                     dnName.normalize( schemaManager.getNormalizerMapping() );
-                    subentryCache.setSubentry( dnName.getNormName(), ss, getSubentryAdminRoles( subentry ) );
+                    subentryCache.addSubentry( dnName, ss, getSubentryAdminRoles( subentry ) );
                 }
                 
                 subentries.close();
@@ -327,8 +327,9 @@ public class SubentryInterceptor extends
         {
             String subentryDnStr = list.next();
             DN subentryDn = new DN( subentryDnStr );
+            subentryDn.normalize( schemaManager.getNormalizerMapping() );
             DN apDn = subentryDn.getParent();
-            Subentry subentry = subentryCache.getSubentry( subentryDnStr );
+            Subentry subentry = subentryCache.getSubentry( subentryDn );
             SubtreeSpecification ss = subentry.getSubtreeSpecification();
 
             if ( evaluator.evaluate( ss, apDn, dn, entryAttrs ) )
@@ -453,7 +454,7 @@ public class SubentryInterceptor extends
                 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
             }
 
-            subentryCache.setSubentry( name.getNormName(), ss, getSubentryAdminRoles( entry ) );
+            subentryCache.addSubentry( name, ss, getSubentryAdminRoles( entry ) );
 
             next.add( addContext );
 
@@ -511,10 +512,9 @@ public class SubentryInterceptor extends
             while ( list.hasNext() )
             {
                 String subentryDnStr = list.next();
-                DN subentryDn = new DN( subentryDnStr );
-                DN apDn = ( DN ) subentryDn.clone();
-                apDn.remove( apDn.size() - 1 );
-                Subentry subentry = subentryCache.getSubentry( subentryDnStr );
+                DN subentryDn = new DN( subentryDnStr ).normalize( schemaManager.getNormalizerMapping() );
+                DN apDn = subentryDn.getParent();
+                Subentry subentry = subentryCache.getSubentry( subentryDn );
                 SubtreeSpecification ss = subentry.getSubtreeSpecification();
 
                 if ( evaluator.evaluate( ss, apDn, name, entry ) )
@@ -602,7 +602,7 @@ public class SubentryInterceptor extends
         {
             next.delete( deleteContext );
 
-            SubtreeSpecification ss = subentryCache.removeSubentry( name.getNormName() ).getSubtreeSpecification();
+            SubtreeSpecification ss = subentryCache.removeSubentry( name ).getSubtreeSpecification();
 
             /* ----------------------------------------------------------------
              * Find the baseDn for the subentry and use that to search the tree
@@ -612,8 +612,7 @@ public class SubentryInterceptor extends
              * attributes we remove from the entry in a modify operation.
              * ----------------------------------------------------------------
              */
-            DN apName = ( DN ) name.clone();
-            apName.remove( name.size() - 1 );
+            DN apName = name.getParent();
             DN baseDn = ( DN ) apName.clone();
             baseDn.addAll( ss.getBase() );
 
@@ -723,9 +722,9 @@ public class SubentryInterceptor extends
 
         while ( subentries.hasNext() )
         {
-            String subentryDn = subentries.next();
-            DN apDn = new DN( subentryDn );
-            apDn.remove( apDn.size() - 1 );
+            String subentryDnStr = subentries.next();
+            DN subentryDn = new DN( subentryDnStr ).normalize( schemaManager.getNormalizerMapping() );
+            DN apDn = subentryDn.getParent();
             SubtreeSpecification ss = subentryCache.getSubentry( subentryDn ).getSubtreeSpecification();
             boolean isOldNameSelected = evaluator.evaluate( ss, apDn, oldName, entry );
             boolean isNewNameSelected = evaluator.evaluate( ss, apDn, newName, entry );
@@ -746,7 +745,7 @@ public class SubentryInterceptor extends
                     if ( opAttr != null )
                     {
                         opAttr = opAttr.clone();
-                        opAttr.remove( subentryDn );
+                        opAttr.remove( subentryDnStr );
 
                         if ( opAttr.size() < 1 )
                         {
@@ -765,7 +764,7 @@ public class SubentryInterceptor extends
                     ModificationOperation op = ModificationOperation.ADD_ATTRIBUTE;
                     EntryAttribute opAttr = new DefaultEntryAttribute( aSUBENTRY_OPATTRS, schemaManager
                         .lookupAttributeTypeRegistry( aSUBENTRY_OPATTRS ) );
-                    opAttr.add( subentryDn );
+                    opAttr.add( subentryDnStr );
                     modList.add( new DefaultModification( op, opAttr ) );
                 }
             }
@@ -786,7 +785,7 @@ public class SubentryInterceptor extends
         if ( objectClasses.contains( SchemaConstants.SUBENTRY_OC ) )
         {
             // @Todo To be reviewed !!!
-            Subentry subentry = subentryCache.getSubentry( oldDn.getNormName() );
+            Subentry subentry = subentryCache.getSubentry( oldDn );
             SubtreeSpecification ss = subentry.getSubtreeSpecification();
             DN apName = ( DN ) oldDn.clone();
             apName.remove( apName.size() - 1 );
@@ -796,12 +795,12 @@ public class SubentryInterceptor extends
             newName.remove( newName.size() - 1 );
 
             newName.add( renameContext.getNewRdn() );
+            newName.normalize( schemaManager.getNormalizerMapping() );
 
-            String newNormName = newName.getNormName();
-            subentryCache.setSubentry( newNormName, ss, subentry.getAdministrativeRoles() );
+            subentryCache.addSubentry( newName, ss, subentry.getAdministrativeRoles() );
             next.rename( renameContext );
 
-            subentry = subentryCache.getSubentry( newNormName );
+            subentry = subentryCache.getSubentry( newName );
             ExprNode filter = new PresenceNode( schemaManager.getAttributeTypeRegistry().getOidByName(
                 SchemaConstants.OBJECT_CLASS_AT ) );
             SearchControls controls = new SearchControls();
@@ -873,22 +872,20 @@ public class SubentryInterceptor extends
 
         if ( objectClasses.contains( SchemaConstants.SUBENTRY_OC ) )
         {
-            Subentry subentry = subentryCache.getSubentry( oldDn.getNormName() );
+            Subentry subentry = subentryCache.getSubentry( oldDn );
             SubtreeSpecification ss = subentry.getSubtreeSpecification();
-            DN apName = ( DN ) oldDn.clone();
-            apName.remove( apName.size() - 1 );
+            DN apName = oldDn.getParent();
             DN baseDn = ( DN ) apName.clone();
             baseDn.addAll( ss.getBase() );
-            DN newName = ( DN ) newSuperiorDn.clone();
-            newName.remove( newName.size() - 1 );
+            DN newName = newSuperiorDn.getParent();
 
             newName.add( moveAndRenameContext.getNewRdn() );
+            newName.normalize( schemaManager.getNormalizerMapping() );
 
-            String newNormName = newName.getNormName();
-            subentryCache.setSubentry( newNormName, ss, subentry.getAdministrativeRoles() );
+            subentryCache.addSubentry( newName, ss, subentry.getAdministrativeRoles() );
             next.moveAndRename( moveAndRenameContext );
 
-            subentry = subentryCache.getSubentry( newNormName );
+            subentry = subentryCache.getSubentry( newName );
 
             ExprNode filter = new PresenceNode( schemaManager.getAttributeTypeRegistry().getOidByName(
                 SchemaConstants.OBJECT_CLASS_AT ) );
@@ -963,21 +960,19 @@ public class SubentryInterceptor extends
 
         if ( objectClasses.contains( SchemaConstants.SUBENTRY_OC ) )
         {
-            Subentry subentry = subentryCache.getSubentry( oldDn.getNormName() );
+            Subentry subentry = subentryCache.getSubentry( oldDn );
             SubtreeSpecification ss = subentry.getSubtreeSpecification();
-            DN apName = ( DN ) oldDn.clone();
-            apName.remove( apName.size() - 1 );
+            DN apName = oldDn.getParent();
             DN baseDn = ( DN ) apName.clone();
             baseDn.addAll( ss.getBase() );
-            DN newName = ( DN ) newSuperiorDn.clone();
-            newName.remove( newName.size() - 1 );
-            newName.add( newSuperiorDn.get( newSuperiorDn.size() - 1 ) );
+            DN newName = (DN)newSuperiorDn.clone();
+            newName.add( oldDn.getRdn() );
+            newName.normalize( schemaManager.getNormalizerMapping() );
 
-            String newNormName = newName.getNormName();
-            subentryCache.setSubentry( newNormName, ss, subentry.getAdministrativeRoles() );
+            subentryCache.addSubentry( newName, ss, subentry.getAdministrativeRoles() );
             next.move( moveContext );
 
-            subentry = subentryCache.getSubentry( newNormName );
+            subentry = subentryCache.getSubentry( newName );
 
             ExprNode filter = new PresenceNode( SchemaConstants.OBJECT_CLASS_AT );
             SearchControls controls = new SearchControls();
@@ -1107,7 +1102,7 @@ public class SubentryInterceptor extends
 
         if ( objectClasses.contains( SchemaConstants.SUBENTRY_OC ) && isSubtreeSpecificationModification )
         {
-            SubtreeSpecification ssOld = subentryCache.removeSubentry( dn.getNormName() ).getSubtreeSpecification();
+            SubtreeSpecification ssOld = subentryCache.removeSubentry( dn ).getSubtreeSpecification();
             SubtreeSpecification ssNew;
 
             try
@@ -1121,7 +1116,7 @@ public class SubentryInterceptor extends
                 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
             }
 
-            subentryCache.setSubentry( dn.getNormName(), ssNew, getSubentryTypes( entry, mods ) );
+            subentryCache.addSubentry( dn, ssNew, getSubentryTypes( entry, mods ) );
             next.modify( modifyContext );
 
             // search for all entries selected by the old SS and remove references to subentry
@@ -1163,7 +1158,7 @@ public class SubentryInterceptor extends
             }
 
             // search for all selected entries by the new SS and add references to subentry
-            Subentry subentry = subentryCache.getSubentry( dn.getNormName() );
+            Subentry subentry = subentryCache.getSubentry( dn );
             Entry operational = getSubentryOperationalAttributes( dn, subentry );
             DN newBaseDn = ( DN ) apName.clone();
             newBaseDn.addAll( ssNew.getBase() );
@@ -1457,10 +1452,8 @@ public class SubentryInterceptor extends
     {
         public boolean accept( SearchingOperationContext searchContext, ClonedServerEntry entry ) throws Exception
         {
-            String dn = entry.getDn().getNormName();
-
             // see if we can get a match without normalization
-            if ( subentryCache.hasSubentry( dn ) )
+            if ( subentryCache.hasSubentry( entry.getDn() ) )
             {
                 return false;
             }
@@ -1472,11 +1465,8 @@ public class SubentryInterceptor extends
             {
                 return !objectClasses.contains( SchemaConstants.SUBENTRY_OC );
             }
-
-            DN ndn = new DN( dn );
-            ndn.normalize( schemaManager.getNormalizerMapping() );
-            String normalizedDn = ndn.getNormName();
-            return !subentryCache.hasSubentry( normalizedDn );
+            
+            return false;
         }
     }
 
@@ -1488,10 +1478,8 @@ public class SubentryInterceptor extends
     {
         public boolean accept( SearchingOperationContext searchContext, ClonedServerEntry entry ) throws Exception
         {
-            String dn = entry.getDn().getNormName();
-
             // see if we can get a match without normalization
-            if ( subentryCache.hasSubentry( dn ) )
+            if ( subentryCache.hasSubentry( entry.getDn() ) )
             {
                 return true;
             }
@@ -1504,9 +1492,7 @@ public class SubentryInterceptor extends
                 return objectClasses.contains( SchemaConstants.SUBENTRY_OC );
             }
 
-            DN ndn = new DN( dn );
-            ndn.normalize( schemaManager.getNormalizerMapping() );
-            return subentryCache.hasSubentry( ndn.getNormName() );
+            return false;
         }
     }
 
@@ -1519,9 +1505,9 @@ public class SubentryInterceptor extends
 
         while ( subentries.hasNext() )
         {
-            String subentryDn = subentries.next();
-            DN apDn = new DN( subentryDn );
-            apDn.remove( apDn.size() - 1 );
+            String subentryDnStr = subentries.next();
+            DN subentryDn = new DN( subentryDnStr ).normalize( schemaManager.getNormalizerMapping() );
+            DN apDn = subentryDn.getParent();
             SubtreeSpecification ss = subentryCache.getSubentry( subentryDn ).getSubtreeSpecification();
             boolean isOldEntrySelected = evaluator.evaluate( ss, apDn, name, oldEntry );
             boolean isNewEntrySelected = evaluator.evaluate( ss, apDn, name, newEntry );
@@ -1542,7 +1528,7 @@ public class SubentryInterceptor extends
                     if ( opAttr != null )
                     {
                         opAttr = opAttr.clone();
-                        opAttr.remove( subentryDn );
+                        opAttr.remove( subentryDnStr );
 
                         if ( opAttr.size() < 1 )
                         {
@@ -1561,7 +1547,7 @@ public class SubentryInterceptor extends
                     ModificationOperation op = ModificationOperation.ADD_ATTRIBUTE;
                     AttributeType type = schemaManager.lookupAttributeTypeRegistry( attribute );
                     EntryAttribute opAttr = new DefaultEntryAttribute( attribute, type );
-                    opAttr.add( subentryDn );
+                    opAttr.add( subentryDnStr );
                     modList.add( new DefaultModification( op, opAttr ) );
                 }
             }