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 2007/05/23 18:56:49 UTC

svn commit: r540991 - in /directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition: AbstractPartitionStructure.java DefaultPartitionNexus.java PartitionContainer.java PartitionHandler.java PartitionStructure.java

Author: elecharny
Date: Wed May 23 09:56:47 2007
New Revision: 540991

URL: http://svn.apache.org/viewvc?view=rev&rev=540991
Log:
Added classes to hold the new Partition structure needed to find the partition suffices for each operation
Patched the code to use this new structure (it will be much faster because we don't anymore parse and clone each DN)
added some synchronization to avoid a race condition if a partition is being removed

Added:
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/AbstractPartitionStructure.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionContainer.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionHandler.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionStructure.java
Modified:
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java

Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/AbstractPartitionStructure.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/AbstractPartitionStructure.java?view=auto&rev=540991
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/AbstractPartitionStructure.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/AbstractPartitionStructure.java Wed May 23 09:56:47 2007
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition;
+
+import org.apache.directory.shared.ldap.name.LdapDN;
+
+/**
+ * This abstract class is just used to implement the utility method needed to build the
+ * global partition structue used by the getBackend method. 
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+
+public abstract class AbstractPartitionStructure implements PartitionStructure
+{
+    /**
+     * @see PartitionStructure#buildPartitionStructure(PartitionStructure, LdapDN, int, Partition)
+     */
+    public PartitionStructure buildPartitionStructure( PartitionStructure current, LdapDN dn, int index, Partition partition )
+    {
+        if ( index == dn.size() - 1 )
+        {
+            return current.addPartitionHandler( dn.getRdn( index ).toString(), new PartitionHandler( partition ) );
+        }
+        else
+        {
+            return current.addPartitionHandler( dn.getRdn( index ).toString(), 
+                buildPartitionStructure( new PartitionContainer(), dn, index + 1, partition ) );
+        }
+    }
+}

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java?view=diff&rev=540991&r1=540990&r2=540991
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java (original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/DefaultPartitionNexus.java Wed May 23 09:56:47 2007
@@ -73,7 +73,6 @@
 import org.apache.directory.shared.ldap.message.SubentriesControl;
 import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect;
 import org.apache.directory.shared.ldap.name.LdapDN;
-import org.apache.directory.shared.ldap.name.Rdn;
 import org.apache.directory.shared.ldap.schema.AttributeType;
 import org.apache.directory.shared.ldap.schema.Normalizer;
 import org.apache.directory.shared.ldap.schema.UsageEnum;
@@ -123,99 +122,9 @@
     /** the backends keyed by normalized suffix strings */
     private Map<String, Partition> partitions = new HashMap<String, Partition>();
     
+    /** A structure to hold all the partitions */
     private PartitionStructure partitionList = new PartitionContainer();
     
-    private interface PartitionStructure
-    {
-        boolean isPartition();
-        public PartitionStructure addPartitionHandler( String name, PartitionStructure children );
-    }
-    
-    private class PartitionContainer implements PartitionStructure
-    {
-        private Map<String, PartitionStructure> children;
-        
-        private PartitionContainer()
-        {
-            children = new HashMap<String, PartitionStructure>();
-        }
-        
-        public boolean isPartition()
-        {
-            return false;
-        }
-        
-        public PartitionStructure addPartitionHandler( String name, PartitionStructure child )
-        {
-            children.put( name, child );
-            return this;
-        }
-        
-        public String toString()
-        {
-            StringBuilder sb = new StringBuilder();
-            
-            sb.append( "Partition container :\n" );
-            
-            for ( PartitionStructure child:children.values() )
-            {
-                sb.append( '{' ).append( child.toString() ).append( "} " );
-            }
-            
-            return sb.toString();
-        }
-    }
-    
-    private class PartitionHandler implements PartitionStructure
-    {
-        private Partition partition;
-        
-        private PartitionHandler( Partition partition )
-        {
-            this.partition = partition;
-        }
-
-        public boolean isPartition()
-        {
-            return true;
-        }
-
-        public PartitionStructure addPartitionHandler( String name, PartitionStructure partition )
-        {
-            return this;
-        }
-        
-        public Partition getpartition()
-        {
-            return partition;
-        }
-
-        public String toString()
-        {
-            try
-            {
-                return partition.getSuffix().getUpName();
-            }
-            catch ( NamingException ne )
-            {
-                return "Unkown partition";
-            }
-        }
-}
-    
-    private PartitionStructure buildPartitionStructure( PartitionStructure current, LdapDN dn, int index, Partition partition )
-    {
-        if ( index == dn.size() - 1 )
-        {
-            return current.addPartitionHandler( dn.getRdn( index ).toString(), new PartitionHandler( partition ) );
-        }
-        else
-        {
-            return current.addPartitionHandler( dn.getRdn( index ).toString(), 
-                buildPartitionStructure( new PartitionContainer(), dn, index + 1, partition ) );
-        }
-    }
-
     /** the read only rootDSE attributes */
     private final Attributes rootDSE;
 
@@ -479,12 +388,15 @@
             throw new ConfigurationException( "Duplicate partition suffix: " + key );
         }
         
