directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r792502 - in /directory/apacheds/trunk: core-avl/src/main/java/org/apache/directory/server/core/avltree/ core-avl/src/test/java/org/apache/directory/server/core/avltree/ core/src/main/java/org/apache/directory/server/core/ jdbm-store/src/ma...
Date Thu, 09 Jul 2009 11:13:02 GMT
Author: elecharny
Date: Thu Jul  9 11:13:01 2009
New Revision: 792502

URL: http://svn.apache.org/viewvc?rev=792502&view=rev
Log:
o Injected Kiran's patch to move AVL serialization inside JDBM
o Added synchronization in JDBMStore for modification operations and sync()
o The JDBM byte buffers are copied before being returned to the caller, to avoid a modification

made on a reference
o Fixed some double update of the oneLevel index (no need to add a (id,id) entry)
o When we can't find the entry, instead of a NPE, an error 32 is generated (NO_SUCH_OBJECT)
o Minor cleanup in JdbmTable
o Added some logs in JdbmTable
o Added some traces if the AVL Tree deserializer detect some bad tree


Modified:
    directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTree.java
    directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTreeMarshaller.java
    directory/apacheds/trunk/core-avl/src/test/java/org/apache/directory/server/core/avltree/AvlTreeTest.java
    directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
    directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStore.java
    directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
    directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/CacheRecordManager.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/LaunchDiagnosticUiHandler.java

Modified: directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTree.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTree.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTree.java
(original)
+++ directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTree.java
Thu Jul  9 11:13:01 2009
@@ -489,9 +489,9 @@
 
         System.out.println( getRoot() );
         
-        visit( getRoot().getRight(), getRoot() );
+        visit( null, getRoot().getRight(), getRoot() );
         
-        visit( getRoot().getLeft(), getRoot() );
+        visit( null, getRoot().getLeft(), getRoot() );
     }
     
 
@@ -930,7 +930,19 @@
     }
     
     
-    private void visit( LinkedAvlNode<K> node, LinkedAvlNode<K> parentNode )

+    /**
+     * Checks that the tree is correct. It must be balanced, and the prev/next
+     * chain must be equivalent to a depth-first descent on the tree
+     * 
+     * @return true if the tree is balanced and correct
+     */
+    public boolean checkTree()
+    {
+        return true;
+    }
+    
+    
+    private void visit( StringBuilder sb, LinkedAvlNode<K> node, LinkedAvlNode<K>
parentNode ) 
     {
         if( node == null )
         {
@@ -944,10 +956,18 @@
         
         for( int i=0; i < parentNode.getDepth(); i++ )
         {
-            System.out.print( "|  " );
+            if ( sb != null )
+            {
+                sb.append( "|  " );
+            }
+            else
+            {
+                System.out.print( "|  " );
+            }
         }
 
         String type = "";
+        
         if( node == parentNode.left )
         {
             type = "L";
@@ -957,16 +977,43 @@
             type = "R";
         }
         
-        System.out.println( "|--" + node + type );
+        if ( sb != null )
+        {
+            sb.append( "|--" ).append( node ).append( type ).append( '\n' );
+        }
+        else
+        {
+            System.out.println( "|--" + node + type );
+        }
         
         if ( node.getRight() != null )
         {
-            visit( node.getRight(), node );
+            visit( sb, node.getRight(), node );
         }
         
         if( node.getLeft() != null )
         {
-            visit( node.getLeft(), node );
+            visit( sb, node.getLeft(), node );
+        }
+    }
+    
+    public String toString()
+    {
+        if( isEmpty() )
+        {
+            return "[]";
         }
+        
+        getRoot().setDepth( 0 );
+
+        StringBuilder sb = new StringBuilder();
+        
+        sb.append( getRoot() );
+        
+        visit( sb, getRoot().getRight(), getRoot() );
+        
+        visit( sb, getRoot().getLeft(), getRoot() );
+        
+        return sb.toString();
     }
 }

