Author: sandymac
Date: Tue Apr 18 20:04:31 2006
New Revision: 395115

URL: http://svn.apache.org/viewcvs?rev=395115&view=rev
Log:
Fixes some bugs from the initial refactor to reduce synchronization and
implements the "generator" pattern for growing the pool when more objects
are needed as suggested by Peter Steijn.
Also includes the BaseObjectPool.close fixes from the trunk.

Modified:
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFullSync.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailLimitManager.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/SoftReferenceObjectPool.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackObjectPool.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java
    
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java
 Tue Apr 18 20:04:31 2006
@@ -286,7 +286,7 @@
         }
     }
 
-    protected boolean returnObjectToPool(Object obj) {
+    protected boolean returnObjectToPool(final Object obj) {
         // if the pool is closed, don't return objects
         if (isOpen()) {
             tracker.returned(obj);
@@ -296,6 +296,10 @@
         return false;
     }
 
+    protected void returnObjectToPoolManager(final Object obj) {
+        manager.returnToPool(obj);
+    }
+
     /**
      * Invalidates an object from the pool
      * By contract, <code>obj</code> <strong>must</strong> have been obtained
@@ -431,17 +435,13 @@
             sb.append(", validateOnReturn=").append(validateOnReturn);
         }
         sb.append(", open=").append(open);
-        try {
-            final int numActive = getNumActive();
+        final int numActive = getNumActive();
+        if (numActive >= 0) {
             sb.append(", activeObjects=").append(numActive);
-        } catch (Exception e) {
-            // ignored
         }
-        try {
-            final int numIdle = getNumIdle();
+        final int numIdle = getNumIdle();
+        if (numIdle >= 0) {
             sb.append(", idleObjects=").append(numIdle);
-        } catch (Exception e) {
-            // ignored
         }
         sb.append('}');
         return sb.toString();

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java
 Tue Apr 18 20:04:31 2006
@@ -256,8 +256,8 @@
         }
     }
 
-    private static boolean needsFullSync(FactoryConfig config) {
-        return LimitPolicy.WAIT.equals(config.limitPolicy);
+    private static boolean needsFullSync(final FactoryConfig config) {
+        return config.maxActive > 0 && 
LimitPolicy.WAIT.equals(config.limitPolicy);
     }
 
     /**
@@ -794,9 +794,11 @@
             sb.append("factory=").append(factory);
             sb.append(", borrowPolicy=").append(borrowPolicy);
             sb.append(", exhaustionPolicy=").append(exhaustionPolicy);
-            sb.append(", maxIdle=").append(maxIdle);
-            sb.append(", maxActive=").append(maxActive);
+            if (maxIdle >= 0) {
+                sb.append(", maxIdle=").append(maxIdle);
+            }
             if (maxActive > 0) {
+                sb.append(", maxActive=").append(maxActive);
                 sb.append(", limitPolicy=").append(limitPolicy);
                 if (LimitPolicy.WAIT.equals(limitPolicy)) {
                     sb.append(", maxWaitMillis=").append(maxWaitMillis);

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFullSync.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFullSync.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFullSync.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFullSync.java
 Tue Apr 18 20:04:31 2006
@@ -80,4 +80,10 @@
         }
         return false;
     }
+
+    protected void returnObjectToPoolManager(final Object obj) {
+        synchronized (getPool()) {
+            getManager().returnToPool(obj);
+        }
+    }
 }

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailLimitManager.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailLimitManager.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailLimitManager.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailLimitManager.java
 Tue Apr 18 20:04:31 2006
@@ -52,10 +52,11 @@
      * @throws Exception usually from [EMAIL PROTECTED] PoolableObjectFactory} 
methods.
      */
     public Object nextFromPool() throws NoSuchElementException, Exception {
-        if (objectPool.getNumActive() < getMaxActive()) {
+        final int numActive = objectPool.getNumActive();
+        if (numActive < getMaxActive()) {
             return super.nextFromPool();
         } else {
-            throw new NoSuchElementException("No more than " + getMaxActive() 
+ " objects allowed from this pool. Currently " + objectPool.getNumActive() + " 
have been borrowed.");
+            throw new NoSuchElementException("No more than " + getMaxActive() 
+ " objects allowed from this pool. Currently " + numActive + " have been 
borrowed.");
         }
     }
 

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java
 Tue Apr 18 20:04:31 2006
@@ -20,6 +20,8 @@
 
 import java.io.Serializable;
 import java.util.List;
+import java.util.TimerTask;
+import java.util.Timer;
 
 /**
  * Grows the pool automatically when it is exhausted.
@@ -35,6 +37,8 @@
 
     private static final long serialVersionUID = 1225746308358794900L;
 
+    private static final Timer GENERATOR_TIMER = 
CompositeObjectPool.COMPOSITE_TIMER;
+
     /**
      * Retreives the next object from the pool, creating new objects if the 
pool has been exhausted.
      *
@@ -46,13 +50,14 @@
         Object obj = null;
 
         // Drain until good or empty
-        boolean tryAgain = true;
-        while (tryAgain && obj == null) {
+        Generator generator = null;
+        while (obj == null) {
             synchronized (pool) {
                 if (objectPool.getLender().size() > 0) {
                     obj = objectPool.getLender().borrow();
-                } else {
-                    tryAgain = false;
+                    if (generator != null) {
+                        generator.cancel();
+                    }
                 }
             }
 
@@ -68,13 +73,98 @@
                     deferDestroyObject(obj);
                     obj = null; // try again
                 }
+            } else {
+                if (generator == null) {
+                    generator = new Generator();
+                    GENERATOR_TIMER.schedule(generator, 0L);
+                }
+                synchronized (pool) {
+                    pool.wait(10L);
+                    obj = generator.getObj();
+                }
             }
         }
-        if (obj == null) {
-            obj = objectPool.getFactory().makeObject();
+        if (generator != null) {
+            generator.cancel();
         }
-
         return obj;
+    }
+
+    private class Generator extends TimerTask {
+        private boolean returnToThread = true;
+        private volatile boolean done = false;
+        private volatile Object obj;
+        private Throwable throwable;
+
+        private final Object key;
+        private final ThreadLocal keys;
+
+        Generator() {
+            final CompositeKeyedObjectPool ockop = 
objectPool.getOwningCompositeKeyedObjectPool();
+            if (ockop != null) {
+                keys = ockop.getKeys();
+                key = keys.get();
+            } else {
+                keys = null;
+                key = null;
+            }
+        }
+
+        public void run() {
+            try {
+                if (keys != null) {
+                    keys.set(key);
+                }
+                final Object obj;
+                try {
+                    obj = objectPool.getFactory().makeObject();
+                } catch (Throwable t) {
+                    throwable = t;
+                    return;
+                }
+                final List pool = objectPool.getPool();
+                synchronized (pool) {
+                    done = true;
+                    if (returnToThread) {
+                        this.obj = obj;
+                        pool.notifyAll();
+                    } else {
+                        try {
+                            objectPool.getFactory().passivateObject(obj);
+                        } catch (Throwable t) {
+                            throwable = t;
+                            return;
+                        }
+                        objectPool.returnObjectToPoolManager(obj);
+                    }
+                }
+            } finally {
+                if (keys != null) {
+                    keys.set(null);
+                }
+            }
+        }
+
+        public boolean cancel() {
+            synchronized (objectPool.getPool()) {
+                returnToThread = false;
+            }
+            return super.cancel();
+        }
+
+        public Object getObj() throws Exception {
+            assert Thread.holdsLock(objectPool.getPool());
+            if (throwable != null) {
+                if (throwable instanceof Exception) {
+                    throw (Exception)throwable;
+                } else if (throwable instanceof Error) {
+                    throw (Error)throwable;
+                } else {
+                    throw new Exception(throwable);
+                }
+            }
+            return obj;
+        }
     }
 
     /**

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
 Tue Apr 18 20:04:31 2006
@@ -1160,13 +1160,15 @@
         }
     }
 
-    public synchronized void close() throws Exception {
-        clear();
-        if (null != _evictor) {
-            _evictor.cancel();
-            _evictor = null;
-        }
+    public void close() throws Exception {
         super.close();
+        synchronized (this) {
+            clear();
+            if (null != _evictor) {
+                _evictor.cancel();
+                _evictor = null;
+            }
+        }
     }
 
     public synchronized void setFactory(KeyedPoolableObjectFactory factory) 
throws IllegalStateException {

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/SoftReferenceObjectPool.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/SoftReferenceObjectPool.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/SoftReferenceObjectPool.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/SoftReferenceObjectPool.java
 Tue Apr 18 20:04:31 2006
@@ -234,9 +234,9 @@
         pruneClearedReferences();
     }
 
-    public synchronized void close() throws Exception {
-        clear();
+    public void close() throws Exception {
         super.close();
+        clear();
     }
 
     /**

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackKeyedObjectPool.java
 Tue Apr 18 20:04:31 2006
@@ -401,9 +401,9 @@
      *
      * @throws Exception <strong>deprecated</strong>: implementations should 
silently fail if not all resources can be freed.
      */
-    public synchronized void close() throws Exception {
-        clear();
+    public void close() throws Exception {
         super.close();
+        clear();
     }
 
     /**

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackObjectPool.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackObjectPool.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackObjectPool.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/impl/StackObjectPool.java
 Tue Apr 18 20:04:31 2006
@@ -274,9 +274,9 @@
      *
      * @throws Exception <strong>deprecated</strong>: implementations should 
silently fail if not all resources can be freed.
      */
-    public synchronized void close() throws Exception {
-        clear();
+    public void close() throws Exception {
         super.close();
+        clear();
     }
 
     /**

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java
 Tue Apr 18 20:04:31 2006
@@ -105,8 +105,12 @@
         }
         final List expectedMethods = new ArrayList();
 
+        assertEquals(0, pool.getNumActive());
+        assertEquals(0, pool.getNumIdle());
         // addObject should make a new object, pasivate it and put it in the 
pool
         pool.addObject();
+        assertEquals(0, pool.getNumActive());
+        assertEquals(1, pool.getNumIdle());
         expectedMethods.add(new MethodCall("makeObject").returned(ZERO));
         expectedMethods.add(new MethodCall("passivateObject", ZERO));
         assertEquals(expectedMethods, factory.getMethodCalls());

Modified: 
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java?rev=395115&r1=395114&r2=395115&view=diff
==============================================================================
--- 
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java
 (original)
+++ 
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java
 Tue Apr 18 20:04:31 2006
@@ -297,8 +297,8 @@
             try {
                 System.out.print("GenericObjectPool\t" + ccg + "\t");
                 objectPool = ccg.getGeneric();
-                //objectPool = ccg.getGenerator();
                 gopBPS = runThreadedTest(objectPool, numThreads, seconds);
+                System.out.println(objectPool);
             } catch (Exception e) {
                 System.out.println("exception thrown! " + e.getMessage());
             }
@@ -310,6 +310,7 @@
                 System.out.print("CompositeObjectPool\t" + ccg + "\t");
                 objectPool = ccg.getComposite();
                 copBPS = runThreadedTest(objectPool, numThreads, seconds);
+                System.out.println(objectPool);
             } catch (Exception e) {
                 System.out.println("exception thrown! " + e.getMessage());
             }
@@ -476,7 +477,8 @@
 
             compositeFactory.setBorrowPolicy(BorrowPolicy.FIFO);
             compositeFactory.setExhaustionPolicy(ExhaustionPolicy.GROW);
-            compositeFactory.setLimitPolicy(LimitPolicy.FAIL);
+            //compositeFactory.setLimitPolicy(LimitPolicy.FAIL);
+            compositeFactory.setLimitPolicy(LimitPolicy.WAIT);
             compositeFactory.setTrackingPolicy(TrackingPolicy.SIMPLE);
 
             genericConfig.minIdle = 0;
@@ -538,7 +540,7 @@
 
         public Object makeObject() throws Exception {
             long end = System.currentTimeMillis() + 30;
-            Thread.sleep(5);
+            Thread.sleep(5); // fake some IO wait
             while (end > System.currentTimeMillis()) {
                 Math.random();
             }
@@ -548,6 +550,11 @@
         public boolean validateObject(final Object obj) {
             final Integer num = (Integer)obj;
             long end = System.currentTimeMillis() + 5;
+            try {
+                Thread.sleep(1); // fake some IO wait
+            } catch (InterruptedException e) {
+                // ignored
+            }
             while (end > System.currentTimeMillis()) {
                 Math.random();
             }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to