View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.pool.impl;
19  
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.NoSuchElementException;
24  import java.util.Set;
25  import java.util.TreeMap;
26  import java.util.TimerTask;
27  
28  import org.apache.commons.pool.BaseKeyedObjectPool;
29  import org.apache.commons.pool.KeyedObjectPool;
30  import org.apache.commons.pool.KeyedPoolableObjectFactory;
31  
32  /***
33   * A configurable <code>KeyedObjectPool</code> implementation.
34   * <p>
35   * When coupled with the appropriate {@link KeyedPoolableObjectFactory},
36   * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for
37   * keyed objects. A <code>GenericKeyedObjectPool</code> can be viewed as a map
38   * of pools, keyed on the (unique) key values provided to the 
39   * {@link #preparePool preparePool}, {@link #addObject addObject} or
40   * {@link #borrowObject borrowObject} methods. Each time a new key value is
41   * provided to one of these methods, a new pool is created under the given key
42   * to be managed by the containing <code>GenericKeyedObjectPool.</code>
43   * </p>
44   * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable
45   * parameters:</p>
46   * <ul>
47   *  <li>
48   *    {@link #setMaxActive maxActive} controls the maximum number of objects
49   *    (per key) that can be borrowed from the pool at one time.  When
50   *    non-positive, there is no limit to the number of objects per key.
51   *    When {@link #setMaxActive maxActive} is exceeded, the keyed pool is said
52   *    to be exhausted.  The default setting for this parameter is 8.
53   *  </li>
54   *  <li>
55   *    {@link #setMaxTotal maxTotal} sets a global limit on the number of objects
56   *    that can be in circulation (active or idle) within the combined set of
57   *    pools.  When non-positive, there is no limit to the total number of
58   *    objects in circulation. When {@link #setMaxTotal maxTotal} is exceeded,
59   *    all keyed pools are exhausted. When <code>maxTotal</code> is set to a
60   *    positive value and {@link #borrowObject borrowObject} is invoked
61   *    when at the limit with no idle instances available, an attempt is made to
62   *    create room by clearing the oldest 15% of the elements from the keyed
63   *    pools. The default setting for this parameter is -1 (no limit).
64   *  </li>
65   *  <li>
66   *    {@link #setMaxIdle maxIdle} controls the maximum number of objects that can
67   *    sit idle in the pool (per key) at any time.  When negative, there
68   *    is no limit to the number of objects that may be idle per key. The
69   *    default setting for this parameter is 8.
70   *  </li>
71   *  <li>
72   *    {@link #setWhenExhaustedAction whenExhaustedAction} specifies the
73   *    behavior of the {@link #borrowObject borrowObject} method when a keyed
74   *    pool is exhausted:
75   *    <ul>
76   *    <li>
77   *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
78   *      {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw
79   *      a {@link NoSuchElementException}
80   *    </li>
81   *    <li>
82   *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
83   *      {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new
84   *      object and return it (essentially making {@link #setMaxActive maxActive}
85   *      meaningless.)
86   *    </li>
87   *    <li>
88   *      When {@link #setWhenExhaustedAction whenExhaustedAction}
89   *      is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block
90   *      (invoke {@link Object#wait() wait} until a new or idle object is available.
91   *      If a positive {@link #setMaxWait maxWait}
92   *      value is supplied, the {@link #borrowObject borrowObject} will block for at
93   *      most that many milliseconds, after which a {@link NoSuchElementException}
94   *      will be thrown.  If {@link #setMaxWait maxWait} is non-positive,
95   *      the {@link #borrowObject borrowObject} method will block indefinitely.
96   *    </li>
97   *    </ul>
98   *    The default <code>whenExhaustedAction</code> setting is
99   *    {@link #WHEN_EXHAUSTED_BLOCK}.
100  *  </li>
101  *  <li>
102  *    When {@link #setTestOnBorrow testOnBorrow} is set, the pool will
103  *    attempt to validate each object before it is returned from the
104  *    {@link #borrowObject borrowObject} method. (Using the provided factory's
105  *    {@link KeyedPoolableObjectFactory#validateObject validateObject} method.)
106  *    Objects that fail to validate will be dropped from the pool, and a
107  *    different object will be borrowed. The default setting for this parameter
108  *    is <code>false.</code>
109  *  </li>
110  *  <li>
111  *    When {@link #setTestOnReturn testOnReturn} is set, the pool will
112  *    attempt to validate each object before it is returned to the pool in the
113  *    {@link #returnObject returnObject} method. (Using the provided factory's
114  *    {@link KeyedPoolableObjectFactory#validateObject validateObject}
115  *    method.)  Objects that fail to validate will be dropped from the pool.
116  *    The default setting for this parameter is <code>false.</code>
117  *  </li>
118  * </ul>
119  * <p>
120  * Optionally, one may configure the pool to examine and possibly evict objects
121  * as they sit idle in the pool and to ensure that a minimum number of idle
122  * objects is maintained for each key. This is performed by an
123  * "idle object eviction" thread, which runs asynchronously. Caution should be
124  * used when configuring this optional feature. Eviction runs require an
125  * exclusive synchronization lock on the pool, so if they run too frequently
126  * and / or incur excessive latency when creating, destroying or validating
127  * object instances, performance issues may result.  The idle object eviction
128  * thread may be configured using the following attributes:
129  * <ul>
130  *  <li>
131  *   {@link #setTimeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis}
132  *   indicates how long the eviction thread should sleep before "runs" of examining
133  *   idle objects.  When non-positive, no eviction thread will be launched. The
134  *   default setting for this parameter is -1 (i.e., by default, idle object
135  *   eviction is disabled).
136  *  </li>
137  *  <li>
138  *   {@link #setMinEvictableIdleTimeMillis minEvictableIdleTimeMillis}
139  *   specifies the minimum amount of time that an object may sit idle in the
140  *   pool before it is eligible for eviction due to idle time.  When
141  *   non-positive, no object will be dropped from the pool due to idle time
142  *   alone.  This setting has no effect unless 
143  *   <code>timeBetweenEvictionRunsMillis > 0.</code>  The default setting
144  *   for this parameter is 30 minutes.
145  *  </li>
146  *  <li>
147  *   {@link #setTestWhileIdle testWhileIdle} indicates whether or not idle
148  *   objects should be validated using the factory's
149  *   {@link KeyedPoolableObjectFactory#validateObject validateObject} method
150  *   during idle object eviction runs.  Objects that fail to validate will be
151  *   dropped from the pool. This setting has no effect unless 
152  *   <code>timeBetweenEvictionRunsMillis > 0.</code>  The default setting
153  *   for this parameter is <code>false.</code>
154  *  </li>
155  *  <li>
156  *    {@link #setMinIdle minIdle} sets a target value for the minimum number of
157  *    idle objects (per key) that should always be available. If this parameter
158  *    is set to a positive number and 
159  *    <code>timeBetweenEvictionRunsMillis > 0,</code> each time the idle object
160  *    eviction thread runs, it will try to create enough idle instances so that
161  *    there will be <code>minIdle</code> idle instances available under each
162  *    key. This parameter is also used by {@link #preparePool preparePool}
163  *    if <code>true</code> is provided as that method's
164  *    <code>populateImmediately</code> parameter. The default setting for this
165  *    parameter is 0.
166  *  </li>
167  * </ul>
168  * <p>
169  * The pools can be configured to behave as LIFO queues with respect to idle
170  * objects - always returning the most recently used object from the pool,
171  * or as FIFO queues, where borrowObject always returns the oldest object
172  * in the idle object pool.
173  * <ul>
174  *  <li>
175  *   {@link #setLifo <i>Lifo</i>}
176  *   determines whether or not the pools return idle objects in 
177  *   last-in-first-out order. The default setting for this parameter is 
178  *   <code>true.</code>
179  *  </li>
180  * </ul>
181  * <p>
182  * GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}.  A
183  * non-<code>null</code> factory must be provided either as a constructor argument
184  * or via a call to {@link #setFactory setFactory} before the pool is used.
185  * </p>
186  * @see GenericObjectPool
187  * @author Rodney Waldhoff
188  * @author Dirk Verbeeck
189  * @author Sandy McArthur
190  * @version $Revision: 609416 $ $Date: 2008-01-06 14:46:01 -0700 (Sun, 06 Jan 2008) $
191  * @since Pool 1.0
192  */
193 public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
194 
195     //--- public constants -------------------------------------------
196 
197     /***
198      * A "when exhausted action" type indicating that when the pool is
199      * exhausted (i.e., the maximum number of active objects has
200      * been reached), the {@link #borrowObject}
201      * method should fail, throwing a {@link NoSuchElementException}.
202      * @see #WHEN_EXHAUSTED_BLOCK
203      * @see #WHEN_EXHAUSTED_GROW
204      * @see #setWhenExhaustedAction
205      */
206     public static final byte WHEN_EXHAUSTED_FAIL   = 0;
207 
208     /***
209      * A "when exhausted action" type indicating that when the pool
210      * is exhausted (i.e., the maximum number
211      * of active objects has been reached), the {@link #borrowObject}
212      * method should block until a new object is available, or the
213      * {@link #getMaxWait maximum wait time} has been reached.
214      * @see #WHEN_EXHAUSTED_FAIL
215      * @see #WHEN_EXHAUSTED_GROW
216      * @see #setMaxWait
217      * @see #getMaxWait
218      * @see #setWhenExhaustedAction
219      */
220     public static final byte WHEN_EXHAUSTED_BLOCK  = 1;
221 
222     /***
223      * A "when exhausted action" type indicating that when the pool is
224      * exhausted (i.e., the maximum number
225      * of active objects has been reached), the {@link #borrowObject}
226      * method should simply create a new object anyway.
227      * @see #WHEN_EXHAUSTED_FAIL
228      * @see #WHEN_EXHAUSTED_GROW
229      * @see #setWhenExhaustedAction
230      */
231     public static final byte WHEN_EXHAUSTED_GROW   = 2;
232 
233     /***
234      * The default cap on the number of idle instances (per key) in the pool.
235      * @see #getMaxIdle
236      * @see #setMaxIdle
237      */
238     public static final int DEFAULT_MAX_IDLE  = 8;
239 
240     /***
241      * The default cap on the total number of active instances (per key)
242      * from the pool.
243      * @see #getMaxActive
244      * @see #setMaxActive
245      */
246     public static final int DEFAULT_MAX_ACTIVE  = 8;
247 
248     /***
249      * The default cap on the the overall maximum number of objects that can
250      * exist at one time.
251      * @see #getMaxTotal
252      * @see #setMaxTotal
253      */
254     public static final int DEFAULT_MAX_TOTAL  = -1;
255 
256     /***
257      * The default "when exhausted action" for the pool.
258      * @see #WHEN_EXHAUSTED_BLOCK
259      * @see #WHEN_EXHAUSTED_FAIL
260      * @see #WHEN_EXHAUSTED_GROW
261      * @see #setWhenExhaustedAction
262      */
263     public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
264 
265     /***
266      * The default maximum amount of time (in milliseconds) the
267      * {@link #borrowObject} method should block before throwing
268      * an exception when the pool is exhausted and the
269      * {@link #getWhenExhaustedAction "when exhausted" action} is
270      * {@link #WHEN_EXHAUSTED_BLOCK}.
271      * @see #getMaxWait
272      * @see #setMaxWait
273      */
274     public static final long DEFAULT_MAX_WAIT = -1L;
275 
276     /***
277      * The default "test on borrow" value.
278      * @see #getTestOnBorrow
279      * @see #setTestOnBorrow
280      */
281     public static final boolean DEFAULT_TEST_ON_BORROW = false;
282 
283     /***
284      * The default "test on return" value.
285      * @see #getTestOnReturn
286      * @see #setTestOnReturn
287      */
288     public static final boolean DEFAULT_TEST_ON_RETURN = false;
289 
290     /***
291      * The default "test while idle" value.
292      * @see #getTestWhileIdle
293      * @see #setTestWhileIdle
294      * @see #getTimeBetweenEvictionRunsMillis
295      * @see #setTimeBetweenEvictionRunsMillis
296      */
297     public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
298 
299     /***
300      * The default "time between eviction runs" value.
301      * @see #getTimeBetweenEvictionRunsMillis
302      * @see #setTimeBetweenEvictionRunsMillis
303      */
304     public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
305 
306     /***
307      * The default number of objects to examine per run in the
308      * idle object evictor.
309      * @see #getNumTestsPerEvictionRun
310      * @see #setNumTestsPerEvictionRun
311      * @see #getTimeBetweenEvictionRunsMillis
312      * @see #setTimeBetweenEvictionRunsMillis
313      */
314     public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
315 
316     /***
317      * The default value for {@link #getMinEvictableIdleTimeMillis}.
318      * @see #getMinEvictableIdleTimeMillis
319      * @see #setMinEvictableIdleTimeMillis
320      */
321     public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
322 
323     /***
324      * The default minimum level of idle objects in the pool.
325      * @since Pool 1.3
326      * @see #setMinIdle
327      * @see #getMinIdle
328      */
329     public static final int DEFAULT_MIN_IDLE = 0;
330     
331     /***
332      * The default LIFO status. True means that borrowObject returns the
333      * most recently used ("last in") idle object in a pool (if there are
334      * idle instances available).  False means that pools behave as FIFO
335      * queues - objects are taken from idle object pools in the order that
336      * they are returned.
337      * @see #setLifo
338      */
339     public static final boolean DEFAULT_LIFO = true;
340     
341     //--- constructors -----------------------------------------------
342 
343     /***
344      * Create a new <code>GenericKeyedObjectPool</code> with no factory.
345      *
346      * @see #GenericKeyedObjectPool(KeyedPoolableObjectFactory)
347      * @see #setFactory(KeyedPoolableObjectFactory)
348      */
349     public GenericKeyedObjectPool() {
350         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);
351     }
352 
353     /***
354      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
355      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
356      */
357     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory) {
358         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);
359     }
360 
361     /***
362      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
363      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
364      * @param config a non-<code>null</code> {@link GenericKeyedObjectPool.Config} describing the configuration
365      */
366     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, GenericKeyedObjectPool.Config config) {
367         this(factory,config.maxActive,config.whenExhaustedAction,config.maxWait,config.maxIdle,config.maxTotal, config.minIdle,config.testOnBorrow,config.testOnReturn,config.timeBetweenEvictionRunsMillis,config.numTestsPerEvictionRun,config.minEvictableIdleTimeMillis,config.testWhileIdle,config.lifo);
368     }
369 
370     /***
371      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
372      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
373      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
374      */
375     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive) {
376         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);
377     }
378 
379     /***
380      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
381      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
382      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
383      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
384      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
385      */
386     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait) {
387         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);
388     }
389 
390     /***
391      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
392      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
393      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
394      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
395      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
396      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
397      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
398      */
399     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn) {
400         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);
401     }
402 
403     /***
404      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
405      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
406      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
407      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
408      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
409      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
410      */
411     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) {
412         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);
413     }
414 
415     /***
416      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
417      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
418      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
419      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
420      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
421      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
422      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
423      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
424      */
425     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
426         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);
427     }
428 
429     /***
430      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
431      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
432      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
433      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
434      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
435      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
436      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
437      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
438      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
439      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
440      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
441      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
442      */
443     public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
444         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
445     }
446 
447     /***
448      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
449      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
450      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
451      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
452      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
453      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
454      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
455      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
456      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
457      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
458      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
459      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
460      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
461      */
462     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) {
463         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
464     }
465     
466     /***
467      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
468      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
469      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
470      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
471      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
472      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
473      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
474      * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
475      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
476      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
477      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
478      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
479      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
480      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
481      * @since Pool 1.3
482      */
483     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) {
484         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle, DEFAULT_LIFO);
485     }
486     
487     /***
488      * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
489      * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects if not <code>null</code>
490      * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
491      * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
492      * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
493      * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
494      * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
495      * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
496      * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
497      * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
498      * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
499      * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
500      * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
501      * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
502      * @param lifo whether or not the pools behave as LIFO (last in first out) queues (see {@link #setLifo}) 
503      * @since Pool 1.4
504      */
505     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, boolean lifo) {
506         _factory = factory;
507         _maxActive = maxActive;
508         _lifo = lifo;
509         switch(whenExhaustedAction) {
510             case WHEN_EXHAUSTED_BLOCK:
511             case WHEN_EXHAUSTED_FAIL:
512             case WHEN_EXHAUSTED_GROW:
513                 _whenExhaustedAction = whenExhaustedAction;
514                 break;
515             default:
516                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
517         }
518         _maxWait = maxWait;
519         _maxIdle = maxIdle;
520         _maxTotal = maxTotal;
521         _minIdle = minIdle;
522         _testOnBorrow = testOnBorrow;
523         _testOnReturn = testOnReturn;
524         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
525         _numTestsPerEvictionRun = numTestsPerEvictionRun;
526         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
527         _testWhileIdle = testWhileIdle;
528 
529         _poolMap = new HashMap();
530         _poolList = new CursorableLinkedList();
531 
532         startEvictor(_timeBetweenEvictionRunsMillis);
533     }
534 
535     //--- public methods ---------------------------------------------
536 
537     //--- configuration methods --------------------------------------
538 
539     /***
540      * Returns the cap on the number of active instances per key.
541      * A negative value indicates no limit.
542      * @return the cap on the number of active instances per key.
543      * @see #setMaxActive
544      */
545     public synchronized int getMaxActive() {
546         return _maxActive;
547     }
548 
549     /***
550      * Sets the cap on the number of active instances per key.
551      * @param maxActive The cap on the number of active instances per key.
552      * Use a negative value for no limit.
553      * @see #getMaxActive
554      */
555     public synchronized void setMaxActive(int maxActive) {
556         _maxActive = maxActive;
557         notifyAll();
558     }
559 
560     /***
561      * Returns the overall maximum number of objects (across pools) that can
562      * exist at one time. A negative value indicates no limit.
563      * @return the maximum number of instances in circulation at one time.
564      * @see #setMaxTotal
565      */
566     public synchronized int getMaxTotal() {
567         return _maxTotal;
568     }
569 
570     /***
571      * Sets the cap on the total number of instances from all pools combined.
572      * When <code>maxTotal</code> is set to a
573      * positive value and {@link #borrowObject borrowObject} is invoked
574      * when at the limit with no idle instances available, an attempt is made to
575      * create room by clearing the oldest 15% of the elements from the keyed
576      * pools.
577      * 
578      * @param maxTotal The cap on the total number of instances across pools.
579      * Use a negative value for no limit.
580      * @see #getMaxTotal
581      */
582     public synchronized void setMaxTotal(int maxTotal) {
583         _maxTotal = maxTotal;
584         notifyAll();
585     }
586 
587     /***
588      * Returns the action to take when the {@link #borrowObject} method
589      * is invoked when the pool is exhausted (the maximum number
590      * of "active" objects has been reached).
591      *
592      * @return one of {@link #WHEN_EXHAUSTED_BLOCK}, 
593      * {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
594      * @see #setWhenExhaustedAction
595      */
596     public synchronized byte getWhenExhaustedAction() {
597         return _whenExhaustedAction;
598     }
599 
600     /***
601      * Sets the action to take when the {@link #borrowObject} method
602      * is invoked when the pool is exhausted (the maximum number
603      * of "active" objects has been reached).
604      *
605      * @param whenExhaustedAction the action code, which must be one of
606      *        {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
607      *        or {@link #WHEN_EXHAUSTED_GROW}
608      * @see #getWhenExhaustedAction
609      */
610     public synchronized void setWhenExhaustedAction(byte whenExhaustedAction) {
611         switch(whenExhaustedAction) {
612             case WHEN_EXHAUSTED_BLOCK:
613             case WHEN_EXHAUSTED_FAIL:
614             case WHEN_EXHAUSTED_GROW:
615                 _whenExhaustedAction = whenExhaustedAction;
616                 notifyAll();
617                 break;
618             default:
619                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
620         }
621     }
622 
623 
624     /***
625      * Returns the maximum amount of time (in milliseconds) the
626      * {@link #borrowObject} method should block before throwing
627      * an exception when the pool is exhausted and the
628      * {@link #setWhenExhaustedAction "when exhausted" action} is
629      * {@link #WHEN_EXHAUSTED_BLOCK}.
630      *
631      * When less than or equal to 0, the {@link #borrowObject} method
632      * may block indefinitely.
633      *
634      * @return the maximum number of milliseconds borrowObject will block.
635      * @see #setMaxWait
636      * @see #setWhenExhaustedAction
637      * @see #WHEN_EXHAUSTED_BLOCK
638      */
639     public synchronized long getMaxWait() {
640         return _maxWait;
641     }
642 
643     /***
644      * Sets the maximum amount of time (in milliseconds) the
645      * {@link #borrowObject} method should block before throwing
646      * an exception when the pool is exhausted and the
647      * {@link #setWhenExhaustedAction "when exhausted" action} is
648      * {@link #WHEN_EXHAUSTED_BLOCK}.
649      *
650      * When less than or equal to 0, the {@link #borrowObject} method
651      * may block indefinitely.
652      *
653      * @param maxWait the maximum number of milliseconds borrowObject will block or negative for indefinitely.
654      * @see #getMaxWait
655      * @see #setWhenExhaustedAction
656      * @see #WHEN_EXHAUSTED_BLOCK
657      */
658     public synchronized void setMaxWait(long maxWait) {
659         _maxWait = maxWait;
660     }
661 
662     /***
663      * Returns the cap on the number of "idle" instances per key.
664      * @return the maximum number of "idle" instances that can be held
665      * in a given keyed pool.
666      * @see #setMaxIdle
667      */
668     public synchronized int getMaxIdle() {
669         return _maxIdle;
670     }
671 
672     /***
673      * Sets the cap on the number of "idle" instances in the pool.
674      * @param maxIdle the maximum number of "idle" instances that can be held
675      * in a given keyed pool. Use a negative value for no limit.
676      * @see #getMaxIdle
677      * @see #DEFAULT_MAX_IDLE
678      */
679     public synchronized void setMaxIdle(int maxIdle) {
680         _maxIdle = maxIdle;
681         notifyAll();
682     }
683 
684     /***
685      * Sets the minimum number of idle objects to maintain in each of the keyed
686      * pools. This setting has no effect unless 
687      * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
688      * that each pool has the required minimum number of instances are only
689      * made during idle object eviction runs.
690      * @param poolSize - The minimum size of the each keyed pool
691      * @since Pool 1.3
692      * @see #getMinIdle
693      * @see #setTimeBetweenEvictionRunsMillis
694      */
695     public synchronized void setMinIdle(int poolSize) {
696         _minIdle = poolSize;
697     }
698 
699     /***
700      * Returns the minimum number of idle objects to maintain in each of the keyed
701      * pools. This setting has no effect unless 
702      * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
703      * that each pool has the required minimum number of instances are only
704      * made during idle object eviction runs.
705      * @return minimum size of the each keyed pool
706      * @since Pool 1.3
707      * @see #setTimeBetweenEvictionRunsMillis
708      */
709     public synchronized int getMinIdle() {
710         return _minIdle;
711     }
712 
713     /***
714      * When <code>true</code>, objects will be
715      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
716      * before being returned by the {@link #borrowObject}
717      * method.  If the object fails to validate,
718      * it will be dropped from the pool, and we will attempt
719      * to borrow another.
720      *
721      * @return <code>true</code> if objects are validated before being borrowed.
722      * @see #setTestOnBorrow
723      */
724     public boolean getTestOnBorrow() {
725         return _testOnBorrow;
726     }
727 
728     /***
729      * When <code>true</code>, objects will be
730      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
731      * before being returned by the {@link #borrowObject}
732      * method.  If the object fails to validate,
733      * it will be dropped from the pool, and we will attempt
734      * to borrow another.
735      *
736      * @param testOnBorrow whether object should be validated before being returned by borrowObject.
737      * @see #getTestOnBorrow
738      */
739     public void setTestOnBorrow(boolean testOnBorrow) {
740         _testOnBorrow = testOnBorrow;
741     }
742 
743     /***
744      * When <code>true</code>, objects will be
745      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
746      * before being returned to the pool within the
747      * {@link #returnObject}.
748      *
749      * @return <code>true</code> when objects will be validated before being returned.
750      * @see #setTestOnReturn
751      */
752     public boolean getTestOnReturn() {
753         return _testOnReturn;
754     }
755 
756     /***
757      * When <code>true</code>, objects will be
758      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
759      * before being returned to the pool within the
760      * {@link #returnObject}.
761      *
762      * @param testOnReturn <code>true</code> so objects will be validated before being returned.
763      * @see #getTestOnReturn
764      */
765     public void setTestOnReturn(boolean testOnReturn) {
766         _testOnReturn = testOnReturn;
767     }
768 
769     /***
770      * Returns the number of milliseconds to sleep between runs of the
771      * idle object evictor thread.
772      * When non-positive, no idle object evictor thread will be
773      * run.
774      *
775      * @return milliseconds to sleep between evictor runs.
776      * @see #setTimeBetweenEvictionRunsMillis
777      */
778     public synchronized long getTimeBetweenEvictionRunsMillis() {
779         return _timeBetweenEvictionRunsMillis;
780     }
781 
782     /***
783      * Sets the number of milliseconds to sleep between runs of the
784      * idle object evictor thread.
785      * When non-positive, no idle object evictor thread will be
786      * run.
787      *
788      * @param timeBetweenEvictionRunsMillis milliseconds to sleep between evictor runs.
789      * @see #getTimeBetweenEvictionRunsMillis
790      */
791     public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
792         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
793         startEvictor(_timeBetweenEvictionRunsMillis);
794     }
795 
796     /***
797      * Returns the number of objects to examine during each run of the
798      * idle object evictor thread (if any).
799      *
800      * @return number of objects to examine each eviction run.
801      * @see #setNumTestsPerEvictionRun
802      * @see #setTimeBetweenEvictionRunsMillis
803      */
804     public synchronized int getNumTestsPerEvictionRun() {
805         return _numTestsPerEvictionRun;
806     }
807 
808     /***
809      * Sets the number of objects to examine during each run of the
810      * idle object evictor thread (if any).
811      * <p>
812      * When a negative value is supplied, <code>ceil({@link #getNumIdle()})/abs({@link #getNumTestsPerEvictionRun})</code>
813      * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
814      * idle objects will be tested per run.
815      *
816      * @param numTestsPerEvictionRun number of objects to examine each eviction run.
817      * @see #getNumTestsPerEvictionRun
818      * @see #setTimeBetweenEvictionRunsMillis
819      */
820     public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
821         _numTestsPerEvictionRun = numTestsPerEvictionRun;
822     }
823 
824     /***
825      * Returns the minimum amount of time an object may sit idle in the pool
826      * before it is eligible for eviction by the idle object evictor
827      * (if any).
828      *
829      * @return minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
830      * @see #setMinEvictableIdleTimeMillis
831      * @see #setTimeBetweenEvictionRunsMillis
832      */
833     public synchronized long getMinEvictableIdleTimeMillis() {
834         return _minEvictableIdleTimeMillis;
835     }
836 
837     /***
838      * Sets the minimum amount of time an object may sit idle in the pool
839      * before it is eligible for eviction by the idle object evictor
840      * (if any).
841      * When non-positive, no objects will be evicted from the pool
842      * due to idle time alone.
843      *
844      * @param minEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
845      * @see #getMinEvictableIdleTimeMillis
846      * @see #setTimeBetweenEvictionRunsMillis
847      */
848     public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
849         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
850     }
851 
852     /***
853      * When <code>true</code>, objects will be
854      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
855      * by the idle object evictor (if any).  If an object
856      * fails to validate, it will be dropped from the pool.
857      *
858      * @return <code>true</code> when objects are validated when borrowed.
859      * @see #setTestWhileIdle
860      * @see #setTimeBetweenEvictionRunsMillis
861      */
862     public synchronized boolean getTestWhileIdle() {
863         return _testWhileIdle;
864     }
865 
866     /***
867      * When <code>true</code>, objects will be
868      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
869      * by the idle object evictor (if any).  If an object
870      * fails to validate, it will be dropped from the pool.
871      *
872      * @param testWhileIdle <code>true</code> so objects are validated when borrowed.
873      * @see #getTestWhileIdle
874      * @see #setTimeBetweenEvictionRunsMillis
875      */
876     public synchronized void setTestWhileIdle(boolean testWhileIdle) {
877         _testWhileIdle = testWhileIdle;
878     }
879 
880     /***
881      * Sets the configuration.
882      * @param conf the new configuration to use.
883      * @see GenericKeyedObjectPool.Config
884      */
885     public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
886         setMaxIdle(conf.maxIdle);
887         setMaxActive(conf.maxActive);
888         setMaxTotal(conf.maxTotal);
889         setMinIdle(conf.minIdle);
890         setMaxWait(conf.maxWait);
891         setWhenExhaustedAction(conf.whenExhaustedAction);
892         setTestOnBorrow(conf.testOnBorrow);
893         setTestOnReturn(conf.testOnReturn);
894         setTestWhileIdle(conf.testWhileIdle);
895         setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
896         setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
897         setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
898     }
899     
900     /***
901      * Whether or not the idle object pools act as LIFO queues. True means
902      * that borrowObject returns the most recently used ("last in") idle object
903      * in a pool (if there are idle instances available).  False means that
904      * the pools behave as FIFO queues - objects are taken from idle object
905      * pools in the order that they are returned.
906      * 
907      * @return <code>true</code> if the pools are configured to act as LIFO queues
908      * @since 1.4
909      */
910      public synchronized boolean getLifo() {
911          return _lifo;
912      }
913 
914      /***
915       * Sets the LIFO property of the pools. True means that borrowObject returns
916       * the most recently used ("last in") idle object in a pool (if there are
917       * idle instances available).  False means that the pools behave as FIFO
918       * queues - objects are taken from idle object pools in the order that
919       * they are returned.
920       * 
921       * @param lifo the new value for the lifo property
922       * @since 1.4
923       */
924      public synchronized void setLifo(boolean lifo) {
925          this._lifo = lifo;
926      }
927 
928     //-- ObjectPool methods ------------------------------------------
929 
930     public Object borrowObject(Object key) throws Exception {
931         long starttime = System.currentTimeMillis();
932         boolean newlyCreated = false;
933         for(;;) {
934             ObjectTimestampPair pair = null;
935             ObjectQueue pool = null;
936             synchronized (this) {
937                 assertOpen();
938                 pool = (ObjectQueue)(_poolMap.get(key));
939                 if(null == pool) {
940                     pool = new ObjectQueue();
941                     _poolMap.put(key,pool);
942                     _poolList.add(key);
943                 }
944                 // if there are any sleeping, just grab one of those
945                 try {
946                     pair = (ObjectTimestampPair)(pool.queue.removeFirst());
947                     if(null != pair) {
948                         _totalIdle--;
949                     }
950                 } catch(NoSuchElementException e) { /* ignored */
951                 }
952                 // otherwise
953                 if(null == pair) {
954                     // if there is a totalMaxActive and we are at the limit then
955                     // we have to make room
956                     if ((_maxTotal > 0) && (_totalActive + _totalIdle >= _maxTotal)) {
957                         clearOldest();
958                     }
959     
960                     // check if we can create one
961                     // (note we know that the num sleeping is 0, else we wouldn't be here)
962                     if ((_maxActive < 0 || pool.activeCount < _maxActive) &&
963                         (_maxTotal < 0 || _totalActive + _totalIdle < _maxTotal)) {
964                         Object obj = _factory.makeObject(key);
965                         pair = new ObjectTimestampPair(obj);
966                         newlyCreated = true;
967                     } else {
968                         // the pool is exhausted
969                         switch(_whenExhaustedAction) {
970                             case WHEN_EXHAUSTED_GROW:
971                                 Object obj = _factory.makeObject(key);
972                                 pair = new ObjectTimestampPair(obj);
973                                 break;
974                             case WHEN_EXHAUSTED_FAIL:
975                                 throw new NoSuchElementException();
976                             case WHEN_EXHAUSTED_BLOCK:
977                                 try {
978                                     if(_maxWait <= 0) {
979                                         wait();
980                                     } else {
981                                         // this code may be executed again after a notify then continue cycle
982                                         // so, need to calculate the amount of time to wait
983                                         final long elapsed = (System.currentTimeMillis() - starttime);
984                                         final long waitTime = _maxWait - elapsed;
985                                         if (waitTime > 0)
986                                         {
987                                             wait(waitTime);
988                                         }
989                                     }
990                                 } catch(InterruptedException e) {
991                                     // ignored
992                                 }
993                                 if(_maxWait > 0 && ((System.currentTimeMillis() - starttime) >= _maxWait)) {
994                                     throw new NoSuchElementException("Timeout waiting for idle object");
995                                 } else {
996                                     continue; // keep looping
997                                 }
998                             default:
999                                 throw new IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + " not recognized.");
1000                         }
1001                     }
1002                 }
1003                 pool.incrementActiveCount();
1004             }
1005             
1006             // Activate.  If activate fails, decrement active count and destroy.
1007             // If instance failing activation is new, throw NoSuchElementException;
1008             // otherwise keep looping
1009             try {
1010                 _factory.activateObject(key, pair.value);
1011             } catch (Exception e) {
1012                 try {
1013                     _factory.destroyObject(key,pair.value);
1014                     synchronized (this) {
1015                         pool.decrementActiveCount();
1016                     }
1017                 } catch (Exception e2) {
1018                     // swallowed
1019                 }
1020                 if(newlyCreated) {
1021                     throw new NoSuchElementException(
1022                        "Could not create a validated object, cause: "
1023                             + e.getMessage());
1024                 }
1025                 else {
1026                     continue; // keep looping
1027                 }
1028             }
1029 
1030             // Validate.  If validation fails, decrement active count and
1031             // destroy. If instance failing validation is new, throw
1032             // NoSuchElementException; otherwise keep looping
1033             boolean invalid = true;
1034             try {
1035                 invalid = _testOnBorrow && !_factory.validateObject(key, pair.value);
1036             } catch (Exception e) {
1037                 // swallowed
1038             }
1039             if (invalid) {
1040                 try {
1041                     _factory.destroyObject(key,pair.value);
1042                     synchronized (this) {
1043                         pool.decrementActiveCount();
1044                     }
1045                 } catch (Exception e) {
1046                     // swallowed
1047                 }
1048                 if(newlyCreated) {
1049                     throw new NoSuchElementException("Could not create a validated object");
1050                 } // else keep looping
1051             } else {
1052                 return pair.value;
1053             }
1054         }
1055     }
1056 
1057     /***
1058      * Clears the pool, removing all pooled instances.
1059      */
1060     public synchronized void clear() {
1061         for(Iterator entries = _poolMap.entrySet().iterator(); entries.hasNext(); ) {
1062             final Map.Entry entry = (Map.Entry)entries.next();
1063             final Object key = entry.getKey();
1064             final CursorableLinkedList list = ((ObjectQueue)(entry.getValue())).queue;
1065             for(Iterator it = list.iterator(); it.hasNext(); ) {
1066                 try {
1067                     _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
1068                 } catch(Exception e) {
1069                     // ignore error, keep destroying the rest
1070                 }
1071                 it.remove();
1072             }
1073         }
1074         _poolMap.clear();
1075         _poolList.clear();
1076         _totalIdle = 0;
1077         notifyAll();
1078     }
1079 
1080     /***
1081      * Method clears oldest 15% of objects in pool.  The method sorts the
1082      * objects into a TreeMap and then iterates the first 15% for removal
1083      * @since Pool 1.3
1084      */
1085     public synchronized void clearOldest() {
1086         // build sorted map of idle objects
1087         final Map map = new TreeMap();
1088         for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
1089             final Object key = keyiter.next();
1090             final CursorableLinkedList list = ((ObjectQueue)_poolMap.get(key)).queue;
1091             for (Iterator it = list.iterator(); it.hasNext();) {
1092                 // each item into the map uses the objectimestamppair object
1093                 // as the key.  It then gets sorted based on the timstamp field
1094                 // each value in the map is the parent list it belongs in.
1095                 map.put(it.next(), key);
1096             }
1097         }
1098 
1099         // Now iterate created map and kill the first 15% plus one to account for zero
1100         Set setPairKeys = map.entrySet();
1101         int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
1102 
1103         Iterator iter = setPairKeys.iterator();
1104         while (iter.hasNext() && itemsToRemove > 0) {
1105             Map.Entry entry = (Map.Entry) iter.next();
1106             // kind of backwards on naming.  In the map, each key is the objecttimestamppair
1107             // because it has the ordering with the timestamp value.  Each value that the
1108             // key references is the key of the list it belongs to.
1109             Object key = entry.getValue();
1110             ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
1111             final CursorableLinkedList list = 
1112                 ((ObjectQueue)(_poolMap.get(key))).queue;
1113             list.remove(pairTimeStamp);
1114 
1115             try {
1116                 _factory.destroyObject(key, pairTimeStamp.value);
1117             } catch (Exception e) {
1118                 // ignore error, keep destroying the rest
1119             }
1120             // if that was the last object for that key, drop that pool
1121             if (list.isEmpty()) {
1122                 _poolMap.remove(key);
1123                 _poolList.remove(key);
1124             }
1125             _totalIdle--;
1126             itemsToRemove--;
1127         }
1128         notifyAll();
1129     }
1130 
1131     /***
1132      * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
1133      *
1134      * @param key the key to clear
1135      */
1136     public synchronized void clear(Object key) {
1137         final ObjectQueue pool = (ObjectQueue)(_poolMap.remove(key));
1138         if(null == pool) {
1139             return;
1140         } else {
1141             _poolList.remove(key);
1142             for(Iterator it = pool.queue.iterator(); it.hasNext(); ) {
1143                 try {
1144                     _factory.destroyObject(key,((ObjectTimestampPair)(it.next())).value);
1145                 } catch(Exception e) {
1146                     // ignore error, keep destroying the rest
1147                 }
1148                 it.remove();
1149                 _totalIdle--;
1150             }
1151         }
1152         
1153         notifyAll();
1154     }
1155 
1156     /***
1157      * Returns the total number of instances current borrowed from this pool but not yet returned.
1158      *
1159      * @return the total number of instances currently borrowed from this pool
1160      */
1161     public synchronized int getNumActive() {
1162         return _totalActive;
1163     }
1164 
1165     /***
1166      * Returns the total number of instances currently idle in this pool.
1167      *
1168      * @return the total number of instances currently idle in this pool
1169      */
1170     public synchronized int getNumIdle() {
1171         return _totalIdle;
1172     }
1173 
1174     /***
1175      * Returns the number of instances currently borrowed from but not yet returned
1176      * to the pool corresponding to the given <code>key</code>.
1177      *
1178      * @param key the key to query
1179      * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
1180      */
1181     public synchronized int getNumActive(Object key) {
1182         final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1183         return pool != null ? pool.activeCount : 0;
1184     }
1185 
1186     /***
1187      * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
1188      *
1189      * @param key the key to query
1190      * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
1191      */
1192     public synchronized int getNumIdle(Object key) {
1193         final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1194         return pool != null ? pool.queue.size() : 0;
1195     }
1196 
1197     public void returnObject(Object key, Object obj) throws Exception {
1198         try {
1199             addObjectToPool(key, obj, true);
1200         } catch (Exception e) {
1201             if (_factory != null) {
1202                 try {
1203                     _factory.destroyObject(key, obj);
1204                 } catch (Exception e2) {
1205                     // swallowed
1206                 }
1207                 // TODO: Correctness here depends on control in addObjectToPool.
1208                 // These two methods should be refactored, removing the 
1209                 // "behavior flag",decrementNumActive, from addObjectToPool.
1210                 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1211                 if (pool != null) {
1212                     synchronized(this) {
1213                         pool.decrementActiveCount();
1214                         notifyAll();
1215                     }  
1216                 }
1217             }
1218         }
1219     }
1220 
1221     private void addObjectToPool(Object key, Object obj,
1222             boolean decrementNumActive) throws Exception {
1223 
1224         // if we need to validate this object, do so
1225         boolean success = true; // whether or not this object passed validation
1226         if(_testOnReturn && !_factory.validateObject(key, obj)) {
1227             success = false;
1228         } else {
1229             _factory.passivateObject(key, obj);
1230         }
1231 
1232         boolean shouldDestroy = !success;
1233         ObjectQueue pool;
1234         
1235         // Add instance to pool if there is room and it has passed validation
1236         // (if testOnreturn is set)
1237         synchronized (this) {
1238             // grab the pool (list) of objects associated with the given key
1239             pool = (ObjectQueue) (_poolMap.get(key));
1240             // if it doesn't exist, create it
1241             if(null == pool) {
1242                 pool = new ObjectQueue();
1243                 _poolMap.put(key, pool);
1244                 _poolList.add(key);
1245             }
1246             if (isClosed()) {
1247                 shouldDestroy = true;
1248             } else {
1249                 // if there's no space in the pool, flag the object for destruction
1250                 // else if we passivated successfully, return it to the pool
1251                 if(_maxIdle >= 0 && (pool.queue.size() >= _maxIdle)) {
1252                     shouldDestroy = true;
1253                 } else if(success) {
1254                     // borrowObject always takes the first element from the queue,
1255                     // so for LIFO, push on top, FIFO add to end
1256                     if (_lifo) {
1257                         pool.queue.addFirst(new ObjectTimestampPair(obj)); 
1258                     } else {
1259                         pool.queue.addLast(new ObjectTimestampPair(obj));
1260                     }
1261                     _totalIdle++;
1262                 }
1263             }
1264         }
1265 
1266         // Destroy the instance if necessary 
1267         if(shouldDestroy) {
1268             try {
1269                 _factory.destroyObject(key, obj);
1270             } catch(Exception e) {
1271                 // ignored?
1272             }
1273         }
1274         
1275         // Decrement active count *after* destroy if applicable
1276         if (decrementNumActive) {
1277             synchronized(this) {
1278                 pool.decrementActiveCount();
1279                 notifyAll();
1280             }
1281         }
1282     }
1283 
1284     public void invalidateObject(Object key, Object obj) throws Exception {
1285         try {
1286             _factory.destroyObject(key, obj);
1287         } finally {
1288             synchronized (this) {
1289                 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1290                 if(null == pool) {
1291                     pool = new ObjectQueue();
1292                     _poolMap.put(key, pool);
1293                     _poolList.add(key);
1294                 }
1295                 pool.decrementActiveCount();
1296                 notifyAll(); // _totalActive has changed
1297             }
1298         }
1299     }
1300 
1301     /***
1302      * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
1303      * passivate it, and then place it in the idle object pool.
1304      * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
1305      *
1306      * @param key the key a new instance should be added to
1307      * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
1308      * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been called on this pool.
1309      */
1310     public void addObject(Object key) throws Exception {
1311         assertOpen();
1312         if (_factory == null) {
1313             throw new IllegalStateException("Cannot add objects without a factory.");
1314         }
1315         Object obj = _factory.makeObject(key);
1316         synchronized (this) {
1317             try {
1318                 assertOpen();
1319                 addObjectToPool(key, obj, false);
1320             } catch (IllegalStateException ex) { // Pool closed
1321                 try {
1322                     _factory.destroyObject(key, obj);
1323                 } catch (Exception ex2) {
1324                     // swallow
1325                 }
1326                 throw ex;
1327             }
1328         }
1329     }
1330 
1331     /***
1332      * Registers a key for pool control.
1333      *
1334      * If <code>populateImmediately</code> is <code>true</code> and
1335      * <code>minIdle > 0,</code> the pool under the given key will be
1336      * populated immediately with <code>minIdle</code> idle instances.
1337      *
1338      * @param key - The key to register for pool control.
1339      * @param populateImmediately - If this is <code>true</code>, the pool
1340      * will be populated immediately.
1341      * @since Pool 1.3
1342      */
1343     public synchronized void preparePool(Object key, boolean populateImmediately) {
1344         ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1345         if (null == pool) {
1346             pool = new ObjectQueue();
1347             _poolMap.put(key,pool);
1348             _poolList.add(key);
1349         }
1350 
1351         if (populateImmediately) {
1352             try {
1353                 // Create the pooled objects
1354                 ensureMinIdle(key);
1355             }
1356             catch (Exception e) {
1357                 //Do nothing
1358             }
1359         }
1360     }
1361 
1362     public void close() throws Exception {
1363         super.close();
1364         synchronized (this) {
1365             clear();
1366             if(null != _evictionCursor) {
1367                 _evictionCursor.close();
1368                 _evictionCursor = null;
1369             }
1370             if(null != _evictionKeyCursor) {
1371                 _evictionKeyCursor.close();
1372                 _evictionKeyCursor = null;
1373             }
1374             startEvictor(-1L);
1375         }
1376     }
1377 
1378     public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
1379         assertOpen();
1380         if(0 < getNumActive()) {
1381             throw new IllegalStateException("Objects are already active");
1382         } else {
1383             clear();
1384             _factory = factory;
1385         }
1386     }
1387 
1388     /***
1389      * <p>Perform <code>numTests</code> idle object eviction tests, evicting
1390      * examined objects that meet the criteria for eviction. If 
1391      * <code>testWhileIdle</code> is true, examined objects are validated
1392      * when visited (and removed if invalid); otherwise only objects that
1393      * have been idle for more than <code>minEvicableIdletimeMillis</code>
1394      * are removed.</p>
1395      * 
1396      * <p>Successive activations of this method examine objects in keyed pools
1397      * in sequence, cycling through the keys and examining objects in
1398      * oldest-to-youngest order within the keyed pools.</p>
1399      *
1400      * @throws Exception when there is a problem evicting idle objects.
1401      */
1402     public synchronized void evict() throws Exception {
1403         // Initialize key to last key value
1404         Object key = null;
1405         if (_evictionKeyCursor != null && 
1406                 _evictionKeyCursor._lastReturned != null) {
1407             key = _evictionKeyCursor._lastReturned.value();
1408         }
1409         
1410         for (int i=0,m=getNumTests(); i<m; i++) {
1411             // make sure pool map is not empty; otherwise do nothing
1412             if (_poolMap == null || _poolMap.size() == 0) {
1413                 continue;
1414             }
1415 
1416             // if we don't have a key cursor, then create one
1417             if (null == _evictionKeyCursor) {
1418                 resetEvictionKeyCursor();
1419                 key = null;
1420             }
1421 
1422             // if we don't have an object cursor, create one
1423             if (null == _evictionCursor) {
1424                 // if the _evictionKeyCursor has a next value, use this key
1425                 if (_evictionKeyCursor.hasNext()) {
1426                     key = _evictionKeyCursor.next();
1427                     resetEvictionObjectCursor(key);
1428                 } else {
1429                     // Reset the key cursor and try again
1430                     resetEvictionKeyCursor();
1431                     if (_evictionKeyCursor != null) {
1432                         if (_evictionKeyCursor.hasNext()) {
1433                             key = _evictionKeyCursor.next();
1434                             resetEvictionObjectCursor(key);
1435                         }
1436                     }
1437                 }
1438             }  
1439 
1440             if (_evictionCursor == null) {
1441                 continue; // should never happen; do nothing
1442             }
1443 
1444             // If eviction cursor is exhausted, try to move
1445             // to the next key and reset
1446             if((_lifo && !_evictionCursor.hasPrevious()) ||
1447                     (!_lifo && !_evictionCursor.hasNext())) {
1448                 if (_evictionKeyCursor != null) {
1449                     if (_evictionKeyCursor.hasNext()) {
1450                         key = _evictionKeyCursor.next();
1451                         resetEvictionObjectCursor(key);
1452                     } else { // Need to reset Key cursor
1453                         resetEvictionKeyCursor();
1454                         if (_evictionKeyCursor != null) {
1455                             if (_evictionKeyCursor.hasNext()) {
1456                                 key = _evictionKeyCursor.next();
1457                                 resetEvictionObjectCursor(key);
1458                             }
1459                         }
1460                     }
1461                 }
1462             }
1463 
1464             if((_lifo && !_evictionCursor.hasPrevious()) ||
1465                     (!_lifo && !_evictionCursor.hasNext())) {
1466                 continue; // reset failed, do nothing
1467             }
1468 
1469             // if LIFO and the _evictionCursor has a previous object, 
1470             // or FIFO and _evictionCursor has a next object, test it
1471             ObjectTimestampPair pair = _lifo ? 
1472                     (ObjectTimestampPair) _evictionCursor.previous() : 
1473                     (ObjectTimestampPair) _evictionCursor.next();
1474             boolean removeObject=false;
1475             if((_minEvictableIdleTimeMillis > 0) &&
1476                (System.currentTimeMillis() - pair.tstamp > 
1477                _minEvictableIdleTimeMillis)) {
1478                 removeObject=true;
1479             }
1480             if(_testWhileIdle && removeObject == false) {
1481                 boolean active = false;
1482                 try {
1483                     _factory.activateObject(key,pair.value);
1484                     active = true;
1485                 } catch(Exception e) {
1486                     removeObject=true;
1487                 }
1488                 if(active) {
1489                     if(!_factory.validateObject(key,pair.value)) {
1490                         removeObject=true;
1491                     } else {
1492                         try {
1493                             _factory.passivateObject(key,pair.value);
1494                         } catch(Exception e) {
1495                             removeObject=true;
1496                         }
1497                     }
1498                 }
1499             }
1500             if(removeObject) {
1501                 try {
1502                     _evictionCursor.remove();
1503                     _totalIdle--;
1504                     _factory.destroyObject(key, pair.value);
1505                     // Do not remove the key from the _poolList or _poolmap,
1506                     // even if the list stored in the _poolMap for this key is
1507                     // empty when minIdle > 0.
1508                     //
1509                     // Otherwise if it was the last object for that key,
1510                     // drop that pool
1511                     if (_minIdle == 0) {
1512                         ObjectQueue objectQueue = 
1513                             (ObjectQueue)_poolMap.get(key);
1514                         if (objectQueue != null && 
1515                                 objectQueue.queue.isEmpty()) {
1516                             _poolMap.remove(key);
1517                             _poolList.remove(key);  
1518                         }
1519                     }
1520                 } catch(Exception e) {
1521                     ; // ignored
1522                 }
1523             }
1524         }
1525     }
1526     
1527     /***
1528      * Resets the eviction key cursor and closes any
1529      * associated eviction object cursor
1530      */
1531     private void resetEvictionKeyCursor() {
1532         if (_evictionKeyCursor != null) {
1533             _evictionKeyCursor.close();
1534         }
1535         _evictionKeyCursor = _poolList.cursor();
1536         if (null != _evictionCursor) {
1537             _evictionCursor.close();
1538             _evictionCursor = null;
1539         }  
1540     }
1541     
1542     /***
1543      * Resets the eviction object cursor for the given key
1544      * 
1545      * @param key eviction key
1546      */
1547     private void resetEvictionObjectCursor(Object key) {
1548         if (_evictionCursor != null) {
1549             _evictionCursor.close();
1550         }
1551         if (_poolMap == null) { 
1552             return;
1553         }
1554         ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1555         if (pool != null) {
1556             CursorableLinkedList queue = 
1557                 (CursorableLinkedList)(pool.queue);
1558             _evictionCursor = queue.cursor(_lifo ? queue.size() : 0);   
1559         }
1560     }
1561 
1562     /***
1563      * Iterates through all the known keys and creates any necessary objects to maintain
1564      * the minimum level of pooled objects.
1565      * @see #getMinIdle
1566      * @see #setMinIdle
1567      * @throws Exception If there was an error whilst creating the pooled objects.
1568      */
1569     private synchronized void ensureMinIdle() throws Exception {
1570         Iterator iterator = _poolMap.keySet().iterator();
1571 
1572         //Check if should sustain the pool
1573         if (_minIdle > 0) {
1574             // Loop through all elements in _poolList
1575             // Find out the total number of max active and max idle for that class
1576             // If the number is less than the minIdle, do creation loop to boost numbers
1577             // Increment idle count + 1
1578             while (iterator.hasNext()) {
1579                 //Get the next key to process
1580                 Object key = iterator.next();
1581                 ensureMinIdle(key);
1582             }
1583         }
1584     }
1585 
1586     /***
1587      * Re-creates any needed objects to maintain the minimum levels of
1588      * pooled objects for the specified key.
1589      *
1590      * This method uses {@link #calculateDefecit} to calculate the number
1591      * of objects to be created. {@link #calculateDefecit} can be overridden to
1592      * provide a different method of calculating the number of objects to be
1593      * created.
1594      * @param key The key to process
1595      * @throws Exception If there was an error whilst creating the pooled objects
1596      */
1597     private synchronized void ensureMinIdle(Object key) throws Exception {
1598         // Calculate current pool objects
1599         int numberToCreate = calculateDefecit(key);
1600 
1601         //Create required pool objects, if none to create, this loop will not be run.
1602         for (int i = 0; i < numberToCreate; i++) {
1603             addObject(key);
1604         }
1605     }
1606 
1607     //--- non-public methods ----------------------------------------
1608 
1609     /***
1610      * Start the eviction thread or service, or when
1611      * <code>delay</code> is non-positive, stop it
1612      * if it is already running.
1613      *
1614      * @param delay milliseconds between evictor runs.
1615      */
1616     protected synchronized void startEvictor(long delay) {
1617         if(null != _evictor) {
1618             EvictionTimer.cancel(_evictor);
1619             _evictor = null;
1620         }
1621         if(delay > 0) {
1622             _evictor = new Evictor();
1623             EvictionTimer.schedule(_evictor, delay, delay);
1624         }
1625     }
1626 
1627     synchronized String debugInfo() {
1628         StringBuffer buf = new StringBuffer();
1629         buf.append("Active: ").append(getNumActive()).append("\n");
1630         buf.append("Idle: ").append(getNumIdle()).append("\n");
1631         Iterator it = _poolMap.keySet().iterator();
1632         while(it.hasNext()) {
1633             buf.append("\t").append(_poolMap.get(it.next())).append("\n");
1634         }
1635         return buf.toString();
1636     }
1637 
1638     private int getNumTests() {
1639         if(_numTestsPerEvictionRun >= 0) {
1640             return _numTestsPerEvictionRun;
1641         } else {
1642             return(int)(Math.ceil((double)_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
1643         }
1644     }
1645 
1646     /***
1647      * This returns the number of objects to create during the pool
1648      * sustain cycle. This will ensure that the minimum number of idle
1649      * connections is maintained without going past the maxPool value.
1650      * <p>
1651      * This method has been left public so derived classes can override
1652      * the way the defecit is calculated. ie... Increase/decrease the pool
1653      * size at certain times of day to accomodate for usage patterns.
1654      *
1655      * @param key - The key of the pool to calculate the number of
1656      *              objects to be re-created
1657      * @return The number of objects to be created
1658      */
1659     private int calculateDefecit(Object key) {
1660         int objectDefecit = 0;
1661 
1662         //Calculate no of objects needed to be created, in order to have
1663         //the number of pooled objects < maxActive();
1664         objectDefecit = getMinIdle() - getNumIdle(key);
1665         if (getMaxActive() > 0) {
1666             int growLimit = Math.max(0, getMaxActive() - getNumActive(key) - getNumIdle(key));
1667             objectDefecit = Math.min(objectDefecit, growLimit);
1668         }
1669 
1670         // Take the maxTotal limit into account
1671         if (getMaxTotal() > 0) {
1672             int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle());
1673             objectDefecit = Math.min(objectDefecit, growLimit);
1674         }
1675 
1676         return objectDefecit;
1677     }
1678 
1679     //--- inner classes ----------------------------------------------
1680 
1681     /***
1682      * A "struct" that keeps additional information about the actual queue of pooled objects.
1683      */
1684     private class ObjectQueue {
1685         private int activeCount = 0;
1686         private final CursorableLinkedList queue = new CursorableLinkedList();
1687 
1688         void incrementActiveCount() {
1689             _totalActive++;
1690             activeCount++;
1691         }
1692 
1693         void decrementActiveCount() {
1694             _totalActive--;
1695             if (activeCount > 0) {
1696                 activeCount--;
1697             }
1698         }
1699     }
1700     
1701     /***
1702      * A simple "struct" encapsulating an object instance and a timestamp.
1703      *
1704      * Implements Comparable, objects are sorted from old to new.
1705      *
1706      * This is also used by {@link GenericObjectPool}.
1707      */
1708     static class ObjectTimestampPair implements Comparable {
1709         Object value;
1710         long tstamp;
1711 
1712         ObjectTimestampPair(Object val) {
1713             this(val, System.currentTimeMillis());
1714         }
1715 
1716         ObjectTimestampPair(Object val, long time) {
1717             value = val;
1718             tstamp = time;
1719         }
1720 
1721         public String toString() {
1722             return value + ";" + tstamp;
1723         }
1724 
1725         public int compareTo(Object obj) {
1726             return compareTo((ObjectTimestampPair) obj);
1727         }
1728 
1729         public int compareTo(ObjectTimestampPair other) {
1730             final long tstampdiff = this.tstamp - other.tstamp;
1731             if (tstampdiff == 0) {
1732                 // make sure the natural ordering is consistent with equals
1733                 // see java.lang.Comparable Javadocs
1734                 return System.identityHashCode(this) - System.identityHashCode(other);
1735             } else {
1736                 // handle int overflow
1737                 return (int)Math.min(Math.max(tstampdiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
1738             }
1739         }
1740     }
1741 
1742     /***
1743      * The idle object evictor {@link TimerTask}.
1744      * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
1745      */
1746     private class Evictor extends TimerTask {
1747         public void run() {
1748             //Evict from the pool
1749             try {
1750                 evict();
1751             } catch(Exception e) {
1752                 // ignored
1753             }
1754             //Re-create the connections.
1755             try {
1756                 ensureMinIdle();
1757             } catch (Exception e) {
1758                 // ignored
1759             }
1760         }
1761     }
1762 
1763     /***
1764      * A simple "struct" encapsulating the
1765      * configuration information for a <code>GenericKeyedObjectPool</code>.
1766      * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
1767      * @see GenericKeyedObjectPool#setConfig
1768      */
1769     public static class Config {
1770         /***
1771          * @see GenericKeyedObjectPool#setMaxIdle
1772          */
1773         public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
1774         /***
1775          * @see GenericKeyedObjectPool#setMaxActive
1776          */
1777         public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
1778         /***
1779          * @see GenericKeyedObjectPool#setMaxTotal
1780          */
1781         public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
1782         /***
1783          * @see GenericKeyedObjectPool#setMinIdle
1784          */
1785         public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
1786         /***
1787          * @see GenericKeyedObjectPool#setMaxWait
1788          */
1789         public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
1790         /***
1791          * @see GenericKeyedObjectPool#setWhenExhaustedAction
1792          */
1793         public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
1794         /***
1795          * @see GenericKeyedObjectPool#setTestOnBorrow
1796          */
1797         public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
1798         /***
1799          * @see GenericKeyedObjectPool#setTestOnReturn
1800          */
1801         public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
1802         /***
1803          * @see GenericKeyedObjectPool#setTestWhileIdle
1804          */
1805         public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
1806         /***
1807          * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
1808          */
1809         public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1810         /***
1811          * @see GenericKeyedObjectPool#setNumTestsPerEvictionRun
1812          */
1813         public int numTestsPerEvictionRun =  GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1814         /***
1815          * @see GenericKeyedObjectPool#setMinEvictableIdleTimeMillis
1816          */
1817         public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1818         /***
1819          * @see GenericKeyedObjectPool#setLifo
1820          */
1821         public boolean lifo = GenericKeyedObjectPool.DEFAULT_LIFO;
1822     }
1823 
1824     //--- protected attributes ---------------------------------------
1825 
1826     /***
1827      * The cap on the number of idle instances in the pool.
1828      * @see #setMaxIdle
1829      * @see #getMaxIdle
1830      */
1831     private int _maxIdle = DEFAULT_MAX_IDLE;
1832 
1833     /***
1834      * The minimum no of idle objects to keep in the pool.
1835      * @see #setMinIdle
1836      * @see #getMinIdle
1837      */
1838     private int _minIdle = DEFAULT_MIN_IDLE;
1839 
1840     /***
1841      * The cap on the number of active instances from the pool.
1842      * @see #setMaxActive
1843      * @see #getMaxActive
1844      */
1845     private int _maxActive = DEFAULT_MAX_ACTIVE;
1846 
1847     /***
1848      * The cap on the total number of instances from the pool if non-positive.
1849      * @see #setMaxTotal
1850      * @see #getMaxTotal
1851      */
1852     private int _maxTotal = DEFAULT_MAX_TOTAL;
1853     
1854     /***
1855      * The maximum amount of time (in millis) the
1856      * {@link #borrowObject} method should block before throwing
1857      * an exception when the pool is exhausted and the
1858      * {@link #getWhenExhaustedAction "when exhausted" action} is
1859      * {@link #WHEN_EXHAUSTED_BLOCK}.
1860      *
1861      * When less than or equal to 0, the {@link #borrowObject} method
1862      * may block indefinitely.
1863      *
1864      * @see #setMaxWait
1865      * @see #getMaxWait
1866      * @see #WHEN_EXHAUSTED_BLOCK
1867      * @see #setWhenExhaustedAction
1868      * @see #getWhenExhaustedAction
1869      */
1870     private long _maxWait = DEFAULT_MAX_WAIT;
1871 
1872     /***
1873      * The action to take when the {@link #borrowObject} method
1874      * is invoked when the pool is exhausted (the maximum number
1875      * of "active" objects has been reached).
1876      *
1877      * @see #WHEN_EXHAUSTED_BLOCK
1878      * @see #WHEN_EXHAUSTED_FAIL
1879      * @see #WHEN_EXHAUSTED_GROW
1880      * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
1881      * @see #setWhenExhaustedAction
1882      * @see #getWhenExhaustedAction
1883      */
1884     private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
1885 
1886     /***
1887      * When <code>true</code>, objects will be
1888      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1889      * before being returned by the {@link #borrowObject}
1890      * method.  If the object fails to validate,
1891      * it will be dropped from the pool, and we will attempt
1892      * to borrow another.
1893      *
1894      * @see #setTestOnBorrow
1895      * @see #getTestOnBorrow
1896      */
1897     private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
1898 
1899     /***
1900      * When <code>true</code>, objects will be
1901      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1902      * before being returned to the pool within the
1903      * {@link #returnObject}.
1904      *
1905      * @see #getTestOnReturn
1906      * @see #setTestOnReturn
1907      */
1908     private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
1909 
1910     /***
1911      * When <code>true</code>, objects will be
1912      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
1913      * by the idle object evictor (if any).  If an object
1914      * fails to validate, it will be dropped from the pool.
1915      *
1916      * @see #setTestWhileIdle
1917      * @see #getTestWhileIdle
1918      * @see #getTimeBetweenEvictionRunsMillis
1919      * @see #setTimeBetweenEvictionRunsMillis
1920      */
1921     private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
1922 
1923     /***
1924      * The number of milliseconds to sleep between runs of the
1925      * idle object evictor thread.
1926      * When non-positive, no idle object evictor thread will be
1927      * run.
1928      *
1929      * @see #setTimeBetweenEvictionRunsMillis
1930      * @see #getTimeBetweenEvictionRunsMillis
1931      */
1932     private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
1933 
1934     /***
1935      * The number of objects to examine during each run of the
1936      * idle object evictor thread (if any).
1937      * <p>
1938      * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
1939      * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
1940      * idle objects will be tested per run.
1941      *
1942      * @see #setNumTestsPerEvictionRun
1943      * @see #getNumTestsPerEvictionRun
1944      * @see #getTimeBetweenEvictionRunsMillis
1945      * @see #setTimeBetweenEvictionRunsMillis
1946      */
1947     private int _numTestsPerEvictionRun =  DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
1948 
1949     /***
1950      * The minimum amount of time an object may sit idle in the pool
1951      * before it is eligible for eviction by the idle object evictor
1952      * (if any).
1953      * When non-positive, no objects will be evicted from the pool
1954      * due to idle time alone.
1955      *
1956      * @see #setMinEvictableIdleTimeMillis
1957      * @see #getMinEvictableIdleTimeMillis
1958      * @see #getTimeBetweenEvictionRunsMillis
1959      * @see #setTimeBetweenEvictionRunsMillis
1960      */
1961     private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
1962 
1963     /*** My hash of pools (ObjectQueue). */
1964     private Map _poolMap = null;
1965 
1966     /*** The total number of active instances. */
1967     private int _totalActive = 0;
1968 
1969     /*** The total number of idle instances. */
1970     private int _totalIdle = 0;
1971 
1972     /*** My {@link KeyedPoolableObjectFactory}. */
1973     private KeyedPoolableObjectFactory _factory = null;
1974 
1975     /***
1976      * My idle object eviction {@link TimerTask}, if any.
1977      */
1978     private Evictor _evictor = null;
1979 
1980     /***
1981      * A cursorable list of my pools.
1982      * @see GenericKeyedObjectPool.Evictor#run
1983      */
1984     private CursorableLinkedList _poolList = null;
1985     
1986     private CursorableLinkedList.Cursor _evictionCursor = null;
1987     private CursorableLinkedList.Cursor _evictionKeyCursor = null;
1988     
1989     /*** Whether or not the pools behave as LIFO queues (last in first out) */
1990     private boolean _lifo = DEFAULT_LIFO;
1991 }