Modified: directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTreeMarshaller.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTreeMarshaller.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTreeMarshaller.java
(original)
+++ directory/apacheds/trunk/core-avl/src/main/java/org/apache/directory/server/core/avltree/AvlTreeMarshaller.java
Thu Jul  9 11:13:01 2009
@@ -27,6 +27,12 @@
 import java.io.IOException;
 import java.util.Comparator;
 
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sun.reflect.Reflection;
+
 
 /**
  * Class to serialize the AvlTree node data.
@@ -37,6 +43,9 @@
 @SuppressWarnings("unchecked")
 public class AvlTreeMarshaller<E> implements Marshaller<AvlTree<E>>
 {
+    /** static logger */
+    private static final Logger LOG = LoggerFactory.getLogger( AvlTreeMarshaller.class );
+
     /** used for serialized form of an empty AvlTree */
     private static final byte[] EMPTY_TREE = new byte[1];
 
@@ -104,6 +113,18 @@
             writeTree( tree.getRoot(), out );
             out.flush();
             data = byteStream.toByteArray();
+            
+            // Try to deserialize, just to see
+            try
+            {
+                deserialize( data );
+            }
+            catch (NullPointerException npe )
+            {
+                System.out.println( "Bad serialization, tree : [" + StringTools.dumpBytes(
data ) + "]");
+                throw npe;
+            }
+
             out.close();
         }
         catch( IOException e )
@@ -164,49 +185,59 @@
      */
     public AvlTree<E> deserialize( byte[] data ) throws IOException
     {
-        if ( data == null || data.length == 0 )
-        {
-            throw new IOException( "Null or empty data array is invalid." );
-        }
+        LOG.debug( "Deserializing the tree, called by {}", Reflection.getCallerClass( 2 ).getSimpleName()
);
 
-        if ( data.length == 1 && data[0] == 0 )
-        {
-            return new AvlTree<E>( comparator );
-        }
-
-        ByteArrayInputStream bin = new ByteArrayInputStream( data );
-        DataInputStream din = new DataInputStream( bin );
-        
-        byte startByte = din.readByte();
-        
-        if( startByte != 0 )
-        {
-            throw new IOException("wrong AvlTree serialized data format");
-        }
-        
-        int size = din.readInt();
-        
-        LinkedAvlNode[] nodes = new LinkedAvlNode[ size ];
-        LinkedAvlNode<E> root = readTree( din, null, nodes );
-        
-        AvlTree<E> tree = new AvlTree<E>( comparator );
-        
-        tree.setRoot( root );
-        
-        tree.setFirst( nodes[0] );
-        
-        if( nodes.length >= 1 )
+        try
         {
-            tree.setLast( nodes[ nodes.length - 1 ] );
+            if ( data == null || data.length == 0 )
+            {
+                throw new IOException( "Null or empty data array is invalid." );
+            }
+    
+            if ( data.length == 1 && data[0] == 0 )
+            {
+                return new AvlTree<E>( comparator );
+            }
+    
+            ByteArrayInputStream bin = new ByteArrayInputStream( data );
+            DataInputStream din = new DataInputStream( bin );
+            
+            byte startByte = din.readByte();
+            
+            if( startByte != 0 )
+            {
+                throw new IOException("wrong AvlTree serialized data format");
+            }
+            
+            int size = din.readInt();
+            
+            LinkedAvlNode[] nodes = new LinkedAvlNode[ size ];
+            LinkedAvlNode<E> root = readTree( din, null, nodes );
+            
+            AvlTree<E> tree = new AvlTree<E>( comparator );
+            
+            tree.setRoot( root );
+            
+            tree.setFirst( nodes[0] );
+            
+            if( nodes.length >= 1 )
+            {
+                tree.setLast( nodes[ nodes.length - 1 ] );
+            }
+            
+            for( int i = 0; i < nodes.length - 1; i++ )
+            {
+                nodes[ i ].setNext( nodes[ i + 1] );
+                nodes[ i + 1].setPrevious( nodes[ i ] );
+            }
+    
+            return tree;
         }
-        
-        for( int i = 0; i < nodes.length - 1; i++ )
+        catch (NullPointerException npe )
         {
-            nodes[ i ].setNext( nodes[ i + 1] );
-            nodes[ i + 1].setPrevious( nodes[ i ] );
+            System.out.println( "Bad tree : [" + StringTools.dumpBytes( data ) + "]");
+            throw npe;
         }
-
-        return tree;
     }
 
     

Modified: directory/apacheds/trunk/core-avl/src/test/java/org/apache/directory/server/core/avltree/AvlTreeTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-avl/src/test/java/org/apache/directory/server/core/avltree/AvlTreeTest.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/core-avl/src/test/java/org/apache/directory/server/core/avltree/AvlTreeTest.java
(original)
+++ directory/apacheds/trunk/core-avl/src/test/java/org/apache/directory/server/core/avltree/AvlTreeTest.java
Thu Jul  9 11:13:01 2009
@@ -490,4 +490,42 @@
       }
       //3. post-order
     }
+
+
+    @Test
+    public void testRemoveEmptyTree()
+    {
+        tree.remove( null );
+        
+        assertEquals( 0, tree.getSize() );
+
+        tree.remove( 1 );
+        
+        assertEquals( 0, tree.getSize() );
+    }
+
+
+    @Test
+    public void testRemoveOneNode()
+    {
+        tree.insert( 1 );
+        assertEquals( 1, tree.getSize() );
+        
+        tree.remove( 1 );
+        assertEquals( 0, tree.getSize() );
+    }
+
+
+    @Test
+    public void testRemoveOneNodeWithRight()
+    {
+        tree.insert( 1 );
+        tree.insert( 2 );
+        assertEquals( 2, tree.getSize() );
+        assertEquals( "1,2", getInorderForm() );
+        
+        tree.remove( 1 );
+        assertEquals( 1, tree.getSize() );
+        assertEquals( Integer.valueOf( 2 ), tree.getRoot().getKey() );
+    }
 }

Modified: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
(original)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/DefaultOperationManager.java
Thu Jul  9 11:13:01 2009
@@ -265,8 +265,8 @@
             pop();
         }
 
-        LOG.debug( "<< AddOperation successfull" );
-        LOG_CHANGES.debug( "<< AddOperation successfull" );
+        LOG.debug( "<< AddOperation successful" );
+        LOG_CHANGES.debug( "<< AddOperation successful" );
     }
 
 

Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStore.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStore.java
(original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmStore.java
Thu Jul  9 11:13:01 2009
@@ -1160,9 +1160,12 @@
 
     /**
      * {@inheritDoc}
+     * TODO : We should be able to revert all the changes made to index 
+     * if something went wrong. Also the index should auto-repair : if
+     * an entry does not exist in the Master table, then the index must be updated to reflect
this.
      */
     @SuppressWarnings("unchecked")
-    public void add( ServerEntry entry ) throws Exception
+    public synchronized void add( ServerEntry entry ) throws Exception
     {
         if ( entry instanceof ClonedServerEntry )
         {
@@ -1210,7 +1213,6 @@
 
         // Start adding the system userIndices
         // Why bother doing a lookup if this is not an alias.
-
         // First, the ObjectClass index
         for ( Value<?> value : objectClass )
         {
@@ -1306,7 +1308,7 @@
     /**
      * {@inheritDoc}
      */
-    public void delete( Long id ) throws Exception
+    public synchronized void delete( Long id ) throws Exception
     {
         ServerEntry entry = lookup( id );
         Long parentId = getParentId( id );

Modified: directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
(original)
+++ directory/apacheds/trunk/jdbm-store/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
Thu Jul  9 11:13:01 2009
@@ -35,7 +35,10 @@
 import org.apache.directory.shared.ldap.cursor.Cursor;
 import org.apache.directory.shared.ldap.cursor.EmptyCursor;
 import org.apache.directory.shared.ldap.cursor.SingletonCursor;
+import org.apache.directory.shared.ldap.util.StringTools;
 import org.apache.directory.shared.ldap.util.SynchronizedLRUMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.util.Comparator;
@@ -50,30 +53,36 @@
  */
 public class JdbmTable<K,V> implements Table<K,V>
 {
-    private static final byte[] EMPTY_BYTES = new byte[0];
+    /** A logger for this class */
+    private static final Logger LOG = LoggerFactory.getLogger( JdbmTable.class.getSimpleName()
);
 
     /** the key to store and retreive the count information */
     private static final String SZSUFFIX = "_btree_sz";
 
     /** the name of this table */
     private final String name;
+
     /** the JDBM record manager for the file this table is managed in */
     private final RecordManager recMan;
+    
     /** whether or not this table allows for duplicates */
     private final boolean allowsDuplicates;
+    
     /** a key comparator for the keys in this Table */
     private final Comparator<K> keyComparator;
+    
     /** a value comparator for the values in this Table */
     private final Comparator<V> valueComparator;
 
     /** the current count of entries in this Table */
     private int count;
+    
     /** the wrappedCursor JDBM btree used in this Table */
     private BTree bt;
 
-
     /** the limit at which we start using btree redirection for duplicates */
     private int numDupLimit = JdbmIndex.DEFAULT_DUPLICATE_LIMIT;
+
     /** a cache of duplicate BTrees */
     private final Map<Long, BTree> duplicateBtrees;
 
@@ -388,6 +397,7 @@
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
         tree.browse().getNext( tuple );
         //noinspection unchecked
+        
         return ( V ) tuple.getKey();
     }
 
@@ -395,7 +405,6 @@
     /**
      * @see Table#hasGreaterOrEqual(Object,Object)
      */
-    @SuppressWarnings("unchecked")
     public boolean hasGreaterOrEqual( K key, V val ) throws IOException
     {
         if ( key == null )
@@ -410,6 +419,7 @@
         }
 
         DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
+        
         if ( values.isAvlTree() )
         {
             AvlTree<V> set = values.getAvlTree();
@@ -419,6 +429,7 @@
 
         // last option is to try a btree with BTreeRedirects
         BTree tree = getBTree( values.getBTreeRedirect() );
+        
         return tree.size() != 0 && btreeHas( tree, val, true );
     }
 
@@ -426,7 +437,6 @@
     /**
      * @see Table#hasLessOrEqual(Object,Object)
      */
-    @SuppressWarnings("unchecked")
     public boolean hasLessOrEqual( K key, V val ) throws IOException
     {
         if ( key == null )
@@ -441,6 +451,7 @@
         }
 
         DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
+        
         if ( values.isAvlTree() )
         {
             AvlTree<V> set = values.getAvlTree();
@@ -450,6 +461,7 @@
 
         // last option is to try a btree with BTreeRedirects
         BTree tree = getBTree( values.getBTreeRedirect() );
+        
         return tree.size() != 0 && btreeHas( tree, val, false );
     }
 
@@ -547,6 +559,7 @@
         }
         
         DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
+        
         if ( values.isAvlTree() )
         {
             return values.getAvlTree().find( value ) != null;
@@ -570,58 +583,92 @@
      * java.lang.Object)
      */
     @SuppressWarnings("unchecked")
-    public void put( K key, V value ) throws Exception
+    public synchronized void put( K key, V value ) throws Exception
     {
-        if ( value == null || key == null )
+        try
         {
-            throw new IllegalArgumentException( "null for key or value is not valid" );
-        }
-        
-        V replaced;
-
-        if ( ! allowsDuplicates )
-        {
-            replaced = ( V ) bt.insert( key, value, true );
-
-            if ( null == replaced )
+            if ( LOG.isDebugEnabled() )
             {
-                count++;
+                LOG.debug( "---> Add {} = {}", name, key );
             }
 
-            return;
-        }
-        
-        DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
-        if ( values.isAvlTree() )
-        {
-            AvlTree<V> set = values.getAvlTree();
-            replaced = set.insert( value );
+            if ( ( value == null ) || ( key == null ) )
+            {
+                throw new IllegalArgumentException( "null for key or value is not valid"
);
+            }
             
-            if ( replaced != null )// if the value already present returns the same value
+            V replaced;
+    
+            if ( ! allowsDuplicates )
             {
+                replaced = ( V ) bt.insert( key, value, true );
+    
+                if ( null == replaced )
+                {
+                    count++;
+                }
+    
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "<--- Add ONE {} = {}", name, key );
+                }
+                
+                return;
+            }
+            
+            DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
+            
+            if ( values.isAvlTree() )
+            {
+                AvlTree<V> set = values.getAvlTree();
+                replaced = set.insert( value );
+                
+                if ( replaced != null )// if the value already present returns the same value
+                {
+                    return;
+                }
+                if ( set.getSize() > numDupLimit )
+                {
+                    BTree tree = convertToBTree( set );
+                    BTreeRedirect redirect = new BTreeRedirect( tree.getRecid() );
+                    bt.insert( key, BTreeRedirectMarshaller.INSTANCE.serialize( redirect
), true );
+                    
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "<--- Add new BTREE {} = {}", name, key );
+                    }
+                }
+                else
+                {
+                    bt.insert( key, marshaller.serialize( set ), true );
+                    
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "<--- Add AVL {} = {}", name, key );
+                    }
+                }
+    
+                count++;
                 return;
             }
-            if ( set.getSize() > numDupLimit )
+            
+            BTree tree = getBTree( values.getBTreeRedirect() );
+            replaced = ( V ) tree.insert( value, StringTools.EMPTY_BYTES, true );
+            
+            if ( replaced == null )
             {
-                BTree tree = convertToBTree( set );
-                BTreeRedirect redirect = new BTreeRedirect( tree.getRecid() );
-                bt.insert( key, BTreeRedirectMarshaller.INSTANCE.serialize( redirect ), true
);
+                count++;
             }
-            else
+            
+            if ( LOG.isDebugEnabled() )
             {
-                bt.insert( key, marshaller.serialize( set ), true );
+                LOG.debug( "<--- Add BTREE {} = {}", name, key );
             }
-
-            count++;
-            return;
         }
-        
-        BTree tree = getBTree( values.getBTreeRedirect() );
-        replaced = ( V ) tree.insert( value, EMPTY_BYTES, true );
-        
-        if ( replaced == null )
+        catch ( Exception e )
         {
-            count++;
+            LOG.error( "Error while adding " + key + " on table " + name, e );
+            throw e;
         }
     }
     
@@ -631,70 +678,107 @@
      * java.lang.Object)
      */
     @SuppressWarnings("unchecked")
-    public void remove( K key, V value ) throws IOException
+    public synchronized void remove( K key, V value ) throws IOException
     {
-        if ( key == null )
+        try
         {
-            return;
-        }
-
-        if ( ! allowsDuplicates )
-        {
-            V oldValue = ( V ) bt.find( key );
-        
-            // Remove the value only if it is the same as value.
-            if ( ( oldValue != null ) && oldValue.equals( value ) )
+            if ( LOG.isDebugEnabled() )
+            {
+                LOG.debug( "---> Remove " + name + " = " + key + ", " + value );
+            }
+            
+            if ( key == null )
             {
-                bt.remove( key );
-                count--;
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "<--- Remove NULL key " + name );
+                }
                 return;
             }
-
-            return;
-        }
-
-        DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
-        
-        if ( values.isAvlTree() )
-        {
-            AvlTree<V> set = values.getAvlTree();
-
-            // If removal succeeds then remove if set is empty else replace it
-            if ( set.remove( value ) != null )
+    
+            if ( ! allowsDuplicates )
             {
-                if ( set.isEmpty() )
+                V oldValue = ( V ) bt.find( key );
+            
+                // Remove the value only if it is the same as value.
+                if ( ( oldValue != null ) && oldValue.equals( value ) )
                 {
                     bt.remove( key );
+                    count--;
+                    
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "<--- Remove ONE " + name + " = " + key + ", " + value
);
+                    }
+                    
+                    return;
                 }
-                else
+    
+                return;
+            }
+    
+            DupsContainer<V> values = getDupsContainer( ( byte[] ) bt.find( key ) );
+            
+            if ( values.isAvlTree() )
+            {
+                AvlTree<V> set = values.getAvlTree();
+    
+                // If removal succeeds then remove if set is empty else replace it
+                if ( set.remove( value ) != null )
                 {
-                    bt.insert( key, marshaller.serialize( set ), true );
+                    if ( set.isEmpty() )
+                    {
+                        bt.remove( key );
+                    }
+                    else
+                    {
+                        bt.insert( key, marshaller.serialize( set ), true );
+                    }
+                    count--;
+
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "<--- Remove AVL " + name + " = " + key + ", " + value
);
+                    }
+                    
+                    return;
                 }
-                count--;
+    
                 return;
             }
-
-            return;
-        }
-
-        // if the number of duplicates falls below the numDupLimit value
-        BTree tree = getBTree( values.getBTreeRedirect() );
-        
-        if ( removeDupFromBTree( tree, value ) )
-        {
-            /*
-             * If we drop below the duplicate limit then we revert from using
-             * a Jdbm BTree to using an in memory AvlTree.
-             */
-            if ( tree.size() <= numDupLimit )
+    
+            // if the number of duplicates falls below the numDupLimit value
+            BTree tree = getBTree( values.getBTreeRedirect() );
+            
+            if ( tree.find( value ) != null )
             {
-                AvlTree<V> avlTree = convertToAvlTree( tree );
-                bt.insert( key, marshaller.serialize( avlTree ), true );
-                recMan.delete( tree.getRecid() );
+                if ( tree.remove( value ) != null )
+                {
+                    /*
+                     * If we drop below the duplicate limit then we revert from using
+                     * a Jdbm BTree to using an in memory AvlTree.
+                     */
+                    if ( tree.size() <= numDupLimit )
+                    {
+                        AvlTree<V> avlTree = convertToAvlTree( tree );
+                        bt.insert( key, marshaller.serialize( avlTree ), true );
+                        recMan.delete( tree.getRecid() );
+                    }
+                    
+                    count--;
+                    
+                    if ( LOG.isDebugEnabled() )
+                    {
+                        LOG.debug( "<--- Remove BTREE " + name + " = " + key + ", " +
value );
+                    }
+                    
+                    return;
+                }
             }
-            
-            count--;
-            return;
+        }
+        catch ( Exception e )
+        {
+            LOG.error( "Error while adding " + key + ", " + value + " on table " + name,
e );
         }
     }
 
@@ -702,39 +786,79 @@
     /**
      * @see Table#remove(Object)
      */
-    public void remove( K key ) throws IOException
+    public synchronized void remove( K key ) throws IOException
     {
-        if ( key == null )
-        {
-            return;
-        }
-
-        Object returned = bt.remove( key );
-
-        if ( null == returned )
+        try
         {
-            return;
-        }
-
-        if ( ! allowsDuplicates )
-        {
-            this.count--;
-            return;
-        }
-
-        byte[] serialized = ( byte[] ) returned;
-
-        if ( BTreeRedirectMarshaller.isRedirect( serialized ) )
-        {
-            BTree tree = getBTree( BTreeRedirectMarshaller.INSTANCE.deserialize( serialized
) );
-            this.count -= tree.size();
-            return;
+            if ( LOG.isDebugEnabled() )
+            {
+                LOG.debug( "---> Remove {} = {}", name, key );
+            }
+            
+            if ( key == null )
+            {
+                return;
+            }
+    
+            Object returned = bt.remove( key );
+    
+            if ( null == returned )
+            {
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "<--- Remove AVL {} = {} (not found)", name, key );
+                }
+                
+                return;
+            }
+    
+            if ( ! allowsDuplicates )
+            {
+                this.count--;
+             
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "<--- Remove ONE {} = {}", name, key );
+                }
+                
+                return;
+            }
+    
+            byte[] serialized = ( byte[] ) returned;
+    
+            if ( BTreeRedirectMarshaller.isRedirect( serialized ) )
+            {
+                BTree tree = getBTree( BTreeRedirectMarshaller.INSTANCE.deserialize( serialized
) );
+                this.count -= tree.size();
+                
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "<--- Remove BTree {} = {}", name, key );
+                }
+                
+                return;
+            }
+            else
+            {
+                AvlTree<V> set = marshaller.deserialize( serialized );
+                this.count -= set.getSize();
+    
+                if ( LOG.isDebugEnabled() )
+                {
+                    LOG.debug( "<--- Remove AVL {} = {}", name, key );
+                }
+                
+                return;
+            }
         }
-        else
+        catch ( Exception e )
         {
-            AvlTree<V> set = marshaller.deserialize( serialized );
-            this.count -= set.getSize();
-            return;
+            LOG.error(  "Exception while removing " + key + " from index " + name, e );
+            
+            if ( e instanceof IOException )
+            {
+                throw (IOException)e;
+            }
         }
     }
 
@@ -833,7 +957,7 @@
      *
      * @throws IOException if errors are encountered on the flush
      */
-    public void sync() throws IOException
+    public synchronized void sync() throws IOException
     {
         long recId = recMan.getNamedObject( name + SZSUFFIX );
         recMan.update( recId, count );
@@ -849,8 +973,6 @@
     // ------------------------------------------------------------------------
     // Private/Package Utility Methods 
     // ------------------------------------------------------------------------
-
-
     DupsContainer<V> getDupsContainer( byte[] serialized ) throws IOException
     {
         if ( serialized == null )
@@ -928,23 +1050,13 @@
     }
 
 
-    private boolean removeDupFromBTree( BTree tree, V value ) throws IOException
-    {
-        Object removed = null;
-        if ( tree.find( value ) != null )
-        {
-            removed = tree.remove( value );
-        }
-        return null != removed;
-    }
-
-
     @SuppressWarnings("unchecked")
     private AvlTree<V> convertToAvlTree( BTree bTree ) throws IOException
     {
         AvlTree<V> avlTree = new AvlTree<V>( valueComparator );
         TupleBrowser browser = bTree.browse();
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
+        
         while ( browser.getNext( tuple ) )
         {
             avlTree.insert( ( V ) tuple.getKey() );
@@ -969,10 +1081,12 @@
 
         Cursor<V> keys = new AvlTreeCursor<V>( avlTree );
         keys.beforeFirst();
+        
         while ( keys.next() )
         {
-            bTree.insert( keys.get(), EMPTY_BYTES, true );
+            bTree.insert( keys.get(), StringTools.EMPTY_BYTES, true );
         }
+        
         return bTree;
     }
 }

Modified: directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/CacheRecordManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/CacheRecordManager.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/CacheRecordManager.java (original)
+++ directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/CacheRecordManager.java Thu Jul
 9 11:13:01 2009
@@ -267,6 +267,14 @@
                 throw new WrappedRuntimeException( except );
             }
         }
+        
+        if ( entry._obj instanceof byte[] )
+        {
+            byte[] copy = new byte[((byte[])entry._obj).length];
+            System.arraycopy( entry._obj, 0, copy, 0, ((byte[])entry._obj).length );
+            return copy;
+        }
+        
         return entry._obj;
     }
 

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/LaunchDiagnosticUiHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/LaunchDiagnosticUiHandler.java?rev=792502&r1=792501&r2=792502&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/LaunchDiagnosticUiHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/extended/LaunchDiagnosticUiHandler.java
Thu Jul  9 11:13:01 2009
@@ -104,15 +104,24 @@
             
             if ( partition instanceof BTreePartition )
             {
-                BTreePartition btPartition = ( BTreePartition ) partition;
-                PartitionFrame frame = new PartitionFrame( btPartition, service.getRegistries()
);
-                Point pos = getCenteredPosition( frame );
-                pos.y = launchedWindowCount * 20 + pos.y;
-                double multiplier = getAspectRatio() * 20.0;
-                pos.x = ( int ) ( launchedWindowCount * multiplier ) + pos.x;
-                frame.setLocation( pos );
-                frame.setVisible( true );
-                launchedWindowCount++;
+                try
+                {
+                    BTreePartition btPartition = ( BTreePartition ) partition;
+                    // TODO : If a partition does not have an initial entry associated, we
wil:
+                    // get a NPE : this has to be fixed.
+                    PartitionFrame frame = new PartitionFrame( btPartition, service.getRegistries()
);
+                    Point pos = getCenteredPosition( frame );
+                    pos.y = launchedWindowCount * 20 + pos.y;
+                    double multiplier = getAspectRatio() * 20.0;
+                    pos.x = ( int ) ( launchedWindowCount * multiplier ) + pos.x;
+                    frame.setLocation( pos );
+                    frame.setVisible( true );
+                    launchedWindowCount++;
+                }
+                catch ( Exception e )
+                {
+                    // Continue
+                }
             }
         }
 



Mime
View raw message