View Javadoc

1   /*
2    * Copyright 1999-2004,2006 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.pool.impl;
18  
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.ListIterator;
22  import java.util.Map;
23  import java.util.NoSuchElementException;
24  import java.util.Set;
25  import java.util.TreeMap;
26  import java.util.LinkedList;
27  import java.util.HashSet;
28  import java.util.TimerTask;
29  
30  import org.apache.commons.pool.BaseKeyedObjectPool;
31  import org.apache.commons.pool.KeyedObjectPool;
32  import org.apache.commons.pool.KeyedPoolableObjectFactory;
33  
34  /***
35   * A configurable {@link KeyedObjectPool} implementation.
36   * <p>
37   * When coupled with the appropriate {@link KeyedPoolableObjectFactory},
38   * <tt>GenericKeyedObjectPool</tt> provides robust pooling functionality for
39   * arbitrary objects.
40   * <p>
41   * A <tt>GenericKeyedObjectPool</tt> provides a number of configurable parameters:
42   * <ul>
43   *  <li>
44   *    {@link #setMaxActive <i>maxActive</i>} controls the maximum number of objects (per key)
45   *    that can be borrowed from the pool at one time.  When non-positive, there
46   *    is no limit to the number of objects that may be active at one time.
47   *    When {@link #setMaxActive <i>maxActive</i>} is exceeded, the pool is said to be exhausted.
48   *  </li>
49   *  <li>
50   *    {@link #setMaxIdle <i>maxIdle</i>} controls the maximum number of objects that can
51   *    sit idle in the pool (per key) at any time.  When negative, there
52   *    is no limit to the number of objects that may be idle at one time.
53   *  </li>
54   *  <li>
55   *    {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} specifies the
56   *    behaviour of the {@link #borrowObject} method when the pool is exhausted:
57   *    <ul>
58   *    <li>
59   *      When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
60   *      {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject} will throw
61   *      a {@link NoSuchElementException}
62   *    </li>
63   *    <li>
64   *      When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>} is
65   *      {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject} will create a new
66   *      object and return it(essentially making {@link #setMaxActive <i>maxActive</i>}
67   *      meaningless.)
68   *    </li>
69   *    <li>
70   *      When {@link #setWhenExhaustedAction <i>whenExhaustedAction</i>}
71   *      is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject} will block
72   *      (invoke {@link Object#wait} until a new or idle object is available.
73   *      If a positive {@link #setMaxWait <i>maxWait</i>}
74   *      value is supplied, the {@link #borrowObject} will block for at
75   *      most that many milliseconds, after which a {@link NoSuchElementException}
76   *      will be thrown.  If {@link #setMaxWait <i>maxWait</i>} is non-positive,
77   *      the {@link #borrowObject} method will block indefinitely.
78   *    </li>
79   *    </ul>
80   *  </li>
81   *  <li>
82   *    When {@link #setTestOnBorrow <i>testOnBorrow</i>} is set, the pool will
83   *    attempt to validate each object before it is returned from the
84   *    {@link #borrowObject} method. (Using the provided factory's
85   *    {@link KeyedPoolableObjectFactory#validateObject} method.)  Objects that fail
86   *    to validate will be dropped from the pool, and a different object will
87   *    be borrowed.
88   *  </li>
89   *  <li>
90   *    When {@link #setTestOnReturn <i>testOnReturn</i>} is set, the pool will
91   *    attempt to validate each object before it is returned to the pool in the
92   *    {@link #returnObject} method. (Using the provided factory's
93   *    {@link KeyedPoolableObjectFactory#validateObject}
94   *    method.)  Objects that fail to validate will be dropped from the pool.
95   *  </li>
96   * </ul>
97   * <p>
98   * Optionally, one may configure the pool to examine and possibly evict objects as they
99   * sit idle in the pool.  This is performed by an "idle object eviction" thread, which
100  * runs asychronously.  The idle object eviction thread may be configured using the
101  * following attributes:
102  * <ul>
103  *  <li>
104  *   {@link #setTimeBetweenEvictionRunsMillis <i>timeBetweenEvictionRunsMillis</i>}
105  *   indicates how long the eviction thread should sleep before "runs" of examining
106  *   idle objects.  When non-positive, no eviction thread will be launched.
107  *  </li>
108  *  <li>
109  *   {@link #setMinEvictableIdleTimeMillis <i>minEvictableIdleTimeMillis</i>}
110  *   specifies the minimum amount of time that an object may sit idle in the pool
111  *   before it is eligable for eviction due to idle time.  When non-positive, no object
112  *   will be dropped from the pool due to idle time alone.
113  *  </li>
114  *  <li>
115  *   {@link #setTestWhileIdle <i>testWhileIdle</i>} indicates whether or not idle
116  *   objects should be validated using the factory's
117  *   {@link KeyedPoolableObjectFactory#validateObject} method.  Objects
118  *   that fail to validate will be dropped from the pool.
119  *  </li>
120  * </ul>
121  * <p>
122  * GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}.  A
123  * non-<code>null</code> factory must be provided either as a constructor argument
124  * or via a call to {@link #setFactory} before the pool is used.
125  * </p>
126  * @see GenericObjectPool
127  * @author Rodney Waldhoff
128  * @author Dirk Verbeeck
129  * @version $Revision: 386116 $ $Date: 2006-03-15 12:15:58 -0500 (Wed, 15 Mar 2006) $
130  */
131 public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
132 
133     //--- public constants -------------------------------------------
134 
135     /***
136      * A "when exhausted action" type indicating that when the pool is
137      * exhausted (i.e., the maximum number of active objects has
138      * been reached), the {@link #borrowObject}
139      * method should fail, throwing a {@link NoSuchElementException}.
140      * @see #WHEN_EXHAUSTED_BLOCK
141      * @see #WHEN_EXHAUSTED_GROW
142      * @see #setWhenExhaustedAction
143      */
144     public static final byte WHEN_EXHAUSTED_FAIL   = 0;
145 
146     /***
147      * A "when exhausted action" type indicating that when the pool
148      * is exhausted (i.e., the maximum number
149      * of active objects has been reached), the {@link #borrowObject}
150      * method should block until a new object is available, or the
151      * {@link #getMaxWait maximum wait time} has been reached.
152      * @see #WHEN_EXHAUSTED_FAIL
153      * @see #WHEN_EXHAUSTED_GROW
154      * @see #setMaxWait
155      * @see #getMaxWait
156      * @see #setWhenExhaustedAction
157      */
158     public static final byte WHEN_EXHAUSTED_BLOCK  = 1;
159 
160     /***
161      * A "when exhausted action" type indicating that when the pool is
162      * exhausted (i.e., the maximum number
163      * of active objects has been reached), the {@link #borrowObject}
164      * method should simply create a new object anyway.
165      * @see #WHEN_EXHAUSTED_FAIL
166      * @see #WHEN_EXHAUSTED_GROW
167      * @see #setWhenExhaustedAction
168      */
169     public static final byte WHEN_EXHAUSTED_GROW   = 2;
170 
171     /***
172      * The default cap on the number of idle instances in the pool
173      * (per key).
174      * @see #getMaxIdle
175      * @see #setMaxIdle
176      */
177     public static final int DEFAULT_MAX_IDLE  = 8;
178 
179     /***
180      * The default cap on the total number of active instances from the pool
181      * (per key).
182      * @see #getMaxActive
183      * @see #setMaxActive
184      */
185     public static final int DEFAULT_MAX_ACTIVE  = 8;
186 
187     /***
188      * The default cap on the the maximum number of objects that can exists at one time.
189      * @see #getMaxTotal
190      * @see #setMaxTotal
191      */
192     public static final int DEFAULT_MAX_TOTAL  = -1;
193 
194     /***
195      * The default "when exhausted action" for the pool.
196      * @see #WHEN_EXHAUSTED_BLOCK
197      * @see #WHEN_EXHAUSTED_FAIL
198      * @see #WHEN_EXHAUSTED_GROW
199      * @see #setWhenExhaustedAction
200      */
201     public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
202 
203     /***
204      * The default maximum amount of time (in millis) the
205      * {@link #borrowObject} method should block before throwing
206      * an exception when the pool is exhausted and the
207      * {@link #getWhenExhaustedAction "when exhausted" action} is
208      * {@link #WHEN_EXHAUSTED_BLOCK}.
209      * @see #getMaxWait
210      * @see #setMaxWait
211      */
212     public static final long DEFAULT_MAX_WAIT = -1L;
213 
214     /***
215      * The default "test on borrow" value.
216      * @see #getTestOnBorrow
217      * @see #setTestOnBorrow
218      */
219     public static final boolean DEFAULT_TEST_ON_BORROW = false;
220 
221     /***
222      * The default "test on return" value.
223      * @see #getTestOnReturn
224      * @see #setTestOnReturn
225      */
226     public static final boolean DEFAULT_TEST_ON_RETURN = false;
227 
228     /***
229      * The default "test while idle" value.
230      * @see #getTestWhileIdle
231      * @see #setTestWhileIdle
232      * @see #getTimeBetweenEvictionRunsMillis
233      * @see #setTimeBetweenEvictionRunsMillis
234      */
235     public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
236 
237     /***
238      * The default "time between eviction runs" value.
239      * @see #getTimeBetweenEvictionRunsMillis
240      * @see #setTimeBetweenEvictionRunsMillis
241      */
242     public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
243 
244     /***
245      * The default number of objects to examine per run in the
246      * idle object evictor.
247      * @see #getNumTestsPerEvictionRun
248      * @see #setNumTestsPerEvictionRun
249      * @see #getTimeBetweenEvictionRunsMillis
250      * @see #setTimeBetweenEvictionRunsMillis
251      */
252     public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
253 
254     /***
255      * The default value for {@link #getMinEvictableIdleTimeMillis}.
256      * @see #getMinEvictableIdleTimeMillis
257      * @see #setMinEvictableIdleTimeMillis
258      */
259     public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
260 
261     /***
262      * The default minimum level of idle objects in the pool.
263      * @see #setMinIdle
264      * @see #getMinIdle
265      */
266     public static final int DEFAULT_MIN_IDLE = 0;
267     
268     //--- constructors -----------------------------------------------
269 
270     /***
271      * Create a new <tt>GenericKeyedObjectPool</tt>..
272      */
273     public GenericKeyedObjectPool() {
274         this(null,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
275     }
276 
277     /***
278      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
279      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
280      */
281     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory) {
282         this(factory,DEFAULT_MAX_ACTIVE,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
283     }
284 
285     /***
286      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
287      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
288      * @param config a non-<tt>null</tt> {@link GenericKeyedObjectPool.Config} describing my configuration
289      */
290     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, GenericKeyedObjectPool.Config config) {
291         this(factory,config.maxActive,config.whenExhaustedAction,config.maxWait,config.maxIdle,config.maxTotal,config.testOnBorrow,config.testOnReturn,config.timeBetweenEvictionRunsMillis,config.numTestsPerEvictionRun,config.minEvictableIdleTimeMillis,config.testWhileIdle);
292     }
293 
294     /***
295      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
296      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
297      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
298      */
299     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive) {
300         this(factory,maxActive,DEFAULT_WHEN_EXHAUSTED_ACTION,DEFAULT_MAX_WAIT,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
301     }
302 
303     /***
304      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
305      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
306      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
307      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
308      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
309      */
310     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait) {
311         this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
312     }
313 
314     /***
315      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
316      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
317      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
318      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
319      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
320      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
321      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
322      */
323     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn) {
324         this(factory,maxActive,whenExhaustedAction,maxWait,DEFAULT_MAX_IDLE,testOnBorrow,testOnReturn,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
325     }
326 
327     /***
328      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
329      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
330      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
331      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
332      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
333      * @param maxIdle the maximum number of idle objects in my pool (per key) (see {@link #setMaxIdle})
334      */
335     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) {
336         this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,DEFAULT_TEST_ON_BORROW,DEFAULT_TEST_ON_RETURN,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
337     }
338 
339     /***
340      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
341      * @param factory the (possibly <tt>null</tt>)KeyedPoolableObjectFactory to use to create, validate and destroy objects
342      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
343      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
344      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
345      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
346      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
347      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
348      */
349     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
350         this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,testOnBorrow,testOnReturn,DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,DEFAULT_NUM_TESTS_PER_EVICTION_RUN,DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,DEFAULT_TEST_WHILE_IDLE);
351     }
352 
353     /***
354      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
355      * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
356      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
357      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
358      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
359      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
360      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
361      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
362      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
363      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
364      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
365      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
366      */
367     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
368         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
369     }
370 
371     /***
372      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
373      * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
374      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
375      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
376      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
377      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
378      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
379      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
380      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
381      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
382      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
383      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
384      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
385      */
386     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
387         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
388     }
389     
390     /***
391      * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
392      * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
393      * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
394      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
395      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
396      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
397      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
398      * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
399      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
400      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
401      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
402      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
403      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
404      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
405      */
406     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
407         _factory = factory;
408         _maxActive = maxActive;
409         switch(whenExhaustedAction) {
410             case WHEN_EXHAUSTED_BLOCK:
411             case WHEN_EXHAUSTED_FAIL:
412             case WHEN_EXHAUSTED_GROW:
413                 _whenExhaustedAction = whenExhaustedAction;
414                 break;
415             default:
416                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
417         }
418         _maxWait = maxWait;
419         _maxIdle = maxIdle;
420         _maxTotal = maxTotal;
421         _minIdle = minIdle;
422         _testOnBorrow = testOnBorrow;
423         _testOnReturn = testOnReturn;
424         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
425         _numTestsPerEvictionRun = numTestsPerEvictionRun;
426         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
427         _testWhileIdle = testWhileIdle;
428 
429         _poolMap = new HashMap();
430         _activeMap = new HashMap();
431 
432         startEvictor(_timeBetweenEvictionRunsMillis);
433     }
434 
435     //--- public methods ---------------------------------------------
436 
437     //--- configuration methods --------------------------------------
438 
439     /***
440      * Returns the cap on the number of active instances from my pool (per key).
441      * @return the cap on the number of active instances from my pool (per key).
442      * @see #setMaxActive
443      */
444     public synchronized int getMaxActive() {
445         return _maxActive;
446     }
447 
448     /***
449      * Sets the cap on the number of active instances from my pool (per key).
450      * @param maxActive The cap on the number of active instances from my pool (per key).
451      *                  Use a negative value for an infinite number of instances.
452      * @see #getMaxActive
453      */
454     public synchronized void setMaxActive(int maxActive) {
455         _maxActive = maxActive;
456         notifyAll();
457     }
458 
459     /***
460      * Returns the cap on the total number of instances from my pool if non-positive.
461      * @return the cap on the total number of instances from my pool if non-positive.
462      * @see #setMaxTotal
463      */
464     public synchronized int getMaxTotal() {
465         return _maxTotal;
466     }
467 
468     /***
469      * Sets the cap on the total number of instances from my pool if non-positive.
470      * @param maxTotal The cap on the total number of instances from my pool.
471      *                  Use a non-positive value for an infinite number of instances.
472      * @see #getMaxTotal
473      */
474     public synchronized void setMaxTotal(int maxTotal) {
475         _maxTotal = maxTotal;
476         notifyAll();
477     }
478 
479     /***
480      * Returns the action to take when the {@link #borrowObject} method
481      * is invoked when the pool is exhausted (the maximum number
482      * of "active" objects has been reached).
483      *
484      * @return one of {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
485      * @see #setWhenExhaustedAction
486      */
487     public synchronized byte getWhenExhaustedAction() {
488         return _whenExhaustedAction;
489     }
490 
491     /***
492      * Sets the action to take when the {@link #borrowObject} method
493      * is invoked when the pool is exhausted (the maximum number
494      * of "active" objects has been reached).
495      *
496      * @param whenExhaustedAction the action code, which must be one of
497      *        {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
498      *        or {@link #WHEN_EXHAUSTED_GROW}
499      * @see #getWhenExhaustedAction
500      */
501     public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
502         switch(whenExhaustedAction) {
503             case WHEN_EXHAUSTED_BLOCK:
504             case WHEN_EXHAUSTED_FAIL:
505             case WHEN_EXHAUSTED_GROW:
506                 _whenExhaustedAction = whenExhaustedAction;
507                 notifyAll();
508                 break;
509             default:
510                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
511         }
512     }
513 
514 
515     /***
516      * Returns the maximum amount of time (in milliseconds) the
517      * {@link #borrowObject} method should block before throwing
518      * an exception when the pool is exhausted and the
519      * {@link #setWhenExhaustedAction "when exhausted" action} is
520      * {@link #WHEN_EXHAUSTED_BLOCK}.
521      *
522      * When less than 0, the {@link #borrowObject} method
523      * may block indefinitely.
524      *
525      * @see #setMaxWait
526      * @see #setWhenExhaustedAction
527      * @see #WHEN_EXHAUSTED_BLOCK
528      */
529     public synchronized long getMaxWait() {
530         return _maxWait;
531     }
532 
533     /***
534      * Sets the maximum amount of time (in milliseconds) the
535      * {@link #borrowObject} method should block before throwing
536      * an exception when the pool is exhausted and the
537      * {@link #setWhenExhaustedAction "when exhausted" action} is
538      * {@link #WHEN_EXHAUSTED_BLOCK}.
539      *
540      * When less than 0, the {@link #borrowObject} method
541      * may block indefinitely.
542      *
543      * @see #getMaxWait
544      * @see #setWhenExhaustedAction
545      * @see #WHEN_EXHAUSTED_BLOCK
546      */
547     public synchronized void setMaxWait(long maxWait) {
548         _maxWait = maxWait;
549     }
550 
551     /***
552      * Returns the cap on the number of "idle" instances in the pool.
553      * @return the cap on the number of "idle" instances in the pool.
554      * @see #setMaxIdle
555      */
556     public synchronized int getMaxIdle() {
557         return _maxIdle;
558     }
559 
560     /***
561      * Sets the cap on the number of "idle" instances in the pool.
562      * @param maxIdle The cap on the number of "idle" instances in the pool.
563      *                Use a negative value to indicate an unlimited number
564      *                of idle instances.
565      * @see #getMaxIdle
566      */
567     public synchronized void setMaxIdle(int maxIdle) {
568         _maxIdle = maxIdle;
569         notifyAll();
570     }
571 
572     /***
573      * Sets the minimum number of idle objects in pool to maintain (per key)
574      * @param poolSize - The minimum size of the pool
575      * @see #getMinIdle
576      */
577     public synchronized void setMinIdle(int poolSize) {
578         _minIdle = poolSize;
579     }
580 
581     /***
582      * Returns the minimum number of idle objects in pool to maintain (per key)
583      * @return the minimum number of idle objects in pool to maintain (per key)
584      * @see #setMinIdle
585      */
586     public synchronized int getMinIdle() {
587         return _minIdle;
588     }
589 
590     /***
591      * When <tt>true</tt>, objects will be
592      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
593      * before being returned by the {@link #borrowObject}
594      * method.  If the object fails to validate,
595      * it will be dropped from the pool, and we will attempt
596      * to borrow another.
597      *
598      * @see #setTestOnBorrow
599      */
600     public synchronized boolean getTestOnBorrow() {
601         return _testOnBorrow;
602     }
603 
604     /***
605      * When <tt>true</tt>, objects will be
606      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
607      * before being returned by the {@link #borrowObject}
608      * method.  If the object fails to validate,
609      * it will be dropped from the pool, and we will attempt
610      * to borrow another.
611      *
612      * @see #getTestOnBorrow
613      */
614     public synchronized void setTestOnBorrow(boolean testOnBorrow) {
615         _testOnBorrow = testOnBorrow;
616     }
617 
618     /***
619      * When <tt>true</tt>, objects will be
620      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
621      * before being returned to the pool within the
622      * {@link #returnObject}.
623      *
624      * @see #setTestOnReturn
625      */
626     public synchronized boolean getTestOnReturn() {
627         return _testOnReturn;
628     }
629 
630     /***
631      * When <tt>true</tt>, objects will be
632      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
633      * before being returned to the pool within the
634      * {@link #returnObject}.
635      *
636      * @see #getTestOnReturn
637      */
638     public synchronized void setTestOnReturn(boolean testOnReturn) {
639         _testOnReturn = testOnReturn;
640     }
641 
642     /***
643      * Returns the number of milliseconds to sleep between runs of the
644      * idle object evictor thread.
645      * When non-positive, no idle object evictor thread will be
646      * run.
647      *
648      * @see #setTimeBetweenEvictionRunsMillis
649      */
650     public synchronized long getTimeBetweenEvictionRunsMillis() {
651         return _timeBetweenEvictionRunsMillis;
652     }
653 
654     /***
655      * Sets the number of milliseconds to sleep between runs of the
656      * idle object evictor thread.
657      * When non-positive, no idle object evictor thread will be
658      * run.
659      *
660      * @see #getTimeBetweenEvictionRunsMillis
661      */
662     public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
663         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
664         startEvictor(_timeBetweenEvictionRunsMillis);
665     }
666 
667     /***
668      * Returns the number of objects to examine during each run of the
669      * idle object evictor thread (if any).
670      *
671      * @see #setNumTestsPerEvictionRun
672      * @see #setTimeBetweenEvictionRunsMillis
673      */
674     public synchronized int getNumTestsPerEvictionRun() {
675         return _numTestsPerEvictionRun;
676     }
677 
678     /***
679      * Sets the number of objects to examine during each run of the
680      * idle object evictor thread (if any).
681      * <p>
682      * When a negative value is supplied, <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
683      * tests will be run.  I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
684      * idle objects will be tested per run.
685      *
686      * @see #getNumTestsPerEvictionRun
687      * @see #setTimeBetweenEvictionRunsMillis
688      */
689     public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
690         _numTestsPerEvictionRun = numTestsPerEvictionRun;
691     }
692 
693     /***
694      * Returns the minimum amount of time an object may sit idle in the pool
695      * before it is eligable for eviction by the idle object evictor
696      * (if any).
697      *
698      * @see #setMinEvictableIdleTimeMillis
699      * @see #setTimeBetweenEvictionRunsMillis
700      */
701     public synchronized long getMinEvictableIdleTimeMillis() {
702         return _minEvictableIdleTimeMillis;
703     }
704 
705     /***
706      * Sets the minimum amount of time an object may sit idle in the pool
707      * before it is eligable for eviction by the idle object evictor
708      * (if any).
709      * When non-positive, no objects will be evicted from the pool
710      * due to idle time alone.
711      *
712      * @see #getMinEvictableIdleTimeMillis
713      * @see #setTimeBetweenEvictionRunsMillis
714      */
715     public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
716         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
717     }
718 
719     /***
720      * When <tt>true</tt>, objects will be
721      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
722      * by the idle object evictor (if any).  If an object
723      * fails to validate, it will be dropped from the pool.
724      *
725      * @see #setTestWhileIdle
726      * @see #setTimeBetweenEvictionRunsMillis
727      */
728     public synchronized boolean getTestWhileIdle() {
729         return _testWhileIdle;
730     }
731 
732     /***
733      * When <tt>true</tt>, objects will be
734      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
735      * by the idle object evictor (if any).  If an object
736      * fails to validate, it will be dropped from the pool.
737      *
738      * @see #getTestWhileIdle
739      * @see #setTimeBetweenEvictionRunsMillis
740      */
741     public synchronized void setTestWhileIdle(boolean testWhileIdle) {
742         _testWhileIdle = testWhileIdle;
743     }
744 
745     /***
746      * Sets my configuration.
747      * @see GenericKeyedObjectPool.Config
748      */
749     public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
750         setMaxIdle(conf.maxIdle);
751         setMaxActive(conf.maxActive);
752         setMaxTotal(conf.maxTotal);
753         setMinIdle(conf.minIdle);
754         setMaxWait(conf.maxWait);
755         setWhenExhaustedAction(conf.whenExhaustedAction);
756         setTestOnBorrow(conf.testOnBorrow);
757         setTestOnReturn(conf.testOnReturn);
758         setTestWhileIdle(conf.testWhileIdle);
759         setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
760         setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
761         setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
762     }
763 
764     //-- ObjectPool methods ------------------------------------------
765 
766     public synchronized Object borrowObject(Object key) throws Exception {
767         long starttime = System.currentTimeMillis();
768         boolean newlyCreated = false;
769         for(;;) {
770             LinkedList pool = (LinkedList)(_poolMap.get(key));
771             if(null == pool) {
772                 pool = new LinkedList();
773                 _poolMap.put(key,pool);
774             }
775             ObjectTimestampPair pair = null;
776             // if there are any sleeping, just grab one of those
777             try {
778                 pair = (ObjectTimestampPair)(pool.removeFirst());
779                 if(null != pair) {
780                     _totalIdle--;
781                 }
782             } catch(NoSuchElementException e) { /* ignored */
783             }
784             // otherwise
785             if(null == pair) {
786                 // if there is a totalMaxActive and we are at the limit then
787                 // we have to make room
788                 if ((_maxTotal > 0) && (_totalActive + _totalIdle >= _maxTotal)) {
789                     clearOldest();
790                 }
791 
792                 // check if we can create one
793                 // (note we know that the num sleeping is 0, else we wouldn't be here)
794                 int active = getActiveCount(key);
795                 if ((_maxActive < 0 || active < _maxActive) &&
796                     (_maxTotal < 0 || _totalActive + _totalIdle < _maxTotal)) {
797                     Object obj = _factory.makeObject(key);
798                     pair = new ObjectTimestampPair(obj);
799                     newlyCreated = true;
800                 } else {
801                     // the pool is exhausted
802                     switch(_whenExhaustedAction) {
803                         case WHEN_EXHAUSTED_GROW:
804                             Object obj = _factory.makeObject(key);
805                             pair = new ObjectTimestampPair(obj);
806                             break;
807                         case WHEN_EXHAUSTED_FAIL:
808                             throw new NoSuchElementException();
809                         case WHEN_EXHAUSTED_BLOCK:
810                             try {
811                                 if(_maxWait <= 0) {
812                                     wait();
813                                 } else {
814                                     // this code may be executed again after a notify then continue cycle
815                                     // so, need to calculate the amount of time to wait
816                                     final long elapsed = (System.currentTimeMillis() - starttime);
817                                     final long waitTime = _maxWait - elapsed;
818                                     if (waitTime > 0)
819                                     {
820                                         wait(waitTime);
821                                     }
822                                 }
823                             } catch(InterruptedException e) {
824                                 // ignored
825                             }
826                             if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {
827                                 throw new NoSuchElementException("Timeout waiting for idle object");
828                             } else {
829                                 continue; // keep looping
830                             }
831                         default:
832                             throw new IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + " not recognized.");
833                     }
834                 }
835             }
836             _factory.activateObject(key,pair.value);
837             if(_testOnBorrow && !_factory.validateObject(key,pair.value)) {
838                 _factory.destroyObject(key,pair.value);
839                 if(newlyCreated) {
840                     throw new NoSuchElementException("Could not create a validated object");
841                 } // else keep looping
842             } else {
843                 incrementActiveCount(key);
844                 return pair.value;
845             }
846         }
847     }
848 
849     public synchronized void clear() {
850         for(Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext(); ) {
851             Object key = keyiter.next();
852             final LinkedList list = (LinkedList)(_poolMap.get(key));
853             for(Iterator it = list.iterator(); it.hasNext(); ) {
854                 try {
855                     _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
856                 } catch(Exception e) {
857                     // ignore error, keep destroying the rest
858                 }
859                 it.remove();
860             }
861         }
862         _poolMap.clear();
863         if (_recentlyEvictedKeys != null) {
864             _recentlyEvictedKeys.clear();
865         }
866         _totalIdle = 0;
867         notifyAll();
868     }
869 
870     /***
871      * Method clears oldest 15% of objects in pool.  The method sorts the
872      * objects into a TreeMap and then iterates the first 15% for removal
873      */
874     public synchronized void clearOldest() {
875         // build sorted map of idle objects
876         TreeMap map = new TreeMap();
877         for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
878             Object key = keyiter.next();
879             LinkedList list = (LinkedList) _poolMap.get(key);
880             for (Iterator it = list.iterator(); it.hasNext();) {
881                 // each item into the map uses the objectimestamppair object
882                 // as the key.  It then gets sorted based on the timstamp field
883                 // each value in the map is the parent list it belongs in.
884                 ObjectTimestampPair pair = (ObjectTimestampPair) it.next();
885                 map.put(pair, key);
886             }
887         }
888 
889         // Now iterate created map and kill the first 15% plus one to account for zero
890         Set setPairKeys = map.entrySet();
891         int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
892 
893         Iterator iter = setPairKeys.iterator();
894         while (iter.hasNext() && itemsToRemove > 0) {
895             Map.Entry entry = (Map.Entry) iter.next();
896             // kind of backwards on naming.  In the map, each key is the objecttimestamppair
897             // because it has the ordering with the timestamp value.  Each value that the
898             // key references is the key of the list it belongs to.
899             Object key = entry.getValue();
900             ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
901             LinkedList list = (LinkedList) _poolMap.get(key);
902             list.remove(pairTimeStamp);
903 
904             try {
905                 _factory.destroyObject(key, pairTimeStamp.value);
906             } catch (Exception e) {
907                 // ignore error, keep destroying the rest
908             }
909             // if that was the last object for that key, drop that pool
910             if (list.isEmpty()) {
911                 _poolMap.remove(key);
912             }
913             _totalIdle--;
914             itemsToRemove--;
915         }
916         notifyAll();
917     }
918 
919     public synchronized void clear(Object key) {
920         LinkedList pool = (LinkedList)(_poolMap.remove(key));
921         if(null == pool) {
922             return;
923         } else {
924             for(Iterator it = pool.iterator(); it.hasNext(); ) {
925                 try {
926                     _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
927                 } catch(Exception e) {
928                     // ignore error, keep destroying the rest
929                 }
930                 it.remove();
931                 _totalIdle--;
932             }
933         }
934         notifyAll();
935     }
936 
937     public synchronized int getNumActive() {
938         return _totalActive;
939     }
940 
941     public synchronized int getNumIdle() {
942         return _totalIdle;
943     }
944 
945     public synchronized int getNumActive(Object key) {
946         return getActiveCount(key);
947     }
948 
949     public synchronized int getNumIdle(Object key) {
950         try {
951             return((LinkedList)(_poolMap.get(key))).size();
952         } catch(Exception e) {
953             return 0;
954         }
955     }
956 
957     public synchronized void returnObject(Object key, Object obj) throws Exception {
958 
959         // if we need to validate this object, do so
960         boolean success = true; // whether or not this object passed validation
961         if(_testOnReturn && !_factory.validateObject(key, obj)) {
962             success = false;
963             try {
964                 _factory.destroyObject(key, obj);
965             } catch(Exception e) {
966                 // ignored
967             }
968         } else {
969             try {
970                 _factory.passivateObject(key, obj);
971             } catch(Exception e) {
972                 success = false;
973             }
974         }
975 
976         boolean shouldDestroy = false;
977         // grab the pool (list) of objects associated with the given key
978         LinkedList pool = (LinkedList) (_poolMap.get(key));
979         // if it doesn't exist, create it
980         if(null == pool) {
981             pool = new LinkedList();
982             _poolMap.put(key, pool);
983         }
984         decrementActiveCount(key);
985         // if there's no space in the pool, flag the object for destruction
986         // else if we passivated succesfully, return it to the pool
987         if(_maxIdle >= 0 && (pool.size() >= _maxIdle)) {
988             shouldDestroy = true;
989         } else if(success) {
990             pool.addLast(new ObjectTimestampPair(obj));
991             _totalIdle++;
992         }
993         notifyAll();
994 
995         if(shouldDestroy) {
996             try {
997                 _factory.destroyObject(key, obj);
998             } catch(Exception e) {
999                 // ignored?
1000             }
1001         }
1002     }
1003 
1004     public synchronized void invalidateObject(Object key, Object obj) throws Exception {
1005         try {
1006             _factory.destroyObject(key, obj);
1007         }
1008         finally {
1009             decrementActiveCount(key);
1010             notifyAll(); // _totalActive has changed
1011         }
1012     }
1013 
1014     public synchronized void addObject(Object key) throws Exception {
1015         Object obj = _factory.makeObject(key);
1016         incrementActiveCount(key); // returnObject will decrement this
1017         returnObject(key,obj);
1018     }
1019 
1020     /***
1021      * Registers a key for pool control.
1022      *
1023      * If <i>populateImmediately</i> is <code>true</code>, the pool will immediately commence
1024      * a sustain cycle. If <i>populateImmediately</i> is <code>false</code>, the pool will be
1025      * populated when the next schedules sustain task is run.
1026      *
1027      * @param key - The key to register for pool control.
1028      * @param populateImmediately - If this is <code>true</code>, the pool
1029      * will start a sustain cycle immediately.
1030      */
1031     public synchronized void preparePool(Object key, boolean populateImmediately) {
1032         LinkedList pool = (LinkedList)(_poolMap.get(key));
1033         if (null == pool) {
1034             pool = new LinkedList();
1035             _poolMap.put(key,pool);
1036         }
1037 
1038         if (populateImmediately) {
1039             try {
1040                 // Create the pooled objects
1041                 ensureMinIdle(key);
1042             }
1043             catch (Exception e) {
1044                 //Do nothing
1045             }
1046         }
1047     }
1048 
1049     public synchronized void close() throws Exception {
1050         clear();
1051         _poolMap = null;
1052         _activeMap = null;
1053         _recentlyEvictedKeys = null;
1054         if(null != _evictor) {
1055             _evictor.cancel();
1056             _evictor = null;
1057         }
1058     }
1059 
1060     public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
1061         if(0 < getNumActive()) {
1062             throw new IllegalStateException("Objects are already active");
1063         } else {
1064             clear();
1065             _factory = factory;
1066         }
1067     }
1068 
1069     public synchronized void evict() throws Exception {
1070         Object key = null;
1071         if (_recentlyEvictedKeys == null) {
1072             _recentlyEvictedKeys = new HashSet(_poolMap.size());
1073         }
1074         Set remainingKeys = new HashSet(_poolMap.keySet());
1075         remainingKeys.removeAll(_recentlyEvictedKeys);
1076         Iterator keyIter = remainingKeys.iterator();
1077 
1078         ListIterator objIter = null;
1079 
1080         for(int i=0,m=getNumTests();i<m;i++) {
1081             if(_poolMap.size() > 0) {
1082                 // Find next idle object pool key to work on
1083                 if (key == null) {
1084                     if (!keyIter.hasNext()) {
1085                         _recentlyEvictedKeys.clear();
1086                         remainingKeys = new HashSet(_poolMap.keySet());
1087                         keyIter = remainingKeys.iterator();
1088                     }
1089                     if (!keyIter.hasNext()) {
1090                         // done, there are no keyed pools
1091                         return;
1092                     }
1093                     key = keyIter.next();
1094                 }
1095 
1096                 // if we don't have a keyed object pool iterator
1097                 if (objIter == null) {
1098                     final LinkedList list = (LinkedList)_poolMap.get(key);
1099                     if (_evictLastIndex < 0 || _evictLastIndex > list.size()) {
1100                         _evictLastIndex = list.size();
1101                     }
1102                     objIter = list.listIterator(_evictLastIndex);
1103                 }
1104 
1105                 // if the _evictionCursor has a previous object, then test it
1106                 if(objIter.hasPrevious()) {
1107                     ObjectTimestampPair pair = (ObjectTimestampPair)(objIter.previous());
1108                     boolean removeObject=false;
1109                     if(_minEvictableIdleTimeMillis > 0 &&
1110                        System.currentTimeMillis() - pair.tstamp > _minEvictableIdleTimeMillis) {
1111                        removeObject=true;
1112                     }
1113                     if(_testWhileIdle && removeObject == false) {
1114                         boolean active = false;
1115                         try {
1116                             _factory.activateObject(key,pair.value);
1117                             active = true;
1118                         } catch(Exception e) {
1119                             removeObject=true;
1120                         }
1121                         if(active) {
1122                             if(!_factory.validateObject(key,pair.value)) {
1123                                 removeObject=true;
1124                             } else {
1125                                 try {
1126                                     _factory.passivateObject(key,pair.value);
1127                                 } catch(Exception e) {
1128                                     removeObject=true;
1129                                 }
1130                             }
1131                         }
1132                     }
1133                     if(removeObject) {
1134                         try {
1135                             objIter.remove();
1136                             _totalIdle--;
1137                             _factory.destroyObject(key,pair.value);
1138 
1139                             // Do not remove the key from the _poolList or _poolmap, even if the list
1140                             // stored in the _poolMap for this key is empty when the
1141                             // {@link #getMinIdle <i>minIdle</i>} is > 0.
1142                             //
1143                             // Otherwise if it was the last object for that key, drop that pool
1144                             if ((_minIdle == 0) && (((LinkedList)(_poolMap.get(key))).isEmpty())) {
1145                                 _poolMap.remove(key);
1146                             }
1147                         } catch(Exception e) {
1148                             ; // ignored
1149                         }
1150                     }
1151                 } else {
1152                     // else done evicting keyed pool
1153                     _recentlyEvictedKeys.add(key);
1154                     _evictLastIndex = -1;
1155                     objIter = null;
1156                 }
1157             }
1158         }
1159     }
1160 
1161     /***
1162      * Iterates through all the known keys and creates any necessary objects to maintain
1163      * the minimum level of pooled objects.
1164      * @see #getMinIdle
1165      * @see #setMinIdle
1166      * @throws Exception If there was an error whilst creating the pooled objects.
1167      */
1168     private synchronized void ensureMinIdle() throws Exception {
1169         Iterator iterator = _poolMap.keySet().iterator();
1170 
1171         //Check if should sustain the pool
1172         if (_minIdle > 0) {
1173             // Loop through all elements in _poolList
1174             // Find out the total number of max active and max idle for that class
1175             // If the number is less than the minIdle, do creation loop to boost numbers
1176             // Increment idle count + 1
1177             while (iterator.hasNext()) {
1178                 //Get the next key to process
1179                 Object key = iterator.next();
1180                 ensureMinIdle(key);
1181             }
1182         }
1183     }
1184 
1185     /***
1186      * Re-creates any needed objects to maintain the minimum levels of
1187      * pooled objects for the specified key.
1188      *
1189      * This method uses {@link #calculateDefecit} to calculate the number
1190      * of objects to be created. {@link #calculateDefecit} can be overridden to
1191      * provide a different method of calculating the number of objects to be
1192      * created.
1193      * @param key The key to process
1194      * @throws Exception If there was an error whilst creating the pooled objects
1195      */
1196     private synchronized void ensureMinIdle(Object key) throws Exception {
1197         // Calculate current pool objects
1198         int numberToCreate = calculateDefecit(key);
1199 
1200         //Create required pool objects, if none to create, this loop will not be run.
1201         for (int i = 0; i < numberToCreate; i++) {
1202             addObject(key);
1203         }
1204     }
1205 
1206     //--- non-public methods ----------------------------------------
1207 
1208     /***
1209      * Start the eviction thread or service, or when
1210      * <i>delay</i> is non-positive, stop it
1211      * if it is already running.
1212      */
1213     protected synchronized void startEvictor(long delay) {
1214         if(null != _evictor) {
1215             _evictor.cancel();
1216             _evictor = null;
1217         }
1218         if(delay > 0) {
1219             _evictor = new Evictor();
1220             GenericObjectPool.EVICTION_TIMER.schedule(_evictor, delay, delay);
1221         }
1222     }
1223 
1224     synchronized String debugInfo() {
1225         StringBuffer buf = new StringBuffer();
1226         buf.append("Active: ").append(getNumActive()).append("\n");
1227         buf.append("Idle: ").append(getNumIdle()).append("\n");
1228         Iterator it = _poolMap.keySet().iterator();
1229         while(it.hasNext()) {
1230             buf.append("\t").append(_poolMap.get(it.next())).append("\n");
1231         }
1232         return buf.toString();
1233     }
1234 
1235     private int getNumTests() {
1236         if(_numTestsPerEvictionRun >= 0) {
1237             return _numTestsPerEvictionRun;
1238         } else {
1239             return(int)(Math.ceil((double)_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
1240         }
1241     }
1242 
1243     private void incrementActiveCount(Object key) {
1244         _totalActive++;
1245         Integer active = (Integer)(_activeMap.get(key));
1246         if(null == active) {
1247             _activeMap.put(key,new Integer(1));
1248         } else {
1249             _activeMap.put(key,new Integer(active.intValue() + 1));
1250         }
1251     }
1252 
1253     private void decrementActiveCount(Object key) {
1254         _totalActive--;
1255         Integer active = (Integer)(_activeMap.get(key));
1256         if(null == active) {
1257             // do nothing, either null or zero is OK
1258         } else if(active.intValue() <= 1) {
1259             _activeMap.remove(key);
1260         } else {
1261             _activeMap.put(key, new Integer(active.intValue() - 1));
1262         }
1263     }
1264 
1265     private int getActiveCount(Object key) {
1266         int active = 0;
1267         Integer act = (Integer)(_activeMap.get(key));
1268         if(null != act) {
1269             active = act.intValue();
1270         }
1271         return active;
1272     }
1273 
1274     /***
1275      * This returns the number of objects to create during the pool
1276      * sustain cycle. This will ensure that the minimum number of idle
1277      * connections is maintained without going past the maxPool value.
1278      * <p>
1279      * This method has been left public so derived classes can override
1280      * the way the defecit is calculated. ie... Increase/decrease the pool
1281      * size at certain times of day to accomodate for usage patterns.
1282      *
1283      * @param key - The key of the pool to calculate the number of
1284      *              objects to be re-created
1285      * @return The number of objects to be created
1286      */
1287     private int calculateDefecit(Object key) {
1288         int objectDefecit = 0;
1289 
1290         //Calculate no of objects needed to be created, in order to have
1291         //the number of pooled objects < maxActive();
1292         objectDefecit = getMinIdle() - getNumIdle(key);
1293         if (getMaxActive() > 0) {
1294             int growLimit = Math.max(0, getMaxActive() - getNumActive(key) - getNumIdle(key));
1295             objectDefecit = Math.min(objectDefecit, growLimit);
1296         }
1297 
1298         // Take the maxTotal limit into account
1299         if (getMaxTotal() > 0) {
1300             int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle());
1301             objectDefecit = Math.min(objectDefecit, growLimit);
1302         }
1303 
1304         return objectDefecit;
1305     }
1306 
1307     //--- inner classes ----------------------------------------------
1308 
1309     /***
1310      * A simple "struct" encapsulating an object instance and a timestamp.
1311      *
1312      * Implements Comparable, objects are sorted from old to new.
1313      *
1314      * This is also used by {@link GenericObjectPool}.
1315      */
1316     static class ObjectTimestampPair implements Comparable {
1317         Object value;
1318         long tstamp;
1319 
1320         ObjectTimestampPair(Object val) {
1321             this(val, System.currentTimeMillis());
1322         }
1323 
1324         ObjectTimestampPair(Object val, long time) {
1325             value = val;
1326             tstamp = time;
1327         }
1328 
1329         public String toString() {
1330             return value + ";" + tstamp;
1331         }
1332 
1333         public int compareTo(Object obj) {
1334             return compareTo((ObjectTimestampPair) obj);
1335         }
1336 
1337         public int compareTo(ObjectTimestampPair other) {
1338             return (int) (this.tstamp - other.tstamp);
1339         }
1340     }
1341 
1342     /***
1343      * The idle object evictor {@link TimerTask}.
1344      * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
1345      */
1346     private class Evictor extends TimerTask {
1347         public void run() {
1348             //Evict from the pool
1349             try {
1350                 evict();
1351             } catch(Exception e) {
1352                 // ignored
1353             }
1354             //Re-create the connections.
1355             try {
1356                 ensureMinIdle();
1357             } catch (Exception e) {
1358                 // ignored
1359             }
1360         }
1361     }
1362 
1363     /***
1364      * A simple "struct" encapsulating the
1365      * configuration information for a {@link GenericKeyedObjectPool}.
1366      * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
1367      * @see GenericKeyedObjectPool#setConfig
1368      */
1369     public static class Config {
1370         public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
1371         public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
1372         public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
1373         public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
1374         public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
1375         public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
1376         public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
1377         public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
1378         public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
1379         public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1380         public int numTestsPerEvictionRun =  GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1381         public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1382     }
1383 
1384     //--- protected attributes ---------------------------------------
1385 
1386     /***
1387      * The cap on the number of idle instances in the pool (per key).
1388      * @see #setMaxIdle
1389      * @see #getMaxIdle
1390      */
1391     private int _maxIdle = DEFAULT_MAX_IDLE;
1392 
1393     /***
1394      * The minimum no of idle objects to keep in the pool (per key)
1395      * @see #setMinIdle
1396      * @see #getMinIdle
1397      */
1398     private int _minIdle = DEFAULT_MIN_IDLE;
1399 
1400     /***
1401      * The cap on the number of active instances from the pool (per key).
1402      * @see #setMaxActive
1403      * @see #getMaxActive
1404      */
1405     private int _maxActive = DEFAULT_MAX_ACTIVE;
1406 
1407     /***
1408      * The cap on the total number of instances from the pool if non-positive.
1409      * @see #setMaxTotal
1410      * @see #getMaxTotal
1411      */
1412     private int _maxTotal = DEFAULT_MAX_TOTAL;
1413     
1414     /***
1415      * The maximum amount of time (in millis) the
1416      * {@link #borrowObject} method should block before throwing
1417      * an exception when the pool is exhausted and the
1418      * {@link #getWhenExhaustedAction "when exhausted" action} is
1419      * {@link #WHEN_EXHAUSTED_BLOCK}.
1420      *
1421      * When less than 0, the {@link #borrowObject} method
1422      * may block indefinitely.
1423      *
1424      * @see #setMaxWait
1425      * @see #getMaxWait
1426      * @see #WHEN_EXHAUSTED_BLOCK
1427      * @see #setWhenExhaustedAction
1428      * @see #getWhenExhaustedAction
1429      */
1430     private long _maxWait = DEFAULT_MAX_WAIT;
1431 
1432     /***
1433      * The action to take when the {@link #borrowObject} method
1434      * is invoked when the pool is exhausted (the maximum number
1435      * of "active" objects has been reached).
1436      *
1437      * @see #WHEN_EXHAUSTED_BLOCK
1438      * @see #WHEN_EXHAUSTED_FAIL
1439      * @see #WHEN_EXHAUSTED_GROW
1440      * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
1441      * @see #setWhenExhaustedAction
1442      * @see #getWhenExhaustedAction
1443      */
1444     private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
1445 
1446     /***
1447      * When <tt>true</tt>, objects will be
1448      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1449      * before being returned by the {@link #borrowObject}
1450      * method.  If the object fails to validate,
1451      * it will be dropped from the pool, and we will attempt
1452      * to borrow another.
1453      *
1454      * @see #setTestOnBorrow
1455      * @see #getTestOnBorrow
1456      */
1457     private boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
1458 
1459     /***
1460      * When <tt>true</tt>, objects will be
1461      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1462      * before being returned to the pool within the
1463      * {@link #returnObject}.
1464      *
1465      * @see #getTestOnReturn
1466      * @see #setTestOnReturn
1467      */
1468     private boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
1469 
1470     /***
1471      * When <tt>true</tt>, objects will be
1472      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1473      * by the idle object evictor (if any).  If an object
1474      * fails to validate, it will be dropped from the pool.
1475      *
1476      * @see #setTestWhileIdle
1477      * @see #getTestWhileIdle
1478      * @see #getTimeBetweenEvictionRunsMillis
1479      * @see #setTimeBetweenEvictionRunsMillis
1480      */
1481     private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
1482 
1483     /***
1484      * The number of milliseconds to sleep between runs of the
1485      * idle object evictor thread.
1486      * When non-positive, no idle object evictor thread will be
1487      * run.
1488      *
1489      * @see #setTimeBetweenEvictionRunsMillis
1490      * @see #getTimeBetweenEvictionRunsMillis
1491      */
1492     private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1493 
1494     /***
1495      * The number of objects to examine during each run of the
1496      * idle object evictor thread (if any).
1497      * <p>
1498      * When a negative value is supplied, <tt>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</tt>
1499      * tests will be run.  I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
1500      * idle objects will be tested per run.
1501      *
1502      * @see #setNumTestsPerEvictionRun
1503      * @see #getNumTestsPerEvictionRun
1504      * @see #getTimeBetweenEvictionRunsMillis
1505      * @see #setTimeBetweenEvictionRunsMillis
1506      */
1507     private int _numTestsPerEvictionRun =  DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1508 
1509     /***
1510      * The minimum amount of time an object may sit idle in the pool
1511      * before it is eligable for eviction by the idle object evictor
1512      * (if any).
1513      * When non-positive, no objects will be evicted from the pool
1514      * due to idle time alone.
1515      *
1516      * @see #setMinEvictableIdleTimeMillis
1517      * @see #getMinEvictableIdleTimeMillis
1518      * @see #getTimeBetweenEvictionRunsMillis
1519      * @see #setTimeBetweenEvictionRunsMillis
1520      */
1521     private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1522 
1523     /*** My hash of pools (CursorableLinkedLists). */
1524     private HashMap _poolMap = null;
1525 
1526     /*** Count of active objects, per key. */
1527     private HashMap _activeMap = null;
1528 
1529     /*** The total number of active instances. */
1530     private int _totalActive = 0;
1531 
1532     /*** The total number of idle instances. */
1533     private int _totalIdle = 0;
1534 
1535     /*** My {@link KeyedPoolableObjectFactory}. */
1536     private KeyedPoolableObjectFactory _factory = null;
1537 
1538     /***
1539      * My idle object eviction {@link TimerTask}, if any.
1540      */
1541     private Evictor _evictor = null;
1542 
1543     /***
1544      * Idle object pool keys that have been evicted recently.
1545      */
1546     private Set _recentlyEvictedKeys = null;
1547 
1548     /***
1549      * Position in the _pool where the _evictor last stopped.
1550      */
1551     private int _evictLastIndex = -1;
1552 }