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 2011/09/01 19:34:05 UTC

svn commit: r1164182 [2/2] - in /directory/apacheds/trunk: core-annotations/ core-api/ core-avl/ core-constants/ core-integ/ core-integ/src/test/java/org/apache/directory/server/core/collective/ core-jndi/ core/ core/src/main/java/org/apache/directory/...

Modified: directory/apacheds/trunk/jdbm/src/main/java/jdbm/btree/BTree.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm/src/main/java/jdbm/btree/BTree.java?rev=1164182&r1=1164181&r2=1164182&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm/src/main/java/jdbm/btree/BTree.java (original)
+++ directory/apacheds/trunk/jdbm/src/main/java/jdbm/btree/BTree.java Thu Sep  1 17:34:03 2011
@@ -47,18 +47,27 @@
 package jdbm.btree;
 
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Comparator;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
+import jdbm.ActionRecordManager;
 import jdbm.RecordManager;
+import jdbm.helper.ActionContext;
 import jdbm.helper.Serializer;
 import jdbm.helper.Tuple;
 import jdbm.helper.TupleBrowser;
+import jdbm.helper.WrappedRuntimeException;
 
 import org.apache.directory.server.i18n.I18n;
 
@@ -77,7 +86,6 @@ import org.apache.directory.server.i18n.
  * user is responsible to supply a serializable <code>Comparator</code> object
  * to be used for the ordering of entries, which are also called <code>Tuple</code>.
  * The B+Tree allows traversing the keys in forward and reverse order using a
- * TupleBrowser obtained from the browse() methods.
  * <p>
  * This implementation does not directly support duplicate keys, but it is
  * possible to handle duplicates by inlining or referencing an object collection
@@ -106,7 +114,7 @@ public class BTree<K, V> implements Exte
     private transient long recordId;
 
     /** Comparator used to index entries. */
-    private Comparator<K> comparator;
+    Comparator<K> comparator;
 
     /** Serializer used to serialize index keys (optional) */
     protected Serializer keySerializer;
@@ -118,7 +126,7 @@ public class BTree<K, V> implements Exte
      * Height of the B+Tree.  This is the number of BPages you have to traverse
      * to get to a leaf BPage, starting from the root.
      */
-    private int bTreeHeight;
+    int bTreeHeight;
 
     /** Record id of the root BPage */
     private long rootId;
@@ -131,7 +139,16 @@ public class BTree<K, V> implements Exte
 
     /** Serializer used for BPages of this tree */
     private transient BPage<K, V> bpageSerializer;
-
+    
+    /** TRUE if underlying record manager is snapshot capable */
+    private transient boolean isActionCapable;
+    
+    
+    /** Big lock snychronizing all actions */
+    private transient Lock bigLock = new ReentrantLock(); 
+    
+    /** Meta root used to access versions of Btree root */
+    private transient MetaRoot metaRoot = new MetaRoot();
 
     /**
      * No-argument constructor used by serialization.
@@ -220,8 +237,27 @@ public class BTree<K, V> implements Exte
         this.bpageSerializer = new BPage<K, V>();
         this.bpageSerializer.btree = this;
         this.nbEntries = new AtomicInteger( 0 );
+        
+        this.isActionCapable = recordManager instanceof ActionRecordManager; 
 
-        this.recordId = recordManager.insert( this );
+        boolean abortedAction = false;
+        ActionContext context = this.beginAction( false, "createInstance" );
+        try
+        {
+            this.recordId = recordManager.insert( this );
+            updateMetaRoot( this.rootId, this.bTreeHeight );
+        }
+        catch ( IOException e )
+        {
+            abortedAction = true;
+            this.abortAction( context );
+            throw e;
+        }
+        finally
+        {
+            if ( !abortedAction )
+                this.endAction( context );
+        }
     }
     
     
@@ -246,11 +282,33 @@ public class BTree<K, V> implements Exte
      */
     public BTree<K, V> load( RecordManager recman, long recid ) throws IOException
     {
-        BTree<K, V> btree = (BTree<K, V>) recman.fetch( recid );
-        btree.recordId = recid;
-        btree.recordManager = recman;
-        btree.bpageSerializer = new BPage<K, V>();
-        btree.bpageSerializer.btree = btree;
+        BTree<K, V> btree = null;
+        boolean abortedAction = false;
+        ActionContext context = this.beginAction( false, "load" );
+        
+        try
+        {
+            btree = (BTree<K, V>) recman.fetch( recid );
+            btree.recordId = recid;
+            btree.recordManager = recman;
+            btree.bpageSerializer = new BPage<K, V>();
+            btree.bpageSerializer.btree = btree;
+            btree.updateMetaRoot( btree.rootId, btree.bTreeHeight );
+
+        }
+        catch ( IOException e )
+        {
+            abortedAction = true;
+            this.abortAction( context );
+            throw e;
+        }
+        finally
+        {
+            if ( !abortedAction )
+            {
+                this.endAction( context );
+            }
+        }
         
         return btree;
     }
@@ -268,7 +326,7 @@ public class BTree<K, V> implements Exte
      * @param replace Set to true to replace an existing key-value pair.
      * @return Existing value, if any.
      */