-        partitions.put( key, system );
+        synchronized ( partitionList )
+        {
+            partitions.put( key, system );
         
-        buildPartitionStructure( partitionList, system.getSuffix(), 0, system );
+            partitionList.buildPartitionStructure( partitionList, system.getSuffix(), 0, system );
 
-        Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
-        namingContexts.add( system.getUpSuffix().getUpName() );
+            Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
+            namingContexts.add( system.getUpSuffix().getUpName() );
+        }
 
         return systemCfg;
     }
@@ -654,12 +566,15 @@
             partition.init( factoryCfg, config );
         }
         
-        partitions.put( partition.getSuffix().toString(), partition );
-        
-        buildPartitionStructure( partitionList, partition.getSuffix(), 0, partition );
+        synchronized ( partitionList )
+        {
+            partitions.put( partition.getSuffix().toString(), partition );
+            
+            partitionList.buildPartitionStructure( partitionList, partition.getSuffix(), 0, partition );
 
-        Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
-        namingContexts.add( partition.getUpSuffix().getUpName() );
+            Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
+            namingContexts.add( partition.getUpSuffix().getUpName() );
+        }
     }
 
 
@@ -675,10 +590,25 @@
 
         Attribute namingContexts = rootDSE.get( NAMINGCTXS_ATTR );
         namingContexts.remove( partition.getUpSuffix().getUpName() );
-        partitions.remove( key );
 
-        partition.sync();
-        partition.destroy();
+        // Create a new partition list. 
+        // This is easier to create a new structure from scratch than to reorganize
+        // the current structure. As this strcuture is not modified often
+        // this is an acceptable solution.
+        synchronized (partitionList)
+        {
+            partitions.remove( key );
+        
+            partitionList = new PartitionContainer();
+            
+            for ( Partition part:partitions.values() )
+            {
+                partitionList.buildPartitionStructure( partitionList, part.getSuffix(), 0, partition );
+            }
+    
+            partition.sync();
+            partition.destroy();
+        }
     }
 
 
@@ -827,19 +757,6 @@
 
 
     /**
-<<<<<<< .mine
-=======
-     * @see Partition#modify(org.apache.directory.shared.ldap.name.LdapDN,javax.naming.directory.ModificationItem[])
-     */
-    /*public void modify( LdapDN dn, ModificationItemImpl[] mods ) throws NamingException
-    {
-        Partition backend = getBackend( dn );
-        backend.modify( dn, mods );
-    }*/
-
-
-    /**
->>>>>>> .r530934
      * @see Partition#list(org.apache.directory.shared.ldap.name.LdapDN)
      */
     public NamingEnumeration list( OperationContext opContext ) throws NamingException
