directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1162833 - in /directory/apacheds/branches/apacheds-jdbm: core/src/main/java/org/apache/directory/server/core/subtree/ jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/ jdbm/src/main/java/jdbm/ jdbm/sr...
Date Mon, 29 Aug 2011 14:31:54 GMT
Author: elecharny
Date: Mon Aug 29 14:31:53 2011
New Revision: 1162833

URL: http://svn.apache.org/viewvc?rev=1162833&view=rev
Log:
applied Selcuk's change

Modified:
    directory/apacheds/branches/apacheds-jdbm/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
    directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsContainerCursor.java
    directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java
    directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
    directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java
    directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java
    directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/ActionRecordManager.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BPage.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BTree.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/ActionContext.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/LRUCache.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/recman/SnapshotRecordManager.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/btree/SnapshotBTree.java
    directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/helper/TestVersionedCache.java
    directory/apacheds/branches/apacheds-jdbm/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java

Modified: directory/apacheds/branches/apacheds-jdbm/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/core/src/main/java/org/apache/directory/server/core/subtree/SubentryInterceptor.java Mon Aug 29 14:31:53 2011
@@ -371,6 +371,7 @@ public class SubentryInterceptor extends
                     nexus.modify( new ModifyOperationContext( session, candidateDn, modifications ) );
                 }
             }
+            subentries.close();
         }
         catch ( Exception e )
         {
@@ -1085,6 +1086,8 @@ public class SubentryInterceptor extends
                             getOperationalModsForRemove( dn, candidate ) ) );
                     }
                 }
+                
+                subentries.close();
             }
             catch ( Exception e )
             {
@@ -1115,6 +1118,7 @@ public class SubentryInterceptor extends
                             getOperationalModsForAdd( candidate, operationalAttributes ) ) );
                     }
                 }