-    public synchronized Object insert( K key, V value, boolean replace ) throws IOException
+    public Object insert( K key, V value, boolean replace ) throws IOException
     {
         if ( key == null )
         {
@@ -280,56 +338,95 @@ public class BTree<K, V> implements Exte
             throw new IllegalArgumentException( I18n.err( I18n.ERR_524 ) );
         }
 
-        BPage<K, V> rootPage = getRoot();
+        
+        boolean abortedAction = false;
+        ActionContext context  = this.beginAction( false, "insert" );
+        
 
-        if ( rootPage == null )
+        if ( !isActionCapable )
         {
-            // BTree is currently empty, create a new root BPage
-            if ( DEBUG )
-            {
-                System.out.println( "BTree.insert() new root BPage" );
-            }
-            
-            rootPage = new BPage<K, V>( this, key, value );
-            rootId = rootPage.getRecordId();
-            bTreeHeight = 1;
-            nbEntries.set( 1 );
-            recordManager.update( recordId, this );
-            
-            return null;
+            bigLock.lock();
         }
-        else
+        
+        try
         {
-            BPage.InsertResult<K, V> insert = rootPage.insert( bTreeHeight, key, value, replace );
-            boolean dirty = false;
-            
-            if ( insert.overflow != null )
+            BPage<K, V> rootPage = getRoot();
+    
+            if ( rootPage == null )
             {
-                // current root page overflowed, we replace with a new root page
+                // BTree is currently empty, create a new root BPage
                 if ( DEBUG )
                 {
-                    System.out.println( "BTree.insert() replace root BPage due to overflow" );
+                    System.out.println( "BTree.insert() new root BPage" );
                 }
                 
-                rootPage = new BPage<K, V>( this, rootPage, insert.overflow );
+                rootPage = new BPage<K, V>( this, key, value );
                 rootId = rootPage.getRecordId();
-                bTreeHeight += 1;
-                dirty = true;
+                bTreeHeight = 1;
+                nbEntries.set( 1 );
+                recordManager.update( recordId, this );
+                updateMetaRoot( this.rootId, this.bTreeHeight );
+                
+                return null;
             }
-            
-            if ( insert.existing == null )
+            else
             {
-                nbEntries.getAndIncrement();
-                dirty = true;
+                BPage.InsertResult<K, V> insert = rootPage.insert( bTreeHeight, key, value, replace );
+                
+                if ( insert.pageNewCopy != null )
+                {
+                    rootPage = insert.pageNewCopy;
+                }
+                
+                boolean dirty = false;
+                
+                if ( insert.overflow != null )
+                {
+                    // current root page overflowed, we replace with a new root page
+                    if ( DEBUG )
+                    {
+                        System.out.println( "BTree.insert() replace root BPage due to overflow" );
+                    }
+                    
+                    rootPage = new BPage<K, V>( this, rootPage, insert.overflow );
+                    rootId = rootPage.getRecordId();
+                    bTreeHeight += 1;
+                    dirty = true;
+                    updateMetaRoot( this.rootId, this.bTreeHeight );
+                }
+                
+                if ( insert.existing == null )
+                {
+                    nbEntries.getAndIncrement();
+                    dirty = true;
+                }
+                
+                if ( dirty )
+                {
+                    recordManager.update( recordId, this );
+                }
+                
+                // insert might have returned an existing value
+                return insert.existing;
             }
-            
-            if ( dirty )
+        }
+        catch ( IOException e )
+        {
+            abortedAction = true;
+            this.abortAction( context );
+            throw e;
+        }
+        finally
+        {
+            if ( !abortedAction )
             {
-                recordManager.update( recordId, this );
+                this.endAction( context );
             }
             
-            // insert might have returned an existing value
-            return insert.existing;
+            if ( !isActionCapable )
+            {
+                bigLock.unlock();
+            }
         }
     }
 
@@ -341,52 +438,88 @@ public class BTree<K, V> implements Exte
      * @return Value associated with the key, or null if no entry with given
      *         key existed in the BTree.
      */
-    public synchronized V remove( K key ) throws IOException
+    public V remove( K key ) throws IOException
     {
         if ( key == null )
         {
             throw new IllegalArgumentException( I18n.err( I18n.ERR_523 ) );
         }
-
-        BPage<K, V> rootPage = getRoot();
+       
         
-        if ( rootPage == null )
+        boolean abortedAction = false;
+        ActionContext context = this.beginAction( false, "remove" );
+
+        if ( !isActionCapable )
         {
-            return null;
+            bigLock.lock();
         }
         
-        boolean dirty = false;
-        BPage.RemoveResult<V> remove = rootPage.remove( bTreeHeight, key );
-        
-        if ( remove.underflow && rootPage.isEmpty() )
+        try
         {
-            bTreeHeight -= 1;
-            dirty = true;
-
-            recordManager.delete( rootId );
+            BPage<K, V> rootPage = getRoot();
             
-            if ( bTreeHeight == 0 )
+            if ( rootPage == null )
             {
-                rootId = 0;
+                return null;
             }
-            else
+            
+            boolean dirty = false;
+            BPage.RemoveResult<K, V> remove = rootPage.remove( bTreeHeight, key );
+            
+            if ( remove.pageNewCopy != null )
             {
-                rootId = rootPage.childBPage( pageSize - 1 ).getRecordId();
+                rootPage = remove.pageNewCopy;
             }
+            
+            if ( remove.underflow && rootPage.isEmpty() )
+            {
+                bTreeHeight -= 1;
+                dirty = true;
+    
+                recordManager.delete( rootId );
+                
+                if ( bTreeHeight == 0 )
+                {
+                    rootId = 0;
+                }
+                else
+                {
+                    rootId = rootPage.childBPage( pageSize - 1 ).getRecordId();
+                }
+                updateMetaRoot( this.rootId, this.bTreeHeight );
+            }
+            
+            if ( remove.value != null )
+            {
+                nbEntries.getAndDecrement();
+                dirty = true;
+            }
+            
+            if ( dirty )
+            {
+                recordManager.update( recordId, this );
+            }
+            
+            return remove.value;
         }
-        
-        if ( remove.value != null )
+        catch ( IOException e )
         {
-            nbEntries.getAndDecrement();
-            dirty = true;
+            abortedAction = true;
+            this.abortAction( context );
+            throw e;
         }
-        
-        if ( dirty )
+        finally
         {
-            recordManager.update( recordId, this );
+            if ( !abortedAction )
+            {
+                this.endAction( context );
+            }
+            
+            if ( !isActionCapable )
+            {
+                bigLock.unlock();
+            }
         }
-        
-        return remove.value;
     }
 
 
@@ -396,40 +529,58 @@ public class BTree<K, V> implements Exte
      * @param key Lookup key.
      * @return Value associated with the key, or null if not found.
      */