@@ -1108,16 +1025,32 @@
      */
     private Partition getBackend( LdapDN dn ) throws NamingException
     {
-        LdapDN clonedDn = ( LdapDN ) dn.clone();
+        Enumeration<String> rdns = dn.getAll();
+        PartitionStructure currentPartition = partitionList;
         
-        while ( clonedDn.size() > 0 )
+        // This is synchronized so that we can't read the
+        // partitionList when it is modified.
+        synchronized ( partitionList )
         {
-            if ( partitions.containsKey( clonedDn.toString() ) )
+            // Iterate through all the RDN until we find the associated partition
+            while ( rdns.hasMoreElements() )
             {
-                return partitions.get( clonedDn.toString() );
+                String rdn = rdns.nextElement();
+                
+                if ( currentPartition.contains( rdn ) )
+                {
+                    currentPartition = currentPartition.getPartition( rdn );
+    
+                    if ( currentPartition.isPartition() )
+                    {
+                        return currentPartition.getPartition();
+                    }
+                }
+                else
+                {
+                    break;
+                }
             }
-
-            clonedDn.remove( clonedDn.size() - 1 );
         }
         
         throw new LdapNameNotFoundException( dn.getUpName() );

Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionContainer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionContainer.java?view=auto&rev=540991
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionContainer.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionContainer.java Wed May 23 09:56:47 2007
@@ -0,0 +1,133 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 
+ * The Partition Container holds entries which can be either Partitions or 
+ * Containers. 
+ * 
+ * We can see them as directories, where Partitions are the files.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PartitionContainer extends AbstractPartitionStructure
+{
+    /** Stores the list of all the descendant partitions and containers */
+    private Map<String, PartitionStructure> children;
+    
+    /**
+     * Creates a new instance of PartitionContainer.
+     */
+    public PartitionContainer()
+    {
+        children = new HashMap<String, PartitionStructure>();
+    }
+
+    /**
+     * @see PartitionStructure#isPartition()
+     */
+    public boolean isPartition()
+    {
+        return false;
+    }
+    
+    /**
+     * @see PartitionStructure#addPartitionHandler( String, PartitionStructure )
+     */
+    public PartitionStructure addPartitionHandler( String name, PartitionStructure child )
+    {
+        children.put( name, child );
+        return this;
+    }
+    
+    /**
+     * @see PartitionStructure#contains( String )     
+     */
+    public boolean contains( String name )
+    {
+        return children.containsKey( name );
+    }
+    
+    /**
+     * @see PartitionStructure#getPartition()
+     * 
+     * As this is a container, we just return null;
+     */
+    public Partition getPartition()
+    {
+        return null;
+    }
+
+    /**
+     * @see PartitionStructure#getPartition( String )
+     */
+    public PartitionStructure getPartition( String name )
+    {
+        if ( children.containsKey( name ) )
+        {
+            return children.get( name );
+        }
+        else
+        {
+            return null;
+        }
+    }
+    
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( " { " );
+        
+        boolean isFirst = true;
+        
+        for ( PartitionStructure child:children.values() )
+        {
+            if ( isFirst )
+            {
+                isFirst = false;
+            }
+            else
+            {
+                sb.append(  ", " );
+            }
+
+            if ( child instanceof PartitionContainer )
+            {
+                sb.append( "C:").append( child.toString() );
+            }
+            else
+            {
+                sb.append( "P: " ).append( "'" ).append( child.toString() ).append( "'" );
+            }
+        }
+
+        sb.append( " } " );
+        
+        return sb.toString();
+    }
+}

Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionHandler.java?view=auto&rev=540991
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionHandler.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionHandler.java Wed May 23 09:56:47 2007
@@ -0,0 +1,121 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition;
+
+import javax.naming.NamingException;
+
+/**
+ * 
+ * Stores a real Partition. This object is itself stored into a Pazrtition Container.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class PartitionHandler extends AbstractPartitionStructure
+{
+    /** The stored partition */
+    private Partition partition;
+    
+    /**
+     * 
+     * Creates a new instance of PartitionHandler.
+     *
+     * @param partition The partition to store
+     */
+    public PartitionHandler( Partition partition )
+    {
+        this.partition = partition;
+    }
+
+    /**
+     * @see PartitionStructure#isPartition()
+     */
+    public boolean isPartition()
+    {
+        return true;
+    }
+    
+    /**
+     * @see PartitionStructure#contains( String )
+     */
+    public boolean contains( String name )
+    {
+        try
+        {
+            return partition.getSuffix().getNormName().equals(  name  );
+        }
+        catch ( NamingException ne )
+        {
+            return false;
+        }
+    }
+
+    /**
+     * @see PartitionStructure#addPartitionHandler( String, PartitionStructure )
+     */
+    public PartitionStructure addPartitionHandler( String name, PartitionStructure partition )
+    {
+        return this;
+    }
+    
+    /**
+     * @see PartitionStructure#getPartition()
+     */
+    public Partition getPartition()
+    {
+        return partition;
+    }
+
+    /**
+     * @see PartitionStructure#getPartition( String )
+     */
+    public PartitionStructure getPartition( String name )
+    {
+        try
+        {
+            if ( partition.getSuffix().getNormName().equals( name ) )
+            {
+                return this;
+            }
+            else
+            {
+                return null;
+            }
+        }
+        catch ( NamingException ne )
+        {
+            return null;
+        }
+    }
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString()
+    {
+        try
+        {
+            return partition.getSuffix().getUpName();
+        }
+        catch ( NamingException ne )
+        {
+            return "Unkown partition";
+        }
+    }
+}

Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionStructure.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionStructure.java?view=auto&rev=540991
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionStructure.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/partition/PartitionStructure.java Wed May 23 09:56:47 2007
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.core.partition;
+
+import org.apache.directory.shared.ldap.name.LdapDN;
+
+/**
+ * An interface for PartitionStructure implementations. 
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public interface PartitionStructure
+{
+    /**
+     * Tells if the implementation is a Partition object. If it's a PartitionContainer
+     * instance, it returns false.
+     *
+     * @return <code>true</code> if the class is an instance of PartitionHandler, false otherwise.
+     */
+    boolean isPartition();
+    
+    /**
+     * Add a new Partition to the current container.
+     *
+     * @param name The partition name
+     * @param children The PartitionStructure object (it should be a PartitionHandler)
+     * @return The current PartitionStructure to which a Partition has been added.
+     */
+    PartitionStructure addPartitionHandler( String name, PartitionStructure children );
+    
+    /**
+     * Tells if the current PartitionStructure contains the given partition.
+     * 
+     * If the PartitionStructure is an instance of PartitionHandler, returns true
+     * if the partition's name equals the given name.
+     *
+     * If the PartitionStructure is an instance of PartitionContainer, returns true
+     * if the container's children contains the given name.
+     *
+     * @param name The name we are looking for
+     * @return <code>true</code> if the PartitionStructure instance contains this name
+     */
+    boolean contains( String name );
+    
+    /**
+     * Returns the Partition associated with this name, if any, or null if the name is not 
+     * found
+     *
+     * @param name The name we are looking for 
+     * @return The associated PartitionHandler or PartitionContainer
+     */
+    PartitionStructure getPartition( String name );
+    
+    /**
+     * @return Get the partition if the object is an instance of PartitionHandler, null otherwise
+     */
+    Partition getPartition();
+    
+    /**
+     * Construct the global partition structure, assuming the DN passed as an argument is a partition
+     * name.
+     * 
+     * This is a recursive method.
+     *
+     * @param current The current structure
+     * @param dn The DN associated with the partition
+     * @param index The current RDN being processed 
+     * @param partition The associated partition
+     * @return The modified global structure.
+     */
+    PartitionStructure buildPartitionStructure( PartitionStructure current, LdapDN dn, int index, Partition partition );
+}