You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rd...@apache.org on 2005/11/10 22:43:10 UTC

svn commit: r332380 - /jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java

Author: rdonkin
Date: Thu Nov 10 13:43:07 2005
New Revision: 332380

URL: http://svn.apache.org/viewcvs?rev=332380&view=rev
Log:
Break dependency from GenericObjectKeyedPool to commons-collections. Submitted by Sandy McArthur. Issue #37431.

Modified:
    jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java

Modified: jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=332380&r1=332379&r2=332380&view=diff
==============================================================================
--- jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java (original)
+++ jakarta/commons/proper/pool/trunk/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java Thu Nov 10 13:43:07 2005
@@ -23,8 +23,9 @@
 import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.LinkedList;
+import java.util.HashSet;
 
-import org.apache.commons.collections.CursorableLinkedList;
 import org.apache.commons.pool.BaseKeyedObjectPool;
 import org.apache.commons.pool.KeyedObjectPool;
 import org.apache.commons.pool.KeyedPoolableObjectFactory;
@@ -426,7 +427,6 @@
 
         _poolMap = new HashMap();
         _activeMap = new HashMap();
-        _poolList = new CursorableLinkedList();
 
         startEvictor(_timeBetweenEvictionRunsMillis);
     }
@@ -766,11 +766,10 @@
         long starttime = System.currentTimeMillis();
         boolean newlyCreated = false;
         for(;;) {
-            CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.get(key));
+            LinkedList pool = (LinkedList)(_poolMap.get(key));
             if(null == pool) {
-                pool = new CursorableLinkedList();
+                pool = new LinkedList();
                 _poolMap.put(key,pool);
-                _poolList.add(key);
             }
             ObjectTimestampPair pair = null;
             // if there are any sleeping, just grab one of those
@@ -847,9 +846,9 @@
     }
 
     public synchronized void clear() {
-        for(Iterator keyiter = _poolList.iterator(); keyiter.hasNext(); ) {
+        for(Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext(); ) {
             Object key = keyiter.next();
-            CursorableLinkedList list = (CursorableLinkedList)(_poolMap.get(key));
+            final LinkedList list = (LinkedList)(_poolMap.get(key));
             for(Iterator it = list.iterator(); it.hasNext(); ) {
                 try {
                     _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
@@ -860,7 +859,9 @@
             }
         }
         _poolMap.clear();
-        _poolList.clear();
+        if (_recentlyEvictedKeys != null) {
+            _recentlyEvictedKeys.clear();
+        }
         _totalIdle = 0;
         notifyAll();
     }
@@ -872,9 +873,9 @@
     public synchronized void clearOldest() {
         // build sorted map of idle objects
         TreeMap map = new TreeMap();
-        for (Iterator keyiter = _poolList.iterator(); keyiter.hasNext();) {
+        for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
             Object key = keyiter.next();
-            CursorableLinkedList list = (CursorableLinkedList) _poolMap.get(key);
+            LinkedList list = (LinkedList) _poolMap.get(key);
             for (Iterator it = list.iterator(); it.hasNext();) {
                 // each item into the map uses the objectimestamppair object
                 // as the key.  It then gets sorted based on the timstamp field
@@ -896,7 +897,7 @@
             // key references is the key of the list it belongs to.
             Object key = entry.getValue();
             ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
-            CursorableLinkedList list = (CursorableLinkedList) _poolMap.get(key);
+            LinkedList list = (LinkedList) _poolMap.get(key);
             list.remove(pairTimeStamp);
 
             try {
@@ -907,7 +908,6 @@
             // if that was the last object for that key, drop that pool
             if (list.isEmpty()) {
                 _poolMap.remove(key);
-                _poolList.remove(key);
             }
             _totalIdle--;
             itemsToRemove--;
@@ -916,11 +916,10 @@
     }
      
     public synchronized void clear(Object key) {
-        CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.remove(key));
+        LinkedList pool = (LinkedList)(_poolMap.remove(key));
         if(null == pool) {
             return;
         } else {
-            _poolList.remove(key);
             for(Iterator it = pool.iterator(); it.hasNext(); ) {
                 try {
                     _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
@@ -948,7 +947,7 @@
 
     public synchronized int getNumIdle(Object key) {
         try {
-            return((CursorableLinkedList)(_poolMap.get(key))).size();
+            return((LinkedList)(_poolMap.get(key))).size();
         } catch(Exception e) {
             return 0;
         }
@@ -975,12 +974,11 @@
 
         boolean shouldDestroy = false;
         // grab the pool (list) of objects associated with the given key
-        CursorableLinkedList pool = (CursorableLinkedList) (_poolMap.get(key));
+        LinkedList pool = (LinkedList) (_poolMap.get(key));
         // if it doesn't exist, create it
         if(null == pool) {
-            pool = new CursorableLinkedList();
+            pool = new LinkedList();
             _poolMap.put(key, pool);
-            _poolList.add(key);
         }
         decrementActiveCount(key);
         // if there's no space in the pool, flag the object for destruction
@@ -1030,11 +1028,10 @@
      * will start a sustain cycle immediately.
      */
     public synchronized void preparePool(Object key, boolean populateImmediately) {
-        CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.get(key));
+        LinkedList pool = (LinkedList)(_poolMap.get(key));
         if (null == pool) {
-            pool = new CursorableLinkedList();
+            pool = new LinkedList();
             _poolMap.put(key,pool);
-            _poolList.add(key);
         }
         
         if (populateImmediately) {
@@ -1050,17 +1047,9 @@
     
     public synchronized void close() throws Exception {
         clear();
-        _poolList = null;
         _poolMap = null;
         _activeMap = null;
-        if(null != _evictionCursor) {
-            _evictionCursor.close();
-            _evictionCursor = null;
-        }
-        if(null != _evictionKeyCursor) {
-            _evictionKeyCursor.close();
-            _evictionKeyCursor = null;
-        }
+        _recentlyEvictedKeys = null;
         if(null != _evictor) {
             _evictor.cancel();
             _evictor = null;
@@ -1078,40 +1067,43 @@
 
     public synchronized void evict() throws Exception {
         Object key = null;
+        if (_recentlyEvictedKeys == null) {
+            _recentlyEvictedKeys = new HashSet(_poolMap.size());
+        }
+        Set remainingKeys = new HashSet(_poolMap.keySet());
+        remainingKeys.removeAll(_recentlyEvictedKeys);
+        Iterator keyIter = remainingKeys.iterator();
+
+        ListIterator objIter = null;
+
         for(int i=0,m=getNumTests();i<m;i++) {
             if(_poolMap.size() > 0) {
-                // if we don't have a key cursor, then create one, and close any object cursor
-                if(null == _evictionKeyCursor) {
-                    _evictionKeyCursor = _poolList.cursor();
-                    key = null;
-                    if(null != _evictionCursor) {
-                        _evictionCursor.close();
-                        _evictionCursor = null;
+                // Find next idle object pool key to work on
+                if (key == null) {
+                    if (!keyIter.hasNext()) {
+                        _recentlyEvictedKeys.clear();
+                        remainingKeys = new HashSet(_poolMap.keySet());
+                        keyIter = remainingKeys.iterator();
+                    }
+                    if (!keyIter.hasNext()) {
+                        // done, there are no keyed pools
+                        return;
                     }
+                    key = keyIter.next();
                 }
-                // if we don't have an object cursor
-                if(null == _evictionCursor) {
-                    // if the _evictionKeyCursor has a next value, then use it
-                    if(_evictionKeyCursor.hasNext()) {
-                        key = _evictionKeyCursor.next();
-                        CursorableLinkedList pool = (CursorableLinkedList)(_poolMap.get(key));
-                        _evictionCursor = pool.cursor(pool.size());
-                    } else {
-                        // else close the key cursor and loop back around
-                        if(null != _evictionKeyCursor) {
-                            _evictionKeyCursor.close();
-                            _evictionKeyCursor = _poolList.cursor();
-                            if(null != _evictionCursor) {
-                                _evictionCursor.close();
-                                _evictionCursor = null;
-                            }
-                        }
-                        continue;
+
+                // if we don't have a keyed object pool iterator
+                if (objIter == null) {
+                    final LinkedList list = (LinkedList)_poolMap.get(key);
+                    if (_evictLastIndex < 0 || _evictLastIndex > list.size()) {
+                        _evictLastIndex = list.size();
                     }
+                    objIter = list.listIterator(_evictLastIndex);
                 }
+
                 // if the _evictionCursor has a previous object, then test it
-                if(_evictionCursor.hasPrevious()) {
-                    ObjectTimestampPair pair = (ObjectTimestampPair)(_evictionCursor.previous());
+                if(objIter.hasPrevious()) {
+                    ObjectTimestampPair pair = (ObjectTimestampPair)(objIter.previous());
                     boolean removeObject=false;
                     if(_minEvictableIdleTimeMillis > 0 &&
                        System.currentTimeMillis() - pair.tstamp > _minEvictableIdleTimeMillis) {
@@ -1138,7 +1130,7 @@
                     }
                     if(removeObject) {
                         try {
-                            _evictionCursor.remove();
+                            objIter.remove();
                             _totalIdle--;
                             _factory.destroyObject(key,pair.value);
 
@@ -1147,20 +1139,18 @@
                             // {@link #getMinIdle <i>minIdle</i>} is > 0.
                             // 
                             // Otherwise if it was the last object for that key, drop that pool
-                            if ((_minIdle == 0) && (((CursorableLinkedList)(_poolMap.get(key))).isEmpty())) {
+                            if ((_minIdle == 0) && (((LinkedList)(_poolMap.get(key))).isEmpty())) {
                                 _poolMap.remove(key);
-                                _poolList.remove(key);
                             }
                         } catch(Exception e) {
                             ; // ignored
                         }
                     }
                 } else {
-                    // else the _evictionCursor is done, so close it and loop around
-                    if(_evictionCursor != null) {
-                        _evictionCursor.close();
-                        _evictionCursor = null;
-                    }
+                    // else done evicting keyed pool
+                    _recentlyEvictedKeys.add(key);
+                    _evictLastIndex = -1;
+                    objIter = null;
                 }
             }
         }
@@ -1174,7 +1164,7 @@
      * @throws Exception If there was an error whilst creating the pooled objects.
      */
     private synchronized void ensureMinIdle() throws Exception {
-        ListIterator iterator = _poolList.cursor();
+        Iterator iterator = _poolMap.keySet().iterator();
    
         //Check if should sustain the pool
         if (_minIdle > 0) {
@@ -1235,7 +1225,7 @@
         StringBuffer buf = new StringBuffer();
         buf.append("Active: ").append(getNumActive()).append("\n");
         buf.append("Idle: ").append(getNumIdle()).append("\n");
-        Iterator it = _poolList.iterator();
+        Iterator it = _poolMap.keySet().iterator();
         while(it.hasNext()) {
             buf.append("\t").append(_poolMap.get(it.next())).append("\n");
         }
@@ -1350,7 +1340,7 @@
 
     /**
      * The idle object evictor thread.
-     * @see #setTimeBetweenEvictionRunsMillis
+     * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
      */
     class Evictor implements Runnable {
         private boolean _cancelled = false;
@@ -1388,16 +1378,6 @@
                     ; // ignored
                 }
             }
-            synchronized(GenericKeyedObjectPool.this) {
-                if(null != _evictionCursor) {
-                    _evictionCursor.close();
-                    _evictionCursor = null;
-                }
-                if(null != _evictionKeyCursor) {
-                    _evictionKeyCursor.close();
-                    _evictionKeyCursor = null;
-                }
-            }
         }
     }
 
@@ -1564,12 +1544,6 @@
     /** My hash of pools (CursorableLinkedLists). */
     private HashMap _poolMap = null;
 
-    /**
-     * A cursorable list of my pools.
-     * @see GenericKeyedObjectPool.Evictor#run
-     */
-    private CursorableLinkedList _poolList = null;
-
     /** Count of active objects, per key. */
     private HashMap _activeMap = null;
 
@@ -1587,7 +1561,13 @@
      */
     private Evictor _evictor = null;
 
-    private CursorableLinkedList.Cursor _evictionCursor = null;
-    private CursorableLinkedList.Cursor _evictionKeyCursor = null;
+    /**
+     * Idle object pool keys that have been evicted recently.
+     */
+    private Set _recentlyEvictedKeys = null;
 
+    /**
+     * Position in the _pool where the _evictor last stopped.
+     */
+    private int _evictLastIndex = -1;
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org