-    public synchronized V find( K key ) throws IOException
+    public V find( K key ) throws IOException
     {
+        TupleBrowser<K, V> browser = null;
+        Tuple<K, V> tuple = null;
+        
         if ( key == null )
         {
             throw new IllegalArgumentException( I18n.err( I18n.ERR_523 ) );
         }
         
-        BPage<K, V> rootPage = getRoot();
-        
-        if ( rootPage == null )
+        if ( !isActionCapable )
         {
-            return null;
+            bigLock.lock();
         }
-
-        Tuple<K, V> tuple = new Tuple<K, V>( null, null );
-        TupleBrowser<K, V> browser = rootPage.find( bTreeHeight, key );
-
-        if ( browser.getNext( tuple ) )
-        {
-            // find returns the matching key or the next ordered key, so we must
-            // check if we have an exact match
-            if ( comparator.compare( key, tuple.getKey() ) != 0 )
+        
+        try
+        {      
+            tuple = new Tuple<K, V>( null, null );
+     
+            browser = browse( key );
+   
+            if ( browser.getNext( tuple ) )
             {
-                return null;
+                // find returns the matching key or the next ordered key, so we must
+                // check if we have an exact match
+                if ( comparator.compare( key, tuple.getKey() ) != 0 )
+                {
+                    return null;
+                }
+                else
+                {
+                   return this.copyValue( tuple.getValue() );
+                }
             }
             else
             {
-                return tuple.getValue();
+                return null;
             }
         }
-        else
+        finally
         {
-            return null;
+            if ( browser != null )
+            {
+                browser.close();
+            }
+
+            if ( !isActionCapable )
+            {
+                bigLock.unlock();
+            }
         }
+        
     }
 
 
@@ -441,10 +592,10 @@ public class BTree<K, V> implements Exte
      * @return Value associated with the key, or a greater entry, or null if no
      *         greater entry was found.
      */
-    public synchronized Tuple<K, V> findGreaterOrEqual( K key ) throws IOException
+    public Tuple<K, V> findGreaterOrEqual( K key ) throws IOException
     {
         Tuple<K, V> tuple;
-        TupleBrowser<K, V> browser;
+        TupleBrowser<K, V> browser = null;
 
         if ( key == null )
         {
@@ -453,16 +604,38 @@ public class BTree<K, V> implements Exte
             return null;
         }
 
+        if ( !isActionCapable )
+        { 
+            bigLock.lock();
+        }
+        
         tuple = new Tuple<K, V>( null, null );
-        browser = browse( key );
         
-        if ( browser.getNext( tuple ) )
+        try
         {
-            return tuple;
+            browser = browse( key );
+            
+            if ( browser.getNext( tuple ) )
+            {
+                tuple.setValue( this.copyValue( tuple.getValue() ) );
+                return tuple;
+            }
+            else
+            {
+                return null;
+            }
         }
-        else
+        finally
         {
-            return null;
+            if ( browser != null )
+            {
+                browser.close();
+            }
+            
+            if ( !isActionCapable )
+            {
+                bigLock.unlock();
+            }
         }
     }
 
@@ -476,17 +649,31 @@ public class BTree<K, V> implements Exte
      *
      * @return Browser positionned at the beginning of the BTree.
      */
-    public synchronized TupleBrowser<K, V> browse() throws IOException
+    public TupleBrowser<K, V> browse() throws IOException
     {
-        BPage<K, V> rootPage = getRoot();
+        TupleBrowser<K, V> browser = null;
+        ActionContext context = this.beginAction( true, "browse" );
         
-        if ( rootPage == null )
+        try
         {
-            return new EmptyBrowser(){};
+            MetaRoot meta = this.getMetaRoot();
+            BPage<K, V> rootPage = this.getRoot( meta );
+            
+            if ( rootPage == null )
+            {
+                this.endAction( context );
+                return new EmptyBrowser(){};
+            }
+            
+            browser = rootPage.findFirst( context );
+        }
+        catch( IOException e )
+        {
+            this.abortAction( context );
+            throw e;
         }
         
-        TupleBrowser<K, V> browser = rootPage.findFirst();
-        
+        this.unsetAsCurrentAction( context );
         return browser;
     }
 
@@ -503,19 +690,34 @@ public class BTree<K, V> implements Exte
      *            (Null is considered to be an "infinite" key)
      * @return Browser positioned just before the given key.
      */
-    public synchronized TupleBrowser<K, V> browse( K key ) throws IOException
+    public TupleBrowser<K, V> browse( K key ) throws IOException
     {
-        BPage<K, V> rootPage = getRoot();
+        TupleBrowser<K, V> browser = null;
+        ActionContext context = this.beginAction( true, "browse key" );
         
-        if ( rootPage == null )
+        try
         {
-            return new EmptyBrowser(){};
+            MetaRoot meta = this.getMetaRoot();
+            BPage<K, V> rootPage = this.getRoot( meta );
+            
+            if ( rootPage == null )
+            {
+                this.endAction( context );
+                return new EmptyBrowser(){};
+            }
+          
+            browser  = rootPage.find( meta.treeHeight, key, context );
+        }
+        catch( IOException e )
+        {
+            this.abortAction( context );
+            throw e;
         }
         
-        TupleBrowser<K, V> browser = rootPage.find( bTreeHeight, key );
-        
+        this.unsetAsCurrentAction( context );
         return browser;
     }
+    
 
 
     /**
@@ -537,23 +739,65 @@ public class BTree<K, V> implements Exte
 
 
     /**
-     * Return the root BPage<Object, Object>, or null if it doesn't exist.
+     * @return the root BPage<Object, Object>, or null if it doesn't exist.
+     */
+    BPage<K, V> getRoot( ) throws IOException
+    {        
+        assert( this.rootId == metaRoot.rootID) : "Stale root id " + this.rootId + " "+ metaRoot.rootID;
+        
+        if ( this.rootId == 0 )
+        {
+            return null;
+        }
+        
+        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( this.rootId, bpageSerializer );
+        root.setRecordId( this.rootId );
+        root.btree = this;
+        
+        return root;
+    }
+    
+    
+    /**
+     * @param meta The root to search for
+     * 
+     * @return the root BPage<Object, Object>, or null if it doesn't exist.
      */
-    private BPage<K, V> getRoot() throws IOException
+    BPage<K, V> getRoot( MetaRoot meta ) throws IOException
     {
-        if ( rootId == 0 )
+        if ( meta.rootID == 0 )
         {
             return null;
         }
         
-        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( rootId, bpageSerializer );
-        root.setRecordId( rootId );
+        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( meta.rootID, bpageSerializer );
+        root.setRecordId( meta.rootID );
         root.btree = this;
         
         return root;
     }
-
-
+    
+    
+    /**
+     * 
+     * Returns the meta root that can be used to fetch the root page
+     *
+     * @return meta root The meta root to search for
+     * @throws IOException If we had an exception during the fetch operation
+     */
+    MetaRoot getMetaRoot() throws IOException
+    {
+        if ( isActionCapable )
+        { 
+            return ( MetaRoot )recordManager.fetch( -this.recordId );
+        }
+        else
+        {
+            return metaRoot;
+        }
+    }
+    
+    
     /**
      * Implement Externalizable interface.
      */
@@ -616,6 +860,151 @@ public class BTree<K, V> implements Exte
     }
     
     
+    void setAsCurrentAction( ActionContext context )
+    {
+        if ( context != null )
+        {
+            assert( isActionCapable == true );
+            ( ( ActionRecordManager )recordManager ).setCurrentActionContext( context );
+        }
+    }
+
+    
+    void unsetAsCurrentAction( ActionContext context )
+    {
+        if ( context != null )
+        {
+            assert( isActionCapable == true );
+            ( ( ActionRecordManager )recordManager ).unsetCurrentActionContext( context );
+        }
+    }
+
+    
+    ActionContext beginAction( boolean readOnly, String whoStarted )
+    {
+        ActionContext context = null;
+        
+        if ( isActionCapable )
+        {
+            context = ( ( ActionRecordManager )recordManager ).beginAction( readOnly, whoStarted );
+        }
+        
+        return context;
+    }
+    
+    
+    void endAction( ActionContext context )
+    {
+        if ( context != null )
+        {
+            assert( isActionCapable );
+            ( ( ActionRecordManager )recordManager ).endAction( context );
+        }
+    }
+    
+    
+    void abortAction( ActionContext context )
+    {
+        if ( context != null )
+        {
+            assert( isActionCapable );
+            ( ( ActionRecordManager )recordManager ).abortAction( context );
+        }
+
+    }
+    
+    
+    BPage<K,V> copyOnWrite( BPage<K,V> page) throws IOException
+    {
+       return page.copyOnWrite();
+
+    }
+    
+    
+    private MetaRoot copyOnWrite( MetaRoot oldMetaRoot )
+    {
+        MetaRoot newMetaRoot = new MetaRoot();
+        newMetaRoot.rootID = oldMetaRoot.rootID;
+        newMetaRoot.treeHeight = oldMetaRoot.treeHeight;
+        
+        return newMetaRoot;
+    }
+    
+    
+    private void updateMetaRoot( long newRootId, int newTreeHeight ) throws IOException
+    {
+        metaRoot = this.copyOnWrite( metaRoot );
+        metaRoot.rootID = newRootId;
+        metaRoot.treeHeight = newTreeHeight;
+        
+        if ( isActionCapable )
+        { 
+            recordManager.update( -this.recordId, metaRoot );
+        }
+    }
+    
+    
+    V copyValue( V value) throws IOException 
+    {
+        byte[] array;
+        V valueCopy = null;
+        
+        if ( this.valueSerializer != null )
+        {
+            array = this.valueSerializer.serialize( value );
+            valueCopy = (V) this.valueSerializer.deserialize( array );
+        }
+        else
+        {
+            ObjectOutputStream out = null;
+            ObjectInputStream in = null;
+            ByteArrayOutputStream bout = null;
+            ByteArrayInputStream bin = null;
+
+            try
+            {
+                bout = new ByteArrayOutputStream();
+                out = new ObjectOutputStream( bout );
+                out.writeObject( value );
+                out.flush();
+                byte[]  arr = bout.toByteArray();
+                bin = new ByteArrayInputStream( arr );
+                in =new ObjectInputStream( bin );
+                valueCopy = ( V )in.readObject();
+            }
+            catch ( ClassNotFoundException e )
+            {
+                throw new WrappedRuntimeException( e );
+            }
+            finally
+            {
+                if ( bout != null )
+                {
+                    bout.close();
+                }
+
+                if ( out != null )
+                {
+                    out.close();
+                }
+
+                if ( bin != null )
+                {
+                    bin.close();
+                }
+
+                if ( in != null )
+                {
+                    in.close();
+                }
+            }
+
+        }
+        
+        return valueCopy;
+    }
+    
+    
     public String toString()
     {
         StringBuilder sb = new StringBuilder();
@@ -662,4 +1051,14 @@ public class BTree<K, V> implements Exte
 
         return sb.toString();
     }
+    
+    /**
+     * Used to point to the root page that the reader needs based on the reader's
+     * read action context. ReadWrite actions always use the latest root. 
+     */
+    class MetaRoot
+    {
+        long rootID;
+        int treeHeight;
+    }
 }

Modified: directory/apacheds/trunk/jdbm/src/main/java/jdbm/helper/TupleBrowser.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm/src/main/java/jdbm/helper/TupleBrowser.java?rev=1164182&r1=1164181&r2=1164182&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm/src/main/java/jdbm/helper/TupleBrowser.java (original)
+++ directory/apacheds/trunk/jdbm/src/main/java/jdbm/helper/TupleBrowser.java Thu Sep  1 17:34:03 2011
@@ -73,4 +73,11 @@ public abstract class TupleBrowser<K, V>
      *         no previous tuple.
      */
     public abstract boolean getPrevious( Tuple<K, V> tuple ) throws IOException;
+    
+    
+    /**
+     * Closes the browser and deallocates any resources it might have allocated.
+     * Repeated calls of close are OK.
+     */
+    public void close() {}
 }

Modified: directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BaseRecordManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BaseRecordManager.java?rev=1164182&r1=1164181&r2=1164182&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BaseRecordManager.java (original)
+++ directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BaseRecordManager.java Thu Sep  1 17:34:03 2011
@@ -51,6 +51,10 @@ package jdbm.recman;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 import jdbm.RecordManager;
 import jdbm.helper.DefaultSerializer;
@@ -80,8 +84,7 @@ import org.apache.directory.server.i18n.
  * @author <a href="mailto:boisvert@intalio.com">Alex Boisvert</a>
  * @author <a href="cg@cdegroot.com">Cees de Groot</a>
  */
-public final class BaseRecordManager
-    implements RecordManager
+public final class BaseRecordManager implements RecordManager
 {
     /** Underlying record recordFile. */
     private RecordFile recordFile;
@@ -107,6 +110,102 @@ public final class BaseRecordManager
      * the NAME_DIRECTORY_ROOT.
      */
     private Map<String,Long> nameDirectory;
+    
+    private static enum IOType
+    {
+        READ_IO,
+        WRITE_IO
+    }
+
+    /** TODO add asserts to check internal consistency */
+    private static class LockElement
+    {
+        private int readers;
+        private int waiters;
+        private boolean writer;
+
+        private Lock lock = new ReentrantLock();
+        private Condition cv = lock.newCondition();
+
+
+        public boolean anyReaders()
+        {
+            return readers > 0;
+        }
+
+
+        public boolean anyWaiters()
+        {
+            return waiters > 0;
+        }
+
+
+        public boolean beingWritten()
+        {
+            return writer;
+        }
+
+
+        public boolean anyUser()
+        {
+            return ( readers > 0 || waiters > 0 || writer );
+        }
+
+
+        public void bumpReaders()
+        {
+            readers++;
+        }
+
+
+        public void decrementReaders()
+        {
+            readers--;
+        }
+
+
+        public void bumpWaiters()
+        {
+            waiters++;
+        }
+
+
+        public void decrementWaiters()
+        {
+            waiters--;
+        }
+
+
+        public void setWritten()
+        {
+            writer = true;
+        }
+
+
+        public void unsetWritten()
+        {
+            writer = false;
+        }
+
+
+        public Lock getLock()
+        {
+            return lock;
+        }
+
+
+        public Condition getNoConflictingIOCondition()
+        {
+            return cv;
+        }
+    }
+
+    
+    /**
+     * Map used to synchronize reads and writes on the same logical
+     * recid.
+     */
+    private final ConcurrentHashMap<Long, LockElement> lockElements;
 
 
     /**
@@ -121,13 +220,14 @@ public final class BaseRecordManager
         pageMgr = new PageManager( recordFile );
         physMgr = new PhysicalRowIdManager( pageMgr );
         logMgr = new LogicalRowIdManager( pageMgr );
+        lockElements = new ConcurrentHashMap<Long, LockElement>();
     }
 
 
     /**
      * Get the underlying Transaction Manager
      */
-    public synchronized TransactionManager getTransactionManager() throws IOException
+    public TransactionManager getTransactionManager() throws IOException
     {
         checkIfClosed();
         return recordFile.getTxnMgr();
@@ -143,7 +243,7 @@ public final class BaseRecordManager
      *  Only call this method directly after opening the file, otherwise
      *  the results will be undefined.
      */
-    public synchronized void disableTransactions()
+    public void disableTransactions()
     {
         checkIfClosed();
         recordFile.disableTransactions();
@@ -155,7 +255,7 @@ public final class BaseRecordManager
      *
      * @throws IOException when one of the underlying I/O operations fails.
      */
-    public synchronized void close() throws IOException
+    public void close() throws IOException
     {
         checkIfClosed();
 
@@ -188,7 +288,7 @@ public final class BaseRecordManager
      * @return the rowid for the new record.
      * @throws IOException when one of the underlying I/O operations fails.
      */
-    public synchronized long insert( Object obj, Serializer serializer ) throws IOException
+    public long insert( Object obj, Serializer serializer ) throws IOException
     {
         byte[]    data;
         long      recid;
@@ -215,8 +315,9 @@ public final class BaseRecordManager
      * @param recid the rowid for the record that should be deleted.
      * @throws IOException when one of the underlying I/O operations fails.
      */
-    public synchronized void delete( long recid ) throws IOException
+    public void delete( long recid ) throws IOException
     {
+        LockElement element;
         checkIfClosed();
         
         if ( recid <= 0 ) 
@@ -229,10 +330,20 @@ public final class BaseRecordManager
             System.out.println( "BaseRecordManager.delete() recid " + recid ) ;
         }
 
-        Location logRowId = new Location( recid );
-        Location physRowId = logMgr.fetch( logRowId );
-        physMgr.delete( physRowId );
-        logMgr.delete( logRowId );
+        
+        element = this.beginIO(recid, IOType.WRITE_IO);
+        
+        try
+        {
+            Location logRowId = new Location( recid );
+            Location physRowId = logMgr.fetch( logRowId );
+            physMgr.delete( physRowId );
+            logMgr.delete( logRowId );
+        }
+        finally
+        {
+            this.endIO(recid, element, IOType.WRITE_IO);
+        }
     }
 
 
@@ -247,8 +358,8 @@ public final class BaseRecordManager
     {
         update( recid, obj, DefaultSerializer.INSTANCE );
     }
-
     
+
     /**
      * Updates a record using a custom serializer.
      *
@@ -257,8 +368,10 @@ public final class BaseRecordManager
      * @param serializer a custom serializer
      * @throws IOException when one of the underlying I/O operations fails.
      */
-    public synchronized void update( long recid, Object obj, Serializer serializer ) throws IOException
+    public void update( long recid, Object obj, Serializer serializer ) throws IOException
     {
+        LockElement element;
+        
         checkIfClosed();
 
         if ( recid <= 0 ) 
@@ -266,24 +379,33 @@ public final class BaseRecordManager
             throw new IllegalArgumentException( I18n.err( I18n.ERR_536, recid ) );
         }
 
-        Location logRecid = new Location( recid );
-        Location physRecid = logMgr.fetch( logRecid );
-
-        byte[] data = serializer.serialize( obj );
-        
-        if ( DEBUG ) 
-        {
-            System.out.println( "BaseRecordManager.update() recid " + recid + " length " + data.length ) ;
-        }
-        
-        Location newRecid = physMgr.update( physRecid, data, 0, data.length );
-        
-        if ( ! newRecid.equals( physRecid ) ) 
-        {
-            logMgr.update( logRecid, newRecid );
-        }
+        element = this.beginIO(recid, IOType.WRITE_IO);
+         
+        try
+        {
+            Location logRecid = new Location( recid );
+            Location physRecid = logMgr.fetch( logRecid );
+
+            byte[] data = serializer.serialize( obj );
+            
+            if ( DEBUG ) 
+            {
+                System.out.println( "BaseRecordManager.update() recid " + recid + " length " + data.length ) ;
+            }
+            
+            Location newRecid = physMgr.update( physRecid, data, 0, data.length );
+            
+            if ( ! newRecid.equals( physRecid ) ) 
+            {
+                logMgr.update( logRecid, newRecid );
+            }
+         }
+         finally
+         {
+             this.endIO(recid, element, IOType.WRITE_IO);
+         } 
     }
-
+    
 
     /**
      * Fetches a record using standard java object serialization.
@@ -297,7 +419,7 @@ public final class BaseRecordManager
         return fetch( recid, DefaultSerializer.INSTANCE );
     }
 
-
+    
     /**
      * Fetches a record using a custom serializer.
      *
@@ -306,26 +428,40 @@ public final class BaseRecordManager
      * @return the object contained in the record.
      * @throws IOException when one of the underlying I/O operations fails.
      */
-    public synchronized Object fetch( long recid, Serializer serializer )
-        throws IOException
+    public Object fetch( long recid, Serializer serializer ) throws IOException
     {
-        byte[] data;
-
+        Object result;
+        LockElement element;
+        
         checkIfClosed();
-       
+        
         if ( recid <= 0 ) 
         {
             throw new IllegalArgumentException( I18n.err( I18n.ERR_536, recid ) );
         }
         
-        data = physMgr.fetch( logMgr.fetch( new Location( recid ) ) );
+        element = this.beginIO(recid, IOType.READ_IO);
         
-        if ( DEBUG ) 
+        try
+        {
+            byte[] data; 
+            
+            data = physMgr.fetch( logMgr.fetch( new Location( recid ) ) );
+            
+            if ( DEBUG ) 
+            {
+                System.out.println( "BaseRecordManager.fetch() recid " + recid + " length " + data.length ) ;
+            }
+            
+            result = serializer.deserialize( data );
+        }
+        finally
         {
-            System.out.println( "BaseRecordManager.fetch() recid " + recid + " length " + data.length ) ;
+            this.endIO(recid, element, IOType.READ_IO);
         }
         
-        return serializer.deserialize( data );
+        
+        return result;
     }
 
 
@@ -346,7 +482,7 @@ public final class BaseRecordManager
      *
      *  @see #getRootCount
      */
-    public synchronized long getRoot( int id ) throws IOException
+    public long getRoot( int id ) throws IOException
     {
         checkIfClosed();
 
@@ -359,7 +495,7 @@ public final class BaseRecordManager
      *
      *  @see #getRootCount
      */
-    public synchronized void setRoot( int id, long rowid ) throws IOException
+    public void setRoot( int id, long rowid ) throws IOException
     {
         checkIfClosed();
 
@@ -403,6 +539,7 @@ public final class BaseRecordManager
         {
             getNameDirectory().put( name, recid );
         }
+        
         saveNameDirectory( );
     }
 
@@ -410,8 +547,7 @@ public final class BaseRecordManager
     /**
      * Commit (make persistent) all changes since beginning of transaction.
      */
-    public synchronized void commit()
-        throws IOException
+    public void commit() throws IOException
     {
         checkIfClosed();
 
@@ -422,7 +558,7 @@ public final class BaseRecordManager
     /**
      * Rollback (cancel) all changes since beginning of transaction.
      */
-    public synchronized void rollback() throws IOException
+    public void rollback() throws IOException
     {
         checkIfClosed();
 
@@ -477,4 +613,163 @@ public final class BaseRecordManager
             throw new IllegalStateException( I18n.err( I18n.ERR_538 ) );
         }
     }
+    
+
+    /**
+     * Used to serialize reads/write on a given logical rowid. Checks if there is a 
+     * ongoing conflicting IO to the same logical rowid and waits for the ongoing
+     * write if there is one. 
+     *
+     * @param recid the logical rowid for which the fetch will be done.
+     * @param io type of the IO
+     * @return lock element representing the logical lock gotten
+     */
+    private LockElement beginIO( Long recid, IOType io )
+    {
+        boolean lockVerified = false;
+        LockElement element = null;
+
+        // loop until we successfully verify that there is no concurrent writer
+/*
+        element = lockElements.get( recid );
+        
+        do
+        {
+            if ( element == null )
+            {
+                element = new LockElement();
+
+                if ( io == IOType.READ_IO )
+                {
+                    element.bumpReaders();
+                }
+                else
+                {
+                    element.setWritten();
+                }
+
+                LockElement existingElement = lockElements.putIfAbsent( recid, element );
+
+                if ( existingElement == null )
+                {
+                    lockVerified = true;
+                }
+                else
+                {
+                    element = existingElement;
+                }
+            }
+            else
+            {
+                Lock lock = element.getLock();
+                lock.lock();
+                
+                if ( element.anyUser() )
+                {
+                    if ( this.conflictingIOPredicate( io, element ) )
+                    {
+                        element.bumpWaiters();
+                        
+                        do
+                        {
+                            element.getNoConflictingIOCondition()
+                                .awaitUninterruptibly();
+                        }
+                        while ( this.conflictingIOPredicate( io, element ) );
+
+                        element.decrementWaiters();
+                    }
+
+                    // no conflicting IO anymore..done
+                    if ( io == IOType.READ_IO )
+                    {
+                        element.bumpReaders();
+                    }
+                    else
+                    {
+                        element.setWritten();
+                    }
+                    
+                    lockVerified = true;
+                }
+                else
+                {
+                    if ( io == IOType.READ_IO )
+                    {
+                        element.bumpReaders();
+                    }
+                    else
+                    {
+                        element.setWritten();
+                    }
+
+                    LockElement existingElement = lockElements.get( recid );
+
+                    if ( element != existingElement )
+                    {
+                        element = existingElement;
+                    }
+                    else
+                    {
+                        lockVerified = true; // done
+                    }
+                }
+                
+                lock.unlock();
+            }
+        }
+        while ( !lockVerified );
+*/
+        return element;
+    }
+
+
+    /**
+     * Ends the IO by releasing the logical lock on the given recid
+     * 
+     * @param recid logical recid for which the IO is being ended
+     * @param element logical lock to be released
+     * @param io type of the io
+     */
+    private void endIO( Long recid, LockElement element, IOType io )
+    {
+        /*
+        Lock lock = element.getLock();
+        lock.lock();
+
+        if ( io == IOType.READ_IO )
+        {
+            element.decrementReaders();
+        }
+        else
+        {
+            element.unsetWritten();
+        }
+
+        if ( element.anyWaiters() )
+        {
+            element.getNoConflictingIOCondition().notifyAll();
+        }
+
+        if ( !element.anyUser() )
+        {
+            lockElements.remove( recid );
+        }
+
+        lock.unlock();
+        */
+    }
+
+
+    private boolean conflictingIOPredicate( IOType io, LockElement element )
+    {
+        if ( io == IOType.READ_IO )
+        { 
+            return element.beingWritten();
+        }
+        else
+        {
+            return ( element.anyReaders() || element.beingWritten() );
+        }
+    }
 }

Modified: directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BlockIo.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BlockIo.java?rev=1164182&r1=1164181&r2=1164182&view=diff
==============================================================================
--- directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BlockIo.java (original)
+++ directory/apacheds/trunk/jdbm/src/main/java/jdbm/recman/BlockIo.java Thu Sep  1 17:34:03 2011
@@ -52,6 +52,7 @@ import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.util.concurrent.atomic.AtomicInteger;
 
+
 import org.apache.directory.server.i18n.I18n;
 
 

Propchange: directory/apacheds/trunk/ldap-client-test/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -0,0 +1 @@
+/directory/apacheds/branches/apacheds-jdbm/ldap-client-test:1160768-1164092

Propchange: directory/apacheds/trunk/ldif-partition/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -1,6 +1,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/ldif-partition:982369-987590
 /directory/apacheds/branches/apacheds-config/ldif-partition:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/ldif-partition:980138-980936
+/directory/apacheds/branches/apacheds-jdbm/ldif-partition:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/ldif-partition:1040956-1043765
 /directory/apacheds/branches/milestones/ldif-partition:1072812-1075328
 /directory/apacheds/trunk/ldif-partition:1066126-1067785,1068026-1072718,1072800-1075329

Propchange: directory/apacheds/trunk/protocol-ldap/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -2,6 +2,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/protocol-ldap:982369-987590
 /directory/apacheds/branches/apacheds-config/protocol-ldap:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/protocol-ldap:980138-980936
+/directory/apacheds/branches/apacheds-jdbm/protocol-ldap:1160768-1164080
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-ldap:1040956-1043765
 /directory/apacheds/branches/milestones/protocol-ldap:1072812-1075328
 /directory/apacheds/trunk/protocol-ldap:1066126-1067785,1068026-1072718,1072800-1075329

Propchange: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -2,6 +2,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/SyncReplConsumer.java:982369-987590
 /directory/apacheds/branches/apacheds-config/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/SyncReplConsumer.java:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/SyncReplConsumer.java:980138-980936
+/directory/apacheds/branches/apacheds-jdbm/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java:1160768-1164080
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/SyncReplConsumer.java:1040956-1043765
 /directory/apacheds/branches/apacheds-replication/syncrepl/src/main/java/org/apache/directory/server/syncrepl/SyncReplConsumer.java:749790-762530
 /directory/apacheds/branches/apacheds-schema/syncrepl/src/main/java/org/apache/directory/server/syncrepl/SyncReplConsumer.java:806623-896441

Propchange: directory/apacheds/trunk/protocol-shared/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -1,6 +1,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/protocol-shared:982369-987590
 /directory/apacheds/branches/apacheds-config/protocol-shared:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/protocol-shared:980138-980936
+/directory/apacheds/branches/apacheds-jdbm/protocol-shared:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-shared:1040956-1043765
 /directory/apacheds/branches/milestones/protocol-shared:1072812-1075328
 /directory/apacheds/trunk/protocol-shared:1066126-1067785,1068026-1072718,1072800-1075329

Propchange: directory/apacheds/trunk/server-annotations/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -1,6 +1,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-annotations:982369-987590
 /directory/apacheds/branches/apacheds-config/server-annotations:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-annotations:980138-980937
+/directory/apacheds/branches/apacheds-jdbm/server-annotations:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-annotations:1040956-1043765
 /directory/apacheds/branches/milestones/server-annotations:1072812-1075328
 /directory/apacheds/trunk/server-annotations:1066126-1067785,1068026-1072718,1072800-1075329

Propchange: directory/apacheds/trunk/server-config/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -2,6 +2,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-config:982369-987590
 /directory/apacheds/branches/apacheds-config/server-config:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-config:980138-980938
+/directory/apacheds/branches/apacheds-jdbm/server-config:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-config:1040956-1043765
 /directory/apacheds/branches/milestones/server-config:1072812-1075328
 /directory/apacheds/branches/server-config-annotations/server-config:1042727-1043868

Propchange: directory/apacheds/trunk/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -2,6 +2,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java:982369-987590
 /directory/apacheds/branches/apacheds-config/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java:980138-980938
+/directory/apacheds/branches/apacheds-jdbm/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-config/src/main/java/org/apache/directory/server/config/ConfigPartitionReader.java:1040956-1043765
 /directory/apacheds/branches/apacheds-replication/core-annotations/src/main/java/org/apache/directory/server/core/factory/ConfigPartitionReader.java:749790-764110
 /directory/apacheds/branches/apacheds-schema/core-annotations/src/main/java/org/apache/directory/server/core/factory/ConfigPartitionReader.java:806623-896441

Propchange: directory/apacheds/trunk/server-config/src/main/resources/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -3,6 +3,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-config/src/main/resources:982369-987590
 /directory/apacheds/branches/apacheds-config/server-config/src/main/resources:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-config/src/main/resources:980138-980938
+/directory/apacheds/branches/apacheds-jdbm/server-config/src/main/resources:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-config/src/main/resources:1040956-1043765
 /directory/apacheds/branches/apacheds-replication/core-annotations/src/main/resources:749790-764110
 /directory/apacheds/branches/apacheds-replication/default-config/src/main/resources:749790-764110

Propchange: directory/apacheds/trunk/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -3,6 +3,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java:982369-987590
 /directory/apacheds/branches/apacheds-config/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java:980138-980938
+/directory/apacheds/branches/apacheds-jdbm/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-config/src/test/java/org/apache/directory/server/config/ConfigPartitionReaderTest.java:1040956-1043765
 /directory/apacheds/branches/apacheds-replication/core-annotations/src/main/java/org/apache/directory/server/core/factory/CiDITDirectoryServiceFactory.java:749790-764110
 /directory/apacheds/branches/apacheds-schema/core-annotations/src/main/java/org/apache/directory/server/core/factory/CiDITDirectoryServiceFactory.java:806623-896441

Propchange: directory/apacheds/trunk/server-integ/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -2,6 +2,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-integ:982369-987590
 /directory/apacheds/branches/apacheds-config/server-integ:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-integ:980138-980937
+/directory/apacheds/branches/apacheds-jdbm/server-integ:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-integ:1040956-1043765
 /directory/apacheds/branches/milestones/server-integ:1072812-1075328
 /directory/apacheds/trunk/server-integ:1066126-1067785,1068026-1072718,1072800-1075329

Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java?rev=1164182&r1=1164181&r2=1164182&view=diff
==============================================================================
--- directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java (original)
+++ directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java Thu Sep  1 17:34:03 2011
@@ -50,6 +50,7 @@ import org.apache.directory.shared.ldap.
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.Ignore;
 
 
 /**
@@ -98,6 +99,7 @@ public class StoredProcedureIT extends A
     }
 
 
+    @Ignore
     @Test
     public void testExecuteProcedureWithReturnValue() throws Exception
     {
@@ -109,6 +111,7 @@ public class StoredProcedureIT extends A
     }
 
 
+    @Ignore
     @Test
     public void testExecuteProcedureWithParametersAndReturnValue() throws Exception
     {

Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java?rev=1164182&r1=1164181&r2=1164182&view=diff
==============================================================================
--- directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java (original)
+++ directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/replication/ClientServerReplicationIT.java Thu Sep  1 17:34:03 2011
@@ -120,6 +120,7 @@ public class ClientServerReplicationIT
                 if ( entry.getDn().equals( entryDn ) )
                 {
                     System.out.println( "The searched entry exists !!!" );
+                    System.out.println( "found Entry " + entry.getDn().getNormName() + " exists, entrtyUuid = " + entry.get( "entryUuid" ) );
                     break;
                 }
                 

Propchange: directory/apacheds/trunk/server-jndi/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -1,6 +1,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/server-jndi:982369-987590
 /directory/apacheds/branches/apacheds-config/server-jndi:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/server-jndi:980138-980937
+/directory/apacheds/branches/apacheds-jdbm/server-jndi:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/server-jndi:1040956-1043765
 /directory/apacheds/branches/milestones/server-jndi:1072812-1075328
 /directory/apacheds/trunk/server-jndi:1066126-1067785,1068026-1072718,1072800-1075329

Propchange: directory/apacheds/trunk/service/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -0,0 +1 @@
+/directory/apacheds/branches/apacheds-jdbm/service:1160768-1164092

Propchange: directory/apacheds/trunk/xdbm-partition/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -1,6 +1,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/xdbm-partition:982369-987590
 /directory/apacheds/branches/apacheds-config/xdbm-partition:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/xdbm-partition:980138-980938
+/directory/apacheds/branches/apacheds-jdbm/xdbm-partition:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/xdbm-partition:1040956-1043765
 /directory/apacheds/branches/milestones/xdbm-partition:1072812-1075328
 /directory/apacheds/trunk/xdbm-partition:1066126-1067785,1068026-1072718,1072800-1075329

Propchange: directory/apacheds/trunk/xdbm-tools/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep  1 17:34:03 2011
@@ -1,6 +1,7 @@
 /directory/apacheds/branches/apacheds-codec-merge/xdbm-tools:982369-987590
 /directory/apacheds/branches/apacheds-config/xdbm-tools:1023442-1029077
 /directory/apacheds/branches/apacheds-dnfactory-experiment/xdbm-tools:980138-980938
+/directory/apacheds/branches/apacheds-jdbm/xdbm-tools:1160768-1164092
 /directory/apacheds/branches/apacheds-kerberos-codec-2.0/xdbm-tools:1040956-1043765
 /directory/apacheds/branches/milestones/xdbm-tools:1072812-1075328
 /directory/apacheds/trunk/xdbm-tools:1066126-1067785,1068026-1072718,1072800-1075329