+                subentries.close();
             }
             catch ( Exception e )
             {

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsContainerCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsContainerCursor.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsContainerCursor.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsContainerCursor.java Mon Aug 29 14:31:53 2011
@@ -106,7 +106,7 @@ public class DupsContainerCursor<K,V> ex
     public void beforeKey( K key ) throws Exception
     {
         checkNotClosed( "beforeKey()" );
-        
+        this.closeBrowser( browser );
         browser = ((BTree<K,V>)table.getBTree()).browse( key );
         forwardDirection = null;
         clearValue();
@@ -121,6 +121,7 @@ public class DupsContainerCursor<K,V> ex
     {
         checkNotClosed( "afterKey()" );
 
+        this.closeBrowser( browser );
         browser = ((BTree<K,V>)table.getBTree()).browse( key );
         forwardDirection = null;
 
@@ -203,7 +204,7 @@ public class DupsContainerCursor<K,V> ex
     public void beforeFirst() throws Exception
     {
         checkNotClosed( "beforeFirst()" );
-        
+        this.closeBrowser( browser );
         browser = table.getBTree().browse();
         forwardDirection = null;
         clearValue();
@@ -217,7 +218,7 @@ public class DupsContainerCursor<K,V> ex
     public void afterLast() throws Exception
     {
         checkNotClosed( "afterLast()" );
-        
+        this.closeBrowser( browser );
         browser = table.getBTree().browse( null );
         forwardDirection = null;
         clearValue();
@@ -367,4 +368,33 @@ public class DupsContainerCursor<K,V> ex
 
         throw new InvalidCursorPositionException();
     }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws Exception
+    {
+        super.close();
+        this.closeBrowser( browser );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close( Exception cause ) throws Exception
+    {
+        super.close( cause );
+        this.closeBrowser( browser );
+    }
+    
+    private void closeBrowser(TupleBrowser browser)
+    {
+        if ( browser != null )
+        {
+            browser.close();
+        }
+    }
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursor.java Mon Aug 29 14:31:53 2011
@@ -456,4 +456,25 @@ class DupsCursor<K,V> extends AbstractTu
 
         return returnedTuple;
     }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws Exception
+    {
+        super.close();
+        containerCursor.close();            
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close( Exception cause ) throws Exception
+    {
+        super.close( cause );
+        containerCursor.close( cause );
+    }
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/JdbmTable.java Mon Aug 29 14:31:53 2011
@@ -332,7 +332,9 @@ public class JdbmTable<K,V> extends Abst
         BTree tree = getBTree( values.getBTreeRedirect() );
 
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
-        tree.browse().getNext( tuple );
+        TupleBrowser<K,V> browser = tree.browse();
+        browser.getNext( tuple );
+        this.closeBrowser( browser );
         //noinspection unchecked
         
         return ( V ) tuple.getKey();
@@ -465,11 +467,12 @@ public class JdbmTable<K,V> extends Abst
              * be the previous tuple if it exists.
              */
             TupleBrowser browser = bt.browse( tuple.getKey() );
-            
             if ( browser.getPrevious( tuple ) )
             {
+                this.closeBrowser( browser );
                 return true;
             }
+            this.closeBrowser( browser );
         }
 
         return false;
@@ -983,34 +986,42 @@ public class JdbmTable<K,V> extends Abst
         jdbm.helper.Tuple tuple = new jdbm.helper.Tuple();
         
         TupleBrowser browser = tree.browse( key );
-        if ( isGreaterThan )
-        {
-            return browser.getNext( tuple );
-        }
-        else
+        
+        try
         {
-            if ( browser.getPrevious( tuple ) )
-            {
-                return true;
+            if ( isGreaterThan )
+            { 
+                return browser.getNext( tuple );
             }
             else
             {
-                /*
-                 * getPrevious() above fails which means the browser has is
-                 * before the first Tuple of the btree.  A call to getNext()
-                 * should work every time.
-                 */
-                browser.getNext( tuple );
-
-                /*
-                 * Since the browser is positioned now on the Tuple with the
-                 * smallest key we just need to check if it equals this key
-                 * which is the only chance for returning true.
-                 */
-                V firstKey = ( V ) tuple.getKey();
-                return valueComparator.compare( key, firstKey ) == 0;
+                if ( browser.getPrevious( tuple ) )
+                {
+                    return true;
+                }
+                else
+                {
+                    /*
+                     * getPrevious() above fails which means the browser has is
+                     * before the first Tuple of the btree.  A call to getNext()
+                     * should work every time.
+                     */
+                    browser.getNext( tuple );
+    
+                    /*
+                     * Since the browser is positioned now on the Tuple with the
+                     * smallest key we just need to check if it equals this key
+                     * which is the only chance for returning true.
+                     */
+                    V firstKey = ( V ) tuple.getKey();
+                    return valueComparator.compare( key, firstKey ) == 0;
+                }
             }
         }
+        finally
+        {
+            this.closeBrowser( browser );
+        }
     }
 
 
@@ -1026,6 +1037,7 @@ public class JdbmTable<K,V> extends Abst
             avlTree.insert( ( V ) tuple.getKey() );
         }
 
+        this.closeBrowser( browser );
         return avlTree;
     }
     
@@ -1053,4 +1065,12 @@ public class JdbmTable<K,V> extends Abst
         
         return bTree;
     }
+    
+    private void closeBrowser(TupleBrowser<K,V> browser)
+    {
+        if ( browser != null )
+        {
+            browser.close();
+        }
+    }
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyBTreeCursor.java Mon Aug 29 14:31:53 2011
@@ -76,6 +76,7 @@ public class KeyBTreeCursor<E> extends A
     public void before( E element ) throws Exception
     {
         checkNotClosed( "before()" );
+        this.closeBrowser( browser );
         browser = btree.browse( element );
         clearValue();
     }
@@ -84,6 +85,7 @@ public class KeyBTreeCursor<E> extends A
     @SuppressWarnings("unchecked")
     public void after( E element ) throws Exception
     {
+        this.closeBrowser( browser );
         browser = btree.browse( element );
 
         /*
@@ -125,6 +127,7 @@ public class KeyBTreeCursor<E> extends A
     public void beforeFirst() throws Exception
     {
         checkNotClosed( "beforeFirst()" );
+        this.closeBrowser( browser );
         browser = btree.browse();
         clearValue();
     }
@@ -133,6 +136,7 @@ public class KeyBTreeCursor<E> extends A
     public void afterLast() throws Exception
     {
         checkNotClosed( "afterLast()" );
+        this.closeBrowser( browser );
         browser = btree.browse( null );
     }
 
@@ -202,4 +206,33 @@ public class KeyBTreeCursor<E> extends A
 
         throw new InvalidCursorPositionException();
     }
+ 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws Exception
+    {
+        super.close();
+        this.closeBrowser( browser );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close( Exception cause ) throws Exception
+    {
+        super.close( cause );
+        this.closeBrowser( browser );
+    }
+    
+    private void closeBrowser(TupleBrowser browser)
+    {
+        if ( browser != null )
+        {
+            browser.close();
+        }
+    }
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/KeyTupleBTreeCursor.java Mon Aug 29 14:31:53 2011
@@ -108,7 +108,7 @@ public class KeyTupleBTreeCursor<K,V> ex
         {
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
         }
-
+        this.closeBrowser( browser );
         browser = btree.browse( value );
         clearValue();
     }
@@ -125,6 +125,7 @@ public class KeyTupleBTreeCursor<K,V> ex
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_446 ) );
         }
 
+        this.closeBrowser( browser );
         browser = btree.browse( value );
 
         /*
@@ -152,6 +153,7 @@ public class KeyTupleBTreeCursor<K,V> ex
                  */
                 if ( !browser.getPrevious( valueTuple ) )
                 {
+                    this.closeBrowser( browser );
                     browser = btree.browse( this.key );
                 }
 
@@ -176,6 +178,7 @@ public class KeyTupleBTreeCursor<K,V> ex
     public void before( Tuple<K,V> element ) throws Exception
     {
         checkNotClosed( "before()" );
+        this.closeBrowser( browser );
         browser = btree.browse( element.getValue() );
         clearValue();
     }
@@ -196,6 +199,7 @@ public class KeyTupleBTreeCursor<K,V> ex
     public void beforeFirst() throws Exception
     {
         checkNotClosed( "beforeFirst()" );
+        this.closeBrowser( browser );
         browser = btree.browse();
         clearValue();
     }
@@ -207,6 +211,7 @@ public class KeyTupleBTreeCursor<K,V> ex
     public void afterLast() throws Exception
     {
         checkNotClosed( "afterLast()" );
+        this.closeBrowser( browser );
         browser = btree.browse( null );
     }
 
@@ -308,4 +313,33 @@ public class KeyTupleBTreeCursor<K,V> ex
 
         throw new InvalidCursorPositionException();
     }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws Exception
+    {
+        super.close();
+        this.closeBrowser( browser );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close( Exception cause ) throws Exception
+    {
+        super.close( cause );
+        this.closeBrowser( browser );
+    }
+    
+    private void closeBrowser(TupleBrowser browser)
+    {
+        if ( browser != null )
+        {
+            browser.close();
+        }
+    }
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/jdbm/NoDupsCursor.java Mon Aug 29 14:31:53 2011
@@ -78,6 +78,7 @@ class NoDupsCursor<K,V> extends Abstract
     public void beforeKey( K key ) throws Exception
     {
         checkNotClosed( "beforeKey()" );
+        this.closeBrowser( browser );
         browser = table.getBTree().browse( key );
         clearValue();
     }
@@ -86,6 +87,7 @@ class NoDupsCursor<K,V> extends Abstract
     @SuppressWarnings("unchecked")
     public void afterKey( K key ) throws Exception
     {
+        this.closeBrowser( browser );
         browser = table.getBTree().browse( key );
 
         /*
@@ -147,6 +149,7 @@ class NoDupsCursor<K,V> extends Abstract
     public void beforeFirst() throws Exception
     {
         checkNotClosed( "beforeFirst()" );
+        this.closeBrowser( browser );
         browser = table.getBTree().browse();
         clearValue();
     }
@@ -155,6 +158,7 @@ class NoDupsCursor<K,V> extends Abstract
     public void afterLast() throws Exception
     {
         checkNotClosed( "afterLast()" );
+        this.closeBrowser( browser );
         browser = table.getBTree().browse( null );
         clearValue();
     }
@@ -242,4 +246,33 @@ class NoDupsCursor<K,V> extends Abstract
 
         throw new InvalidCursorPositionException();
     }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close() throws Exception
+    {
+        super.close();
+        this.closeBrowser( browser );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void close( Exception cause ) throws Exception
+    {
+        super.close( cause );
+        this.closeBrowser( browser );
+    }
+    
+    private void closeBrowser(TupleBrowser browser)
+    {
+        if ( browser != null )
+        {
+            browser.close();
+        }
+    }
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/ActionRecordManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/ActionRecordManager.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/ActionRecordManager.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/ActionRecordManager.java Mon Aug 29 14:31:53 2011
@@ -2,17 +2,59 @@ package jdbm;
 
 import jdbm.helper.ActionContext;
 
-
+/**
+ * Extends the RecordManager to allow callers to group their RecordManager interface
+ * calls into actions. Actions operate in isolation. 
+ * 
+ * Each thread has a current action context associated with it. Threads can switch
+ * between different action context using set/unsetActionContext calls.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
 public interface ActionRecordManager extends RecordManager
 
 {
-    ActionContext beginAction( boolean readOnly );
+    /**
+     * Initializes the context for the action. Implicity sets the
+     * context as the current action.
+     *
+     * @param readOnly true if action does not do any modification
+     * @param whoStarted caller can use this for debugging
+     * @return
+     */
+    ActionContext beginAction( boolean readOnly, String whoStarted );
     
+    /**
+     * Ends the action associated with the context. 
+     * ReadWrite actions' changes are made visible
+     * to readers.
+     *
+     * @param context identifies the action to end
+     */
     void endAction( ActionContext context );
     
+    /**
+     * Aborts the given action. For write actions, actions's changes
+     * should not be made visible to readers.
+     *
+     * @param context identifies the action to abort
+     */
     void abortAction( ActionContext context );
     
-    void setCurrentActionContext( ActionContext context );
+    /**
+     * Set the context as the current action context for
+     * the given thread
+     *
+     * @param context identifies the context
+     */
+    public void setCurrentActionContext( ActionContext context );
     
-    void unsetCurrentActionContext( ActionContext context );
+    /**
+     * Unsets the context as the current action context. 
+     * Given context should be current action context for the 
+     * calling thread.
+     *
+     * @param context identifies the context.
+     */
+    public void unsetCurrentActionContext( ActionContext context );
 }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BPage.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BPage.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BPage.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BPage.java Mon Aug 29 14:31:53 2011
@@ -48,6 +48,8 @@ package jdbm.btree;
 
 
 import jdbm.btree.BTree.EmptyBrowser;
+import jdbm.btree.BTree.MetaRoot;
+import jdbm.helper.LRUCache;
 import jdbm.helper.Serializer;
 import jdbm.helper.Tuple;
 import jdbm.helper.TupleBrowser;
@@ -61,6 +63,8 @@ import java.io.ObjectOutput;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.directory.server.i18n.I18n;
 
 
@@ -82,7 +86,7 @@ import org.apache.directory.server.i18n.
  * @author <a href="mailto:boisvert@intalio.com">Alex Boisvert</a>
  */
 public class BPage<K, V> implements Serializer
-{
+{ 
     private static final boolean DEBUG = false;
 
     /** Version id for serialization. */
@@ -114,6 +118,8 @@ public class BPage<K, V> implements Seri
 
     /** Next leaf BPage (only if this BPage is a leaf) */
     protected long next;
+    
+    public static AtomicInteger outstandingBrowsers = new AtomicInteger(0);
 
 
     /**
@@ -129,7 +135,7 @@ public class BPage<K, V> implements Seri
      * Root page overflow constructor
      */
     @SuppressWarnings("unchecked")
-    BPage( BTree btree, BPage<K, V> root, BPage<K, V> overflow ) throws IOException
+    BPage( BTree<K, V> btree, BPage<K, V> root, BPage<K, V> overflow ) throws IOException
     {
         this.btree = btree;
 
@@ -153,7 +159,7 @@ public class BPage<K, V> implements Seri
      * Root page (first insert) constructor.
      */
     @SuppressWarnings("unchecked") // Cannot create an array of generic objects
-    BPage( BTree btree, K key, V value ) throws IOException
+    BPage( BTree<K,V> btree, K key, V value ) throws IOException
     {
         this.btree = btree;
 
@@ -166,7 +172,7 @@ public class BPage<K, V> implements Seri
         keys[btree.pageSize - 1] = null; // I am the root BPage for now
 
         values = (V[])new Object[btree.pageSize];
-        values[btree.pageSize - 2] = value;
+        values[btree.pageSize - 2] = btree.copyValue( value );
         values[btree.pageSize - 1] = null; // I am the root BPage for now
 
         recordId = btree.recordManager.insert( this, this );
@@ -288,10 +294,11 @@ public class BPage<K, V> implements Seri
      *
      * @param height Height of the current BPage (zero is leaf page)
      * @param key The key
+     * @param context action context in case of action capable record manager
      * @return TupleBrowser positionned just before the given key, or before
      *                      next greater key if key isn't found.
      */
-    TupleBrowser<K, V> find( int height, K key) throws IOException
+    TupleBrowser<K, V> find( int height, K key, ActionContext context) throws IOException
     {
         int index = this.findChildren( key );
         
@@ -314,26 +321,26 @@ public class BPage<K, V> implements Seri
             }
         }
 
-        return new Browser( child, index);
+        return new Browser( child, index, context);
     }
 
 
     /**
      * Find first entry and return a browser positioned before it.
-     *
+     *@param context Action Context in case of 
      * @return TupleBrowser positionned just before the first entry.
      */
-    TupleBrowser<K, V> findFirst() throws IOException
+    TupleBrowser<K, V> findFirst( ActionContext context ) throws IOException
     {
         if ( isLeaf )
         {
-            return new Browser( this, first );
+            return new Browser( this, first, context );
         }
         else
         {
             BPage<K, V> child = childBPage( first );
             
-            return child.findFirst();
+            return child.findFirst( context );
         }
     }
 
@@ -894,7 +901,7 @@ public class BPage<K, V> implements Seri
     /**
      * Insert entry at given position.
      */
-    private void insertEntry( BPage<K, V> page, int index, K key, V value )
+    private void insertEntry( BPage<K, V> page, int index, K key, V value ) throws IOException
     {
         K[] keys = page.keys;
         V[] values = page.values;
@@ -906,7 +913,7 @@ public class BPage<K, V> implements Seri
         System.arraycopy( values, start, values, start - 1, count );
         page.first -= 1;
         keys[index] = key;
-        values[index] = value;
+        values[index] = btree.copyValue( value );
     }
 
 
@@ -1413,7 +1420,10 @@ public class BPage<K, V> implements Seri
     {
         /** Current page. */
         private BPage<K, V> page;
-      
+        
+        /** context used to track browsing action */
+        ActionContext context;
+        
         /**
          * Current index in the page.  The index positionned on the next
          * tuple to return.
@@ -1425,12 +1435,16 @@ public class BPage<K, V> implements Seri
          * Create a browser.
          *
          * @param page Current page
+         * @param context context in case of action capable record manager 
          * @param index Position of the next tuple to return.
          */
-        Browser( BPage<K, V> page, int index)
+        Browser( BPage<K, V> page, int index, ActionContext context)
         {
             this.page = page;
             this.index = index;
+            this.context = context;
+            
+            outstandingBrowsers.incrementAndGet();
         }
 
 
@@ -1444,192 +1458,106 @@ public class BPage<K, V> implements Seri
          */
         public boolean getNext( Tuple<K, V> tuple ) throws IOException
         {
-            // First, check that we are within a page
-            if ( index < page.btree.pageSize )
-            {
-                // We are. Now check that we have a Tuple
-                if ( page.keys[index] == null )
-                {
-                    // no : reached end of the tree.
-                    return false;
-                }
-                
-                tuple.setKey( page.keys[index] );
-                tuple.setValue( btree.copyValue( page.values[index] ) );
-                index++;
-                return true;
-            }
-            // all the tuple for this page has been read. Move to the 
-            // next page, if we have one. Start a new action while
-            // doing so.
-
-            ActionContext context = btree.beginAction( true );
-            boolean abortedAction = false;
+            btree.setAsCurrentAction( context ); 
             try
             {
-                BPage<K, V> rootPage = btree.getRoot( true );
-
-                if ( rootPage == null )
+                // First, check that we are within a page                                                            
+                if ( index < page.btree.pageSize )
                 {
-                    return false;
-                }
-
-                K prevKey = page.keys[index - 1];
-                Browser browser = ( Browser ) rootPage.find( rootPage.btree.bTreeHeight, prevKey );
-
-                if ( browser.getNextWithinAction( tuple ) )
-                {
-                    if ( btree.comparator.compare( prevKey, tuple.getKey() ) == 0 )
+                    // We are. Now check that we have a Tuple                                                        
+                    if ( page.keys[index] == null )
                     {
-                        // Do not return the same key again, move on to the next key
-                        if ( browser.getNextWithinAction( tuple ) )
-                        {
-                            page = browser.getCurrentPage();
-                            index = browser.getCurrentIndex();
-                            return true;
-                        }
-                        else
-                        {
-                            return false;
-                        }
+                        // no : reached end of the tree.                                                             
+                        return false;
                     }
                 }
-                else
-                {
-                    return false;
+                // all the tuple for this page has been read. Move to the                                            
+                // next page, if we have one.                                                                        
+                else if ( page.next != 0 )
+                {
+                    // move to next page                                                                             
+                    page = page.loadBPage( page.next );
+                    index = page.first;
                 }
-
+    
+                tuple.setKey( page.keys[index] );
+                tuple.setValue( btree.copyValue( page.values[index] ) );
+                index++;
             }
-            catch ( IOException e )
+            catch( IOException e )
             {
-                abortedAction = true;
                 btree.abortAction( context );
+                context = null;
+                this.close();
+                throw e;
             }
             finally
             {
-                if ( !abortedAction )
-                    btree.endAction( context );
+                if ( context != null )
+                    btree.unsetAsCurrentAction( context );
             }
-
-            return false;
+          
+            return true;
         }
 
-
         public boolean getPrevious( Tuple<K, V> tuple ) throws IOException
         {
-            if ( index == page.first )
+            btree.setAsCurrentAction( context );           
+            try
             {
-                ActionContext context = btree.beginAction( true );
-                boolean abortedAction = false;
-                try
+                if ( index == page.first )
                 {
-                    BPage<K, V> rootPage = btree.getRoot( true );
-
-                    if ( rootPage == null )
+                    if ( page.previous != 0 )
                     {
-                        return false;
+                        page = page.loadBPage( page.previous );
+                        index = page.btree.pageSize;
                     }
-
-                    K prevKey = page.keys[index];
-                    Browser browser = ( Browser ) rootPage.find( rootPage.btree.bTreeHeight, prevKey );
-
-                    while ( browser.getPrevWithinAction( tuple ) )
+                    else
                     {
-                        if ( btree.comparator.compare( tuple.getKey(), prevKey ) < 0 )
-                        {
-
-                            page = browser.getCurrentPage();
-                            index = browser.getCurrentIndex();
-                            return true;
-
-                        }
+                        // reached beginning of the tree                                                             
+                        return false;
                     }
                 }
-                catch ( IOException e )
-                {
-                    abortedAction = true;
-                    btree.abortAction( context );
-                }
-                finally
-                {
-                    if ( !abortedAction )
-                        btree.endAction( context );
-                }
-
-                return false;
+    
+                index--;
+                tuple.setKey( page.keys[index] );
+                tuple.setValue( btree.copyValue( page.values[index] ) );
             }
-            
-            index--;
-            tuple.setKey( page.keys[index] );
-            tuple.setValue( btree.copyValue( page.values[index] ) );
-            
-            return true;
-        }
-
-
-        BPage<K, V> getCurrentPage()
-        {
-            return page;
-        }
-
-
-        int getCurrentIndex()
-        {
-            return index;
-        }
-        
-        boolean getNextWithinAction( Tuple<K, V> tuple ) throws IOException
-        {
-            // First, check that we are within a page
-            if ( index < page.btree.pageSize )
+            catch( IOException e )
             {
-                // We are. Now check that we have a Tuple
-                if ( page.keys[index] == null )
-                {
-                    // no : reached end of the tree.
-                    return false;
-                }
+                btree.abortAction( context );
+                context = null;
+                this.close();
+                throw e;
             }
-            // all the tuple for this page has been read. Move to the 
-            // next page,
-            else if ( page.next != 0 )
+            finally
             {
-                // move to next page                                                        
-                page = page.loadBPage( page.next );
-                index = page.first;
-            }
-
-            tuple.setKey( page.keys[index] );
-            tuple.setValue( btree.copyValue( page.values[index] ) );
-            index++;
+                if ( context != null )
+                    btree.unsetAsCurrentAction( context );
+            }          
 
             return true;
-            
         }
         
-        boolean getPrevWithinAction( Tuple<K, V> tuple ) throws IOException
+        @Override
+        public void close()
         {
-            if ( index == page.first )
+            super.close();
+            
+            if ( context!= null )
             {
-                if ( page.previous != 0 )
-                {
-                    page = page.loadBPage( page.previous );
-                    index = page.btree.pageSize;
-                }
-                else
-                {
-                    // reached beginning of the tree
-                    return false;
-                }
+                btree.setAsCurrentAction( context );
+                btree.endAction( context );
+                context = null;
+            }
+            
+            int browserCount = outstandingBrowsers.decrementAndGet();
+            if ( browserCount > 0 )
+            {
+                //System.out.println( "JDBM btree browsers are outstanding after close: " + browserCount );
             }
-
-            index--;
-            tuple.setKey( page.keys[index] );
-            tuple.setValue( btree.copyValue( page.values[index] ) );
-
-            return true;
         }
-        
+
     }
     
     

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BTree.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BTree.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BTree.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/btree/BTree.java Mon Aug 29 14:31:53 2011
@@ -147,6 +147,9 @@ public class BTree<K, V> implements Exte
     
     /** 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.
@@ -239,11 +242,11 @@ public class BTree<K, V> implements Exte
         this.isActionCapable = recordManager instanceof ActionRecordManager; 
 
         boolean abortedAction = false;
-        ActionContext context = this.beginAction( false );
-        
+        ActionContext context = this.beginAction( false, "createInstance" );
         try
         {
             this.recordId = recordManager.insert( this );
+            updateMetaRoot( this.rootId, this.bTreeHeight );
         }
         catch ( IOException e )
         {
@@ -280,12 +283,32 @@ 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;
     }
 
@@ -316,7 +339,7 @@ public class BTree<K, V> implements Exte
 
         
         boolean abortedAction = false;
-        ActionContext context  = this.beginAction( false );
+        ActionContext context  = this.beginAction( false, "insert" );
         
 
         if ( !isActionCapable )
@@ -324,7 +347,7 @@ public class BTree<K, V> implements Exte
         
         try
         {
-            BPage<K, V> rootPage = getRoot( false );
+            BPage<K, V> rootPage = getRoot();
     
             if ( rootPage == null )
             {
@@ -339,7 +362,7 @@ public class BTree<K, V> implements Exte
                 bTreeHeight = 1;
                 nbEntries.set( 1 );
                 recordManager.update( recordId, this );
-                
+                updateMetaRoot( this.rootId, this.bTreeHeight );
                 return null;
             }
             else
@@ -362,6 +385,7 @@ public class BTree<K, V> implements Exte
                     rootId = rootPage.getRecordId();
                     bTreeHeight += 1;
                     dirty = true;
+                    updateMetaRoot( this.rootId, this.bTreeHeight );
                 }
                 
                 if ( insert.existing == null )
@@ -414,7 +438,7 @@ public class BTree<K, V> implements Exte
        
         
         boolean abortedAction = false;
-        ActionContext context = this.beginAction( false );
+        ActionContext context = this.beginAction( false, "remove" );
 
         if ( !isActionCapable )
             bigLock.lock();
@@ -422,7 +446,7 @@ public class BTree<K, V> implements Exte
         try
         {
 
-            BPage<K, V> rootPage = getRoot( false );
+            BPage<K, V> rootPage = getRoot();
             
             if ( rootPage == null )
             {
@@ -449,6 +473,7 @@ public class BTree<K, V> implements Exte
                 {
                     rootId = rootPage.childBPage( pageSize - 1 ).getRecordId();
                 }
+                updateMetaRoot( this.rootId, this.bTreeHeight );
             }
             
             if ( remove.value != null )
@@ -599,33 +624,26 @@ public class BTree<K, V> implements Exte
     public TupleBrowser<K, V> browse() throws IOException
     {
         TupleBrowser<K, V> browser = null;
-        ActionContext context = this.beginAction( true ); 
-        boolean abortedAction = false;
+        ActionContext context = this.beginAction( true, "browse" ); 
         try
         {
-            BPage<K, V> rootPage = getRoot( true );
+            MetaRoot meta = this.getMetaRoot();
+            BPage<K, V> rootPage = this.getRoot( meta );
             
             if ( rootPage == null )
             {
                 this.endAction( context );
                 return new EmptyBrowser(){};
             }
-            browser = rootPage.findFirst();         
+            browser = rootPage.findFirst( context );         
         }
         catch( IOException e )
         {
-            abortedAction = true;
             this.abortAction( context );
             throw e;
         }
-        finally
-        {
-            if ( !abortedAction )
-            {
-                this.endAction( context );
-            }
-        }
         
+        this.unsetAsCurrentAction( context );
         return browser;
     }
 
@@ -645,11 +663,11 @@ public class BTree<K, V> implements Exte
     public TupleBrowser<K, V> browse( K key ) throws IOException
     {
         TupleBrowser<K, V> browser = null;
-        ActionContext context = this.beginAction( true );  
-        boolean abortedAction = false;
+        ActionContext context = this.beginAction( true, "browse key" );  
         try
         {
-            BPage<K, V> rootPage = getRoot( true );
+            MetaRoot meta = this.getMetaRoot();
+            BPage<K, V> rootPage = this.getRoot( meta );
             
             if ( rootPage == null )
             {
@@ -657,22 +675,15 @@ public class BTree<K, V> implements Exte
                 return new EmptyBrowser(){};
             }
           
-            browser  = rootPage.find( rootPage.btree.bTreeHeight, key);
+            browser  = rootPage.find( meta.treeHeight, key, context );
         }
         catch( IOException e )
         {
-            abortedAction = true;
             this.abortAction( context );
             throw e;
         }
-        finally
-        {
-            if ( !abortedAction )
-            {
-                this.endAction( context );
-            }
-        }
         
+        this.unsetAsCurrentAction( context );
         return browser;
     }
     
@@ -699,36 +710,54 @@ public class BTree<K, V> implements Exte
     /**
      * Return the root BPage<Object, Object>, or null if it doesn't exist.
      */
-    BPage<K, V> getRoot( boolean readOnlyAction ) throws IOException
-    {
-        BTree<K, V> bTreeCopy;
+    BPage<K, V> getRoot( ) throws IOException
+    {        
+        assert( this.rootId == metaRoot.rootID) : "Stale root id " + this.rootId + " "+ metaRoot.rootID;
         
-        if ( readOnlyAction )
+        if ( this.rootId == 0 )
         {
-            bTreeCopy = ( BTree<K, V> )recordManager.fetch( recordId );
-            bTreeCopy.comparator = this.comparator;
-            bTreeCopy.keySerializer = this.keySerializer;
-            bTreeCopy.valueSerializer = this.valueSerializer;
-            bTreeCopy.recordManager = this.recordManager;
-            bTreeCopy.recordId = this.recordId;
-            bTreeCopy.bpageSerializer = this.bpageSerializer;
-        }
-        else
-        {
-            bTreeCopy = this;
+            return null;
         }
         
-        if ( bTreeCopy.rootId == 0 )
+        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( this.rootId, bpageSerializer );
+        root.setRecordId( this.rootId );
+        root.btree = this;
+        
+        return root;
+    }
+    
+    BPage<K, V> getRoot( MetaRoot meta ) throws IOException
+    {        
+        if ( meta.rootID == 0 )
         {
             return null;
         }
         
-        BPage<K, V> root = ( BPage<K, V> ) recordManager.fetch( bTreeCopy.rootId, bpageSerializer );
-        root.setRecordId( bTreeCopy.rootId );
-        root.btree = bTreeCopy;
+        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
+     * @throws IOException
+     */
+    MetaRoot getMetaRoot() throws IOException
+    {
+        if ( isActionCapable )
+            return ( MetaRoot )recordManager.fetch( -this.recordId );
+        else
+            return metaRoot;
+    }
+    
+    
+    
+    
 
 
     /**
@@ -793,6 +822,7 @@ public class BTree<K, V> implements Exte
     }
     
     
+    
     void setAsCurrentAction( ActionContext context )
     {
         if ( context != null )
@@ -801,24 +831,23 @@ public class BTree<K, V> implements Exte
             ( ( ActionRecordManager )recordManager ).setCurrentActionContext( context );
         }
     }
-    
+
     void unsetAsCurrentAction( ActionContext context )
     {
         if ( context != null )
         {
             assert( isActionCapable == true );
-            ( ( ActionRecordManager )recordManager ).setCurrentActionContext( context );
+            ( ( ActionRecordManager )recordManager ).unsetCurrentActionContext( context );
         }
     }
+
     
-    
-    ActionContext beginAction( boolean readOnly )
+    ActionContext beginAction( boolean readOnly, String whoStarted )
     {
         ActionContext context = null;
         if ( isActionCapable )
         {
-            context = ( ( ActionRecordManager )recordManager ).beginAction( readOnly );
-            this.setAsCurrentAction( context );
+            context = ( ( ActionRecordManager )recordManager ).beginAction( readOnly, whoStarted );
         }
         return context;
     }
@@ -830,7 +859,6 @@ public class BTree<K, V> implements Exte
         {
             assert( isActionCapable );
             ( ( ActionRecordManager )recordManager ).endAction( context );
-            this.unsetAsCurrentAction( context );
         }
     }
     
@@ -839,9 +867,7 @@ public class BTree<K, V> implements Exte
         if ( context != null )
         {
             assert( isActionCapable );
-            this.abortAction( context );
             ( ( ActionRecordManager )recordManager ).abortAction( context );
-            this.unsetAsCurrentAction( context );
         }
 
     }
@@ -849,16 +875,36 @@ public class BTree<K, V> implements Exte
     
     BPage<K,V> copyOnWrite( BPage<K,V> page) throws IOException
     {
-        return page.copyOnWrite();
-    }
-   
+       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 ) 
+        
+        if ( this.valueSerializer != null )
         {
             array = this.valueSerializer.serialize( value );
             valueCopy = (V) this.valueSerializer.deserialize( array );
@@ -899,9 +945,9 @@ public class BTree<K, V> implements Exte
                 if ( in != null )
                     in.close();
             }
-        }
-        
-        return valueCopy;
+
+           }
+           return valueCopy;   
     }
     
     
@@ -952,4 +998,14 @@ public class BTree<K, V> implements Exte
 
         return sb.toString();
     }
+    
+    /**
+     * Used to poin 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/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/ActionContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/ActionContext.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/ActionContext.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/ActionContext.java Mon Aug 29 14:31:53 2011
@@ -8,13 +8,20 @@ package jdbm.helper;
 public class ActionContext
     {
 
+        /** track whether action is read only */ 
         boolean readOnly;
+        
+        /** Version associated with the context */
         ActionVersioning.Version version;
         
-        public void beginAction( boolean readOnly, ActionVersioning.Version version )
+        /** Who started the action. Usefule for debugging */
+        String whoStarted;
+        
+        public void beginAction( boolean readOnly, ActionVersioning.Version version, String whoStarted )
         {
             this.readOnly = readOnly;
             this.version = version;
+            this.whoStarted = whoStarted;
         }
         
         public void endAction()
@@ -43,6 +50,11 @@ public class ActionContext
         {
             return version;
         }
+        
+        public String getWhoStarted()
+        {
+            return whoStarted;
+        }
     
         
     }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/LRUCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/LRUCache.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/LRUCache.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/helper/LRUCache.java Mon Aug 29 14:31:53 2011
@@ -19,6 +19,13 @@ import java.util.concurrent.atomic.Atomi
 
 import java.io.IOException;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.tools.javac.util.Log;
+
+
+
 
 /**
  * This class implements a versioned lru cache. Entries in the cache are identified with a key. 
@@ -36,13 +43,11 @@ import java.io.IOException;
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
 
-/*
- * TODO handle cache eviction exception, abort of actions and closing of cache
- */
-
 public class LRUCache<K, V>
 {
-   
+    /** A logger for this class */
+    private static final Logger LOG = LoggerFactory.getLogger( LRUCache.class.getSimpleName() );
+       
     /** Array of hash buckets */
     private List<CacheEntry> buckets[];
     
@@ -59,7 +64,10 @@ public class LRUCache<K, V>
     private final static int NUM_LRUS = 16;
     
     /** Min number of entries */
-    private final static int MIN_ENTRIES = 1024;
+    private final static int MIN_ENTRIES = 1 << 10;
+    
+    /** Max sleep time(in ms) for writes in case of cache eviction failure */
+    private final static long MAX_WRITE_SLEEP_TIME = 10000;
     
     /** lru list */
     LRU lrus[];
@@ -143,14 +151,17 @@ public class LRUCache<K, V>
      * @param value new value of the entry
      * @param newVersion version of the new value
      * @param serializer used in case of IO
-     * @throws IOException
+     * @param neverReplace true if caller wants to always keep the entry in cache 
+     * @throws IOException, CacheEvictionException
      */
-    public void put( K key, V value, long newVersion , Serializer serializer ) throws IOException, CacheEvictionException
+    public void put( K key, V value, long newVersion , Serializer serializer, 
+        boolean neverReplace ) throws IOException, CacheEvictionException
     {
         int hashValue = hash(key);
         int hashIndex = ( hashValue & ( numBuckets - 1 ) );
         int latchIndex = ( hashIndex >> LOG_BUCKET_PER_LATCH );
-        boolean done = false;
+        long sleepInterval = 100; 
+        long totalSleepTime = 0;
         
         /*
          * Lock the hash bucket and find the current version of the entry: 
@@ -166,85 +177,117 @@ public class LRUCache<K, V>
          * While reading or waiting, latch is released.
          */
         
-        
-        latches[latchIndex].lock();
-        boolean entryExists = false;
-        
-        Iterator<CacheEntry> it = buckets[hashIndex].listIterator();
-        CacheEntry entry = null;
-        
-        while (it.hasNext() )
+        while ( true )
         {
-            entry = it.next();
-            if ( entry.getKey().equals( key ) )
+            latches[latchIndex].lock();
+            boolean entryExists = false;
+            boolean sleepForFreeEntry = false;
+            
+            Iterator<CacheEntry> it = buckets[hashIndex].listIterator();
+            CacheEntry entry = null;
+            
+            while (it.hasNext() )
             {
-                entryExists = true;
-                break;
+                entry = it.next();
+                if ( entry.getKey().equals( key ) )
+                {
+                    entryExists = true;
+                    break;
+                }
             }
-        }
-
-        try
-        {
-            if ( entryExists )
+    
+            try
             {
-                switch ( entry.getState() )
+                if ( entryExists )
                 {
-    
-                    case ENTRY_READY: // should be the common case
-                        
-                        if ( !entry.isCurrentVersion() )
-                        {
-                            CacheEntry newEntry = this.findNewEntry( key, latchIndex );
+                    switch ( entry.getState() )
+                    {
+        
+                        case ENTRY_READY: // should be the common case
                             
-                            /*
-                             * Remove existing entry, chain as a snapshot
-                             * entry to the new entry and add newentry to the
-                             * list.
-                             */
-                            buckets[hashIndex].remove( entry );
-                            newEntry.getVersionsLink().splice( entry.getVersionsLink() );
-                            buckets[hashIndex].add( newEntry );
-                            entry = newEntry;
+                            if ( !entry.isCurrentVersion() )
+                            {
+                                CacheEntry newEntry = this.findNewEntry( key, latchIndex );
+                                
+                                /*
+                                 * Remove existing entry, chain as a snapshot
+                                 * entry to the new entry and add newentry to the
+                                 * list.
+                                 */
+                                buckets[hashIndex].remove( entry );
+                                newEntry.getVersionsLink().splice( entry.getVersionsLink() );
+                                buckets[hashIndex].add( newEntry );
+                                entry = newEntry;
+                                this.doRead( entry, latches[latchIndex], serializer );
+                            }
+                            
+                            
+                            this.putNewVersion( entry, key, value, newVersion, hashIndex, 
+                                latches[latchIndex], serializer, neverReplace );                       
+                            break;
+                        case ENTRY_READING:
+                            // Somebody is reading our entry, wait until the read is done and then retry
+                            this.doWaitForStateChange( entry, latches[latchIndex] );
+                            if ( entry.getState() == EntryState.ENTRY_READY )
+                            {
+                                this.putNewVersion( entry, key, value, newVersion, hashIndex, latches[latchIndex], 
+                                    serializer, neverReplace );
+                                break;
+                            }
+                            
+                            LOG.warn( "Entry with key {} is at intial state after waiting for IO", entry.getKey() );
+                            // FALLTHROUGH
+                        case ENTRY_INITIAL:
+                            
+                            LOG.warn( "Entry with key {} is at intial while trying to read from it", entry.getKey() );
                             this.doRead( entry, latches[latchIndex], serializer );
-                        }
-                        
-                        
-                        this.putNewVersion( entry, key, value, newVersion, hashIndex, 
-                            latches[latchIndex], serializer );                       
-                        break;
-                    case ENTRY_READING:
-                        // Somebody is reading our entry, wait until the read is done and then retry
-                        this.doWaitForStateChange( entry, latches[latchIndex] );
-                        if ( entry.getState() == EntryState.ENTRY_READY )
-                        {
                             this.putNewVersion( entry, key, value, newVersion, hashIndex, latches[latchIndex], 
-                                serializer );
+                                serializer, neverReplace );
                             break;
-                        }
-                        // FALLTHROUGH
-                    case ENTRY_INITIAL:
-                        this.doRead( entry, latches[latchIndex], serializer );
-                        this.putNewVersion( entry, key, value, newVersion, hashIndex, latches[latchIndex], serializer );
-                        break;
-                    case ENTRY_WRITING:
-                        // FALLTHROUGH
-                    default:
-                        assert ( false );
+                        case ENTRY_WRITING:
+                            // FALLTHROUGH
+                        default:
+                            assert ( false );
+                    }
+        
                 }
-    
+                else
+                {
+                    entry = this.findNewEntry( key, latchIndex );
+                    buckets[hashIndex].add( entry );
+                    this.doRead( entry, latches[latchIndex], serializer );
+                    this.putNewVersion( entry, key, value, newVersion, hashIndex, latches[latchIndex], 
+                        serializer, neverReplace );
+                }            
             }
-            else
+            catch ( CacheEvictionException e )
             {
-                entry = this.findNewEntry( key, latchIndex );
-                buckets[hashIndex].add( entry );
-                this.doRead( entry, latches[latchIndex], serializer );
-                this.putNewVersion( entry, key, value, newVersion, hashIndex, latches[latchIndex], 
-                    serializer );
-            }            
-        }
-        finally
-        {
-            latches[latchIndex].unlock();
+                sleepForFreeEntry = totalSleepTime < this.MAX_WRITE_SLEEP_TIME;
+                
+                if ( sleepForFreeEntry == false )
+                    throw e;
+            }
+            finally
+            {
+                latches[latchIndex].unlock();
+            }
+            
+            if ( sleepForFreeEntry )
+            {
+                try
+                {
+                    Thread.sleep( sleepInterval );
+                }
+                catch ( InterruptedException e )
+                {
+                    // Restore interrupted stat
+                    Thread.currentThread().interrupt();
+                }
+                
+                totalSleepTime += sleepInterval;
+            }
+            else
+                break;
         }
     }
     
@@ -259,7 +302,7 @@ public class LRUCache<K, V>
      * @return value read
      * @throws IOException
      */
-    public V get( K key, long version, Serializer serializer ) throws IOException, CacheEvictionException
+    public V get( K key, long version, Serializer serializer ) throws IOException
     {
         int hashValue = hash(key);
         int hashIndex = ( hashValue & ( numBuckets - 1 ) );
@@ -337,13 +380,11 @@ public class LRUCache<K, V>
                             value = this.searchChainForVersion( entry, version );
                             break;
                         }
+                        LOG.warn( "Entry with key {} is at intial state after waiting for IO", entry.getKey() );
                         // FALLTHROUGH
                     case ENTRY_INITIAL:
                         
-                        // TODO remove this, this can happen when there is an io exception
-                        // with the thread that we waited for the IO.
-                        assert( false );
-                        
+                        LOG.warn( "Entry with key {} is at intial while trying to read from it", entry.getKey() );
                         this.doRead( entry, latches[latchIndex], serializer );
                         value = this.searchChainForVersion( entry, version );
                         break;                
@@ -360,6 +401,16 @@ public class LRUCache<K, V>
                 value = this.searchChainForVersion( entry, version );
             }
         }
+        catch ( CacheEvictionException e)
+        {
+            /*
+             * In this case read while holding the hash bucket lock. Entry
+             * wont be put into the cache but write to the same location will be
+             * blocked
+             */
+            return entryIO.read( key, serializer );
+            
+        }
         finally
         {
             latches[latchIndex].unlock();
@@ -379,10 +430,11 @@ public class LRUCache<K, V>
      * @param hashIndex hash bucket index which covers the enrtry 
      * @param latch lock covering the entry
      * @param serializer used in case of IO
+     * @param neverReplace true if most recent version of entry should be kept in memory all the time
      * @throws IOException
      */
     private void putNewVersion( CacheEntry entry, K key, V value, long newVersion, int hashIndex, 
-        Lock latch, Serializer serializer ) throws IOException
+        Lock latch, Serializer serializer, boolean neverReplace ) throws IOException, CacheEvictionException
     {
         if ( entry.getStartVersion() != newVersion  )
         {
@@ -411,6 +463,10 @@ public class LRUCache<K, V>
             entry.setAsCurrentVersion( value, newVersion );
         }
         
+        if ( neverReplace )
+            entry.setNeverReplace();
+
+        
         entry.setState( EntryState.ENTRY_WRITING );
         latch.unlock();
         
@@ -477,7 +533,7 @@ public class LRUCache<K, V>
                 continue;
             }
         
-            if ( curStartVersion != 0 && ( curEntry.getEndVersion() != curStartVersion ) )
+            if ( curStartVersion != 0 && ( curEntry.getEndVersion() > curStartVersion ) )
                 assert( false );
             
             curStartVersion = curEntry.getStartVersion();
@@ -592,8 +648,9 @@ public class LRUCache<K, V>
      * @param key identifier which we try to put into the cache 
      * @param latchIndex index of the currently held hash bucket lock 
      * @return
+     * @throws CacheEvictionException
      */
-    private CacheEntry findNewEntry( K key, int latchIndex )
+    private CacheEntry findNewEntry( K key, int latchIndex ) throws CacheEvictionException
     {
         LRU lru;
         int index = lruRandomizer.nextInt( NUM_LRUS );
@@ -664,7 +721,8 @@ public class LRUCache<K, V>
             victimEntry.initialize( key );
         else
         {
-            // TODO handle cache eviction failure.
+            LOG.warn( "Cache eviction failure: " + this.minReadVersion );
+            throw new CacheEvictionException( null );
         }
         
         return victimEntry;
@@ -725,6 +783,9 @@ public class LRUCache<K, V>
         /** id of lru this cache entry lives on */
         int lruid;
         
+        /** true if entry should not be replaced */
+        boolean neverReplace;
+        
         public CacheEntry(int lruid)
         {
             versionsLink = new ExplicitList.Link<CacheEntry>( this );
@@ -750,9 +811,15 @@ public class LRUCache<K, V>
             assert ( versionsLink.isUnLinked() == true );
             
             hashIndex = hash( key ) & ( numBuckets - 1 );
+            
+            assert( neverReplace == false );
         }
 
-
+        public void setNeverReplace()
+        {
+            neverReplace = true;
+        }
+        
         public K getKey()
         {
             return key;
@@ -870,6 +937,7 @@ public class LRUCache<K, V>
         public void setAsSnapshotVersion( long newEndVersion )
         {
             this.endVersion = newEndVersion;
+            neverReplace = false;
             LRU lru = this.getLru();
             lru.getLock().lock();
             lru.addToSnapshots( this );
@@ -879,7 +947,7 @@ public class LRUCache<K, V>
         public boolean isEntryFreeable()
         {
             return ( this.state != EntryState.ENTRY_READING && this.numWaiters == 0 && 
-                this.state != EntryState.ENTRY_WRITING );
+                this.state != EntryState.ENTRY_WRITING && !neverReplace);
         }
         
     }

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/recman/SnapshotRecordManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/recman/SnapshotRecordManager.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/recman/SnapshotRecordManager.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/main/java/jdbm/recman/SnapshotRecordManager.java Mon Aug 29 14:31:53 2011
@@ -69,8 +69,10 @@ public class SnapshotRecordManager imple
     
    
     
-         
-     public ActionContext beginAction( boolean readOnly )
+    /**
+     * {@inheritDoc}
+     */     
+     public ActionContext beginAction( boolean readOnly , String whoStarted )
      {
          ActionContext actionContext = new ActionContext();
          ActionVersioning.Version version;
@@ -85,16 +87,24 @@ public class SnapshotRecordManager imple
              version = versioning.beginWriteAction();
          }
          
-         actionContext.beginAction( readOnly, version );
+         actionContext.beginAction( readOnly, version, whoStarted );
+         this.setCurrentActionContext( actionContext );
          return actionContext;
      }
      
+     /**
+      * {@inheritDoc}
+      */
      public void setCurrentActionContext( ActionContext context )
      {
          ActionContext actionContext = actionContextVar.get();
+         assert( actionContext == null ) : "Action Context Not Null: " + actionContext.getWhoStarted();
          actionContextVar.set( context );
      }
      
+     /**
+      * {@inheritDoc}
+      */
      public void unsetCurrentActionContext( ActionContext context )
      {
          ActionContext actionContext = actionContextVar.get();
@@ -102,6 +112,9 @@ public class SnapshotRecordManager imple
          actionContextVar.set( null );
      }
      
+     /**
+      * {@inheritDoc}
+      */
      public void endAction( ActionContext actionContext )
      {
          ActionVersioning.Version minVersion = null;
@@ -122,13 +135,48 @@ public class SnapshotRecordManager imple
              assert( false );
          }
          
+         this.unsetCurrentActionContext( actionContext );
+         
          if ( minVersion != null )
              versionedCache.advanceMinReadVersion( minVersion.getVersion() );
      }
      
-     public void abortAction( ActionContext context )
+     /**
+      * {@inheritDoc}
+      */
+     public void abortAction( ActionContext actionContext )
      {
-         // TODO handle this
+         ActionVersioning.Version minVersion = null;
+         if ( actionContext.isReadOnlyAction() )
+         {
+             ActionVersioning.Version version = actionContext.getVersion(); 
+             minVersion = versioning.endReadAction( version );
+             actionContext.endAction();
+         }
+         else if ( actionContext.isWriteAction() )
+         {
+             /*
+              *  Do not let versioning know that write action is complete,
+              *  so that the readers wont see the effect of the aborted
+              *  txn. The sensible thing to do would be to have the underling
+              *  record manager expose a abort action interface. When that lacks.
+              *  the right thing for the upper layer to do would is to rollback whatever 
+              *  is part of what JDBM calls a txn.
+              */
+             
+             actionContext.endAction();
+             bigLock.unlock();
+         }
+         else
+         {
+             assert( false );
+         }
+         
+         this.unsetCurrentActionContext( actionContext );
+         
+         if ( minVersion != null )
+             versionedCache.advanceMinReadVersion( minVersion.getVersion() );
+
      }
      
          
@@ -171,10 +219,9 @@ public class SnapshotRecordManager imple
         ActionContext actionContext = actionContextVar.get();
         boolean startedAction = false;
         boolean abortedAction = false;
-        if ( actionContext.isWriteAction() == false )
+        if ( actionContext == null )
         {
-            actionContext = this.beginAction( false );
-            this.setCurrentActionContext( actionContext );
+            actionContext = this.beginAction( false, "insert missing action" );
             startedAction = true;
         }
         
@@ -184,7 +231,7 @@ public class SnapshotRecordManager imple
             recid = recordManager.insert( obj, serializer );
             
             versionedCache.put( new Long( recid ), obj, actionContext.getVersion().getVersion(),
-                serializer );
+                serializer, false );
         } 
         catch ( IOException e )
         {
@@ -227,10 +274,9 @@ public class SnapshotRecordManager imple
         ActionContext actionContext = actionContextVar.get();
         boolean startedAction = false;
         boolean abortedAction = false;
-        if ( actionContext.isWriteAction() == false )
+        if ( actionContext == null )
         {
-            actionContext = this.beginAction( false );
-            this.setCurrentActionContext( actionContext );
+            actionContext = this.beginAction( false, "delete missing action" );
             startedAction = true;
         }       
         
@@ -238,7 +284,7 @@ public class SnapshotRecordManager imple
         try 
         {
             versionedCache.put( new Long( recid ), null, actionContext.getVersion().getVersion(),
-                null );
+                null, false );
         }
         catch ( IOException e )
         {
@@ -294,17 +340,16 @@ public class SnapshotRecordManager imple
         ActionContext actionContext = actionContextVar.get();
         boolean startedAction = false;
         boolean abortedAction = false;
-        if ( actionContext.isWriteAction() == false )
+        if ( actionContext == null )
         {
-            actionContext = this.beginAction( false );
-            this.setCurrentActionContext( actionContext );
+            actionContext = this.beginAction( false, "update missing action" );
             startedAction = true;
         }
 
         try 
         {
            versionedCache.put( new Long( recid ), obj, actionContext.getVersion().getVersion(),
-               serializer );       
+               serializer, recid < 0 );       
         }
         catch ( IOException e )
         {
@@ -361,10 +406,9 @@ public class SnapshotRecordManager imple
         
         boolean startedAction = false;
         boolean abortedAction = false;
-        if ( actionContext.isActive() == false )
+        if ( actionContext == null )
         {
-            actionContext = this.beginAction( false );
-            this.setCurrentActionContext( actionContext );
+            actionContext = this.beginAction( false, "fetch missing action" );
             startedAction = true;
         }
         
@@ -382,15 +426,6 @@ public class SnapshotRecordManager imple
             }
             throw e;
         }
-        catch ( CacheEvictionException except ) 
-        {
-            if ( startedAction )
-            {
-                this.abortAction( actionContext );
-                abortedAction = true;
-            }
-            throw new IOException( except.getLocalizedMessage() );
-        }       
         finally
         {
             if ( startedAction && !abortedAction )
@@ -410,7 +445,7 @@ public class SnapshotRecordManager imple
     {
         checkIfClosed();
 
-        // TODO quiesce all actions
+        // Maybe quiesce all actions ..( not really required)
         recordManager.close();
         recordManager = null;
         versionedCache = null;
@@ -558,11 +593,18 @@ public class SnapshotRecordManager imple
     {
         public Object read( Long key, Serializer serializer) throws IOException
         {
+            // Meta objects are kept in memory only
+            if ( key < 0 )
+                return null;
+            
             return recordManager.fetch( key.longValue(), serializer );
         }
         
         public void write( Long key, Object value, Serializer serializer ) throws IOException
         {
+            if ( key < 0 )
+                return;
+            
             if ( value != null )
             {
                 recordManager.update( key.longValue(), value , serializer );

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/btree/SnapshotBTree.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/btree/SnapshotBTree.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/btree/SnapshotBTree.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/btree/SnapshotBTree.java Mon Aug 29 14:31:53 2011
@@ -3,7 +3,16 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 
 import jdbm.RecordManager;
 import jdbm.RecordManagerFactory;
@@ -31,6 +40,15 @@ public class SnapshotBTree
 {
     public TemporaryFolder folder = new TemporaryFolder();
     
+    private static class IntWrapper implements Serializable
+    {
+        int value;
+        IntWrapper( int value )
+        {
+            this.value = value;
+        }
+    }
+    
     private String getTemporaryFile( String name ) throws IOException
     {
         String file = folder.newFile( name ).getAbsolutePath();
@@ -41,7 +59,7 @@ public class SnapshotBTree
     public void testBasic1() throws IOException, InterruptedException
     {
         RecordManager recman;
-        BTree<Integer, String> tree;
+        BTree<Integer, IntWrapper> tree;
       
         int idx;
         int numReadThreads = 1;
@@ -54,11 +72,11 @@ public class SnapshotBTree
         recman = RecordManagerFactory.createRecordManager( getTemporaryFile( "testBasic1" ) );
         SnapshotRecordManager snapshotRecman = new SnapshotRecordManager( recman, 1 << 12 );
         
-        tree = new BTree<Integer, String>( snapshotRecman, new IntegerComparator() );
+        tree = new BTree<Integer, IntWrapper>( snapshotRecman, new IntegerComparator() );
      
         for ( idx = 0; idx < 1024; idx++ )
         {
-            tree.insert( new Integer( idx ), "value" + idx, true );
+            tree.insert( new Integer( idx ), new IntWrapper( idx ), true );
         }
 
         for ( idx = 0; idx < numReadThreads; idx++ )
@@ -87,12 +105,12 @@ public class SnapshotBTree
     class TestThread extends Thread
     {
         boolean readOnly;
-        BTree<Integer, String> btree;
+        BTree<Integer, IntWrapper> btree;
         Semaphore browseSem;
         Semaphore updateSem;
         int numReadThreads;
 
-        TestThread( boolean readOnly, BTree<Integer, String> btree, Semaphore firstBrowse,
+        TestThread( boolean readOnly, BTree<Integer, IntWrapper> btree, Semaphore firstBrowse,
                     Semaphore updateDone, int numReadThreads)
         {
             this.readOnly = readOnly;
@@ -108,108 +126,94 @@ public class SnapshotBTree
         {
             int count = 0;
             int idx;
-            boolean sawXXX = false;
-            
-            TupleBrowser<Integer, String> browser = btree.browse();
-            Tuple<Integer, String> tuple = new Tuple();
+            TupleBrowser<Integer, IntWrapper> browser = btree.browse();
+            Tuple<Integer, IntWrapper> tuple = new Tuple();
             browseSem.release();
-            
+
             assertTrue( browser.getNext( tuple ) );
             assertEquals( tuple.getKey().intValue(), 0 );
             count++;
-            
+
             assertTrue( browser.getNext( tuple ) );
             assertEquals( tuple.getKey().intValue(), 1 );
             count++;
-            
+
             while( browser.getNext( tuple ) )
             {
                 count++;
-                
-                // Sleep a little randomly.
+
+                // Sleep a little randomly.                                                                                                                                                               
                 if ( (count & 7) == 0 )
                     Thread.sleep( 1 );
-                
-                if ( !sawXXX && tuple.getValue().equals( "xxx" ) )
-                    sawXXX = true;
-                
-                if ( sawXXX )
-                {
-                    assertTrue( tuple.getValue().equals( "xxx" ) );
-                }
-                else
-                {
-                    assertTrue( tuple.getValue().equals( "value" + tuple.getKey().intValue() ) );
-                }                    
+
+                assertTrue( tuple.getValue().value != -1 );
             }
-            
-            
+
+
             System.out.println( "count is " + count );
-            assertTrue( count <= 2048 );            
+            assertEquals( count, 1024 );
             browser.close();
-            
+
             updateSem.acquireUninterruptibly();
             browser = btree.browse( new Integer( 10 ) );
-            assertTrue( browser.getNext( tuple ) );
-            assertEquals( tuple.getKey().intValue(), 20 );
-            browser = btree.browse( new Integer( 2047 ) );
-            assertTrue( browser.getNext( tuple ) );
-            assertTrue( tuple.getValue().equals("xxx") );
-            boolean sawNonXXX = false;
-            browseSem.release();
 
-            while ( browser.getPrevious( tuple ) )
+            browseSem.release();
+            for ( idx = 20; idx < 1024; idx++ )
             {
-                
-                if ( !sawNonXXX && !tuple.getValue().equals( "xxx" ) )
-                    sawNonXXX = true;
-                
-                if ( sawNonXXX )
-                {
-                    assertTrue( tuple.getValue().equals( "value" + tuple.getKey().intValue() ) );
-                }
-                else 
-                {
-                    assertTrue( tuple.getValue().equals( "xxx") );
-                }
+                assertTrue( browser.getNext( tuple ) );
+
+                System.out.println( "key:"+ tuple.getKey().intValue() + " idx:" + idx );
+                assertTrue( tuple.getKey().intValue() == idx );
             }
             browser.close();
-            
         }
         
         private void readWriteActions() throws IOException
         {
             int idx;
-            
+
             for ( idx = 0; idx < numReadThreads; idx++ )
                 browseSem.acquireUninterruptibly();
+
             
-            for ( idx = 512; idx < 1024; idx++ )
-            {
-                btree.insert( new Integer( idx ), "xxx", true );
-            }
+            Integer key = new Integer( 1023 );
+            IntWrapper value = btree.find( key );
+            value.value = -1;
+            btree.insert( key, value, true );
+            
+            key = new Integer(512);
+            value = btree.find( key );
+            value.value = -1;
             
+            btree.insert( key, value , true );
             for ( idx = 1024; idx < 2048; idx++ )
             {
-                btree.insert( new Integer( idx ), "xxx", true );
+                btree.insert( new Integer( idx ), new IntWrapper( idx ), true );
             }
-           
+
+            key = new Integer(1);
+            value = btree.find( key );
+            value.value = -1;
+            
+            btree.insert( key, value , true );
+            btree.insert( new Integer(1024), new IntWrapper( -1 ), true );
             for ( idx = 10; idx < 20; idx++ )
             {
                 btree.remove( new Integer( idx ) );
             }
-            
+
             updateSem.release();
-            
+
             for ( idx = 0; idx < numReadThreads; idx++ )
                 browseSem.acquireUninterruptibly();
-            
+
             for ( idx = 0; idx < 10; idx++ )
                 btree.remove( new Integer( idx ) );
-            
+
             for ( idx = 20; idx < 1024; idx++ )
                 btree.remove( new Integer( idx ) );
-            
+
+
         }
 
 

Modified: directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/helper/TestVersionedCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/helper/TestVersionedCache.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/helper/TestVersionedCache.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/jdbm/src/test/java/jdbm/helper/TestVersionedCache.java Mon Aug 29 14:31:53 2011
@@ -41,9 +41,9 @@ public class TestVersionedCache
         val = cache.get( new Integer ( 20 ), 0, null );
         assertEquals( val.intValue(), 1 );
         
-        cache.put( new Integer(1), 2, 1, null );
-        cache.put( new Integer(5), 2, 1, null );
-        cache.put( new Integer(30), 2, 1, null );
+        cache.put( new Integer(1), 2, 1, null, false );
+        cache.put( new Integer(5), 2, 1, null, false );
+        cache.put( new Integer(30), 2, 1, null, false );
         
         int sum = 0;
         for ( idx = 0; idx < numEntries; idx++ )
@@ -209,13 +209,13 @@ public class TestVersionedCache
                 
                 for ( idx = 0; idx <= intsArray.length; idx = idx + 100)
                 {
-                    cache.put( new Integer( idx ), 2, 1, null );
+                    cache.put( new Integer( idx ), 2, 1, null, false );
                     expectedSum = expectedSum + 1;
                 }
                 
                 for ( idx = 0; idx <= intsArray.length; idx = idx + 100)
                 {
-                    cache.put( new Integer( idx ), 3, 2, null );
+                    cache.put( new Integer( idx ), 3, 2, null, false );
                     expectedSum = expectedSum + 1;
                 }
                 

Modified: directory/apacheds/branches/apacheds-jdbm/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-jdbm/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java?rev=1162833&r1=1162832&r2=1162833&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-jdbm/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java (original)
+++ directory/apacheds/branches/apacheds-jdbm/server-integ/src/test/java/org/apache/directory/server/operations/extended/StoredProcedureIT.java Mon Aug 29 14:31:53 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
     {



Mime
View raw message