Author: markt
Date: Thu Mar 24 11:32:21 2011
New Revision: 1084905

URL: http://svn.apache.org/viewvc?rev=1084905&view=rev
Log:
Additional fixes for POOL-180. Ensure the evictor tracks internal processing 
counts per key and remove unused keys only when they are truly unused.

Modified:
    
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
    
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java

Modified: 
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=1084905&r1=1084904&r2=1084905&view=diff
==============================================================================
--- 
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
 (original)
+++ 
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
 Thu Mar 24 11:32:21 2011
@@ -1568,6 +1568,12 @@ public class GenericKeyedObjectPool exte
                 if (pool != null) {
                     synchronized(this) {
                         pool.decrementActiveCount();
+                        if (pool.queue.isEmpty() &&
+                                pool.activeCount == 0 &&
+                                pool.internalProcessingCount == 0) {
+                            _poolMap.remove(key);
+                            _poolList.remove(key);
+                        }
                         allocate();
                     }
                 }
@@ -1649,6 +1655,12 @@ public class GenericKeyedObjectPool exte
             if (decrementNumActive) {
                 synchronized(this) {
                     pool.decrementActiveCount();
+                    if (pool.queue.isEmpty() &&
+                            pool.activeCount == 0 &&
+                            pool.internalProcessingCount == 0) {
+                        _poolMap.remove(key);
+                        _poolList.remove(key);
+                    }
                     allocate();
                 }
             }
@@ -1909,8 +1921,9 @@ public class GenericKeyedObjectPool exte
                         (ObjectTimestampPair) _evictionCursor.previous() :
                         (ObjectTimestampPair) _evictionCursor.next();
                 _evictionCursor.remove();
+                ObjectQueue objectQueue = (ObjectQueue) _poolMap.get(key);
+                objectQueue.incrementInternalProcessingCount();
                 _totalIdle--;
-                _totalInternalProcessing++;
             }
 
             boolean removeObject=false;
@@ -1945,28 +1958,20 @@ public class GenericKeyedObjectPool exte
                     _factory.destroyObject(key, pair.value);
                 } catch(Exception e) {
                     // ignored
-                } finally {
-                    // Do not remove the key from the _poolList or _poolmap,
-                    // even if the list stored in the _poolMap for this key is
-                    // empty when minIdle > 0.
-                    //
-                    // Otherwise if it was the last object for that key,
-                    // drop that pool
-                    if (_minIdle == 0) {
-                        synchronized (this) {
-                            ObjectQueue objectQueue =
-                                (ObjectQueue)_poolMap.get(key);
-                            if (objectQueue != null &&
-                                    objectQueue.queue.isEmpty()) {
-                                _poolMap.remove(key);
-                                _poolList.remove(key);
-                            }
-                        }
-                    }
                 }
             }
             synchronized (this) {
-                if (!removeObject) {
+                ObjectQueue objectQueue =
+                    (ObjectQueue)_poolMap.get(key);
+                objectQueue.decrementInternalProcessingCount();
+                if (removeObject) {
+                    if (objectQueue.queue.isEmpty() &&
+                            objectQueue.activeCount == 0 &&
+                            objectQueue.internalProcessingCount == 0) {
+                        _poolMap.remove(key);
+                        _poolList.remove(key);
+                    }
+                } else {
                     _evictionCursor.add(pair);
                     _totalIdle++;
                     if (_lifo) {
@@ -1974,7 +1979,6 @@ public class GenericKeyedObjectPool exte
                         _evictionCursor.previous();
                     }
                 }
-                _totalInternalProcessing--;
             }
         }
         allocate();

Modified: 
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java?rev=1084905&r1=1084904&r2=1084905&view=diff
==============================================================================
--- 
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
 (original)
+++ 
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
 Thu Mar 24 11:32:21 2011
@@ -725,35 +725,42 @@ public class TestGenericKeyedObjectPool 
         
         pool.evict(); // Kill (0,0),(0,1)
         assertEquals(3, pool.getNumIdle(zero));
-        Object obj = pool.borrowObject(zero);
-        assertTrue(lifo ? obj.equals("04") : obj.equals("02"));
+        Object objZeroA = pool.borrowObject(zero);
+        assertTrue(lifo ? objZeroA.equals("04") : objZeroA.equals("02"));
         assertEquals(2, pool.getNumIdle(zero));
-        obj = pool.borrowObject(zero);
-        assertTrue(obj.equals("03"));
+        Object objZeroB = pool.borrowObject(zero);
+        assertTrue(objZeroB.equals("03"));
         assertEquals(1, pool.getNumIdle(zero));
         
         pool.evict(); // Kill remaining 0 survivor and (1,5)
         assertEquals(0, pool.getNumIdle(zero));
         assertEquals(4, pool.getNumIdle(one));
-        obj = pool.borrowObject(one);
-        assertTrue(lifo ? obj.equals("19") : obj.equals("16"));
+        Object objOneA = pool.borrowObject(one);
+        assertTrue(lifo ? objOneA.equals("19") : objOneA.equals("16"));
         assertEquals(3, pool.getNumIdle(one));
-        obj = pool.borrowObject(one);
-        assertTrue(lifo ? obj.equals("18") : obj.equals("17"));
+        Object objOneB = pool.borrowObject(one);
+        assertTrue(lifo ? objOneB.equals("18") : objOneB.equals("17"));
         assertEquals(2, pool.getNumIdle(one));
         
         pool.evict(); // Kill remaining 1 survivors
         assertEquals(0, pool.getNumIdle(one));
         pool.evict(); // Kill (2,10), (2,11)
         assertEquals(3, pool.getNumIdle(two));
-        obj = pool.borrowObject(two);
-        assertTrue(lifo ? obj.equals("214") : obj.equals("212"));
+        Object objTwoA = pool.borrowObject(two);
+        assertTrue(lifo ? objTwoA.equals("214") : objTwoA.equals("212"));
         assertEquals(2, pool.getNumIdle(two));
         pool.evict(); // All dead now
         assertEquals(0, pool.getNumIdle(two));  
         
         pool.evict(); // Should do nothing - make sure no exception
-        pool.evict();
+        // Currently 2 zero, 2 one and 1 two active. Return them
+        pool.returnObject(zero, objZeroA);
+        pool.returnObject(zero, objZeroB);
+        pool.returnObject(one, objOneA);
+        pool.returnObject(one, objOneB);
+        pool.returnObject(two, objTwoA);
+        // Remove all idle objects
+        pool.clear();
         
         // Reload
         pool.setMinEvictableIdleTimeMillis(500);
@@ -794,8 +801,12 @@ public class TestGenericKeyedObjectPool 
         pool.evict(); // kill (1,6), (1,7) - (1,5) missed
         assertEquals(3, pool.getNumIdle(one));
         assertEquals(5, pool.getNumIdle(two));
-        obj = pool.borrowObject(one);
-        assertTrue(lifo ? obj.equals("19") : obj.equals("15"));  
+        Object obj = pool.borrowObject(one);
+        if (lifo) {
+            assertEquals("19", obj);
+        } else {
+            assertEquals("15", obj);
+        }
     }
     
     


Reply via email to