001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.pool.impl;
019    
020    import java.util.ArrayList;
021    import java.util.Collection;
022    import java.util.HashMap;
023    import java.util.Iterator;
024    import java.util.LinkedList;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.NoSuchElementException;
028    import java.util.Set;
029    import java.util.TreeMap;
030    import java.util.TimerTask;
031    import java.util.Map.Entry;
032    
033    import org.apache.commons.pool.BaseKeyedObjectPool;
034    import org.apache.commons.pool.KeyedObjectPool;
035    import org.apache.commons.pool.KeyedPoolableObjectFactory;
036    import org.apache.commons.pool.PoolUtils;
037    
038    /**
039     * A configurable <code>KeyedObjectPool</code> implementation.
040     * <p>
041     * When coupled with the appropriate {@link KeyedPoolableObjectFactory},
042     * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for
043     * keyed objects. A <code>GenericKeyedObjectPool</code> can be viewed as a map
044     * of pools, keyed on the (unique) key values provided to the
045     * {@link #preparePool preparePool}, {@link #addObject addObject} or
046     * {@link #borrowObject borrowObject} methods. Each time a new key value is
047     * provided to one of these methods, a new pool is created under the given key
048     * to be managed by the containing <code>GenericKeyedObjectPool.</code>
049     * </p>
050     * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable
051     * parameters:</p>
052     * <ul>
053     *  <li>
054     *    {@link #setMaxActive maxActive} controls the maximum number of objects
055     *    (per key) that can allocated by the pool (checked out to client threads,
056     *    or idle in the pool) at one time.  When non-positive, there is no limit
057     *    to the number of objects per key. When {@link #setMaxActive maxActive} is
058     *    reached, the keyed pool is said to be exhausted.  The default setting for
059     *    this parameter is 8.
060     *  </li>
061     *  <li>
062     *    {@link #setMaxTotal maxTotal} sets a global limit on the number of objects
063     *    that can be in circulation (active or idle) within the combined set of
064     *    pools.  When non-positive, there is no limit to the total number of
065     *    objects in circulation. When {@link #setMaxTotal maxTotal} is exceeded,
066     *    all keyed pools are exhausted. When <code>maxTotal</code> is set to a
067     *    positive value and {@link #borrowObject borrowObject} is invoked
068     *    when at the limit with no idle instances available, an attempt is made to
069     *    create room by clearing the oldest 15% of the elements from the keyed
070     *    pools. The default setting for this parameter is -1 (no limit).
071     *  </li>
072     *  <li>
073     *    {@link #setMaxIdle maxIdle} controls the maximum number of objects that can
074     *    sit idle in the pool (per key) at any time.  When negative, there
075     *    is no limit to the number of objects that may be idle per key. The
076     *    default setting for this parameter is 8.
077     *  </li>
078     *  <li>
079     *    {@link #setWhenExhaustedAction whenExhaustedAction} specifies the
080     *    behavior of the {@link #borrowObject borrowObject} method when a keyed
081     *    pool is exhausted:
082     *    <ul>
083     *    <li>
084     *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
085     *      {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw
086     *      a {@link NoSuchElementException}
087     *    </li>
088     *    <li>
089     *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
090     *      {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new
091     *      object and return it (essentially making {@link #setMaxActive maxActive}
092     *      meaningless.)
093     *    </li>
094     *    <li>
095     *      When {@link #setWhenExhaustedAction whenExhaustedAction}
096     *      is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block
097     *      (invoke {@link Object#wait() wait} until a new or idle object is available.
098     *      If a positive {@link #setMaxWait maxWait}
099     *      value is supplied, the {@link #borrowObject borrowObject} will block for at
100     *      most that many milliseconds, after which a {@link NoSuchElementException}
101     *      will be thrown.  If {@link #setMaxWait maxWait} is non-positive,
102     *      the {@link #borrowObject borrowObject} method will block indefinitely.
103     *    </li>
104     *    </ul>
105     *    The default <code>whenExhaustedAction</code> setting is
106     *    {@link #WHEN_EXHAUSTED_BLOCK}.
107     *  </li>
108     *  <li>
109     *    When {@link #setTestOnBorrow testOnBorrow} is set, the pool will
110     *    attempt to validate each object before it is returned from the
111     *    {@link #borrowObject borrowObject} method. (Using the provided factory's
112     *    {@link KeyedPoolableObjectFactory#validateObject validateObject} method.)
113     *    Objects that fail to validate will be dropped from the pool, and a
114     *    different object will be borrowed. The default setting for this parameter
115     *    is <code>false.</code>
116     *  </li>
117     *  <li>
118     *    When {@link #setTestOnReturn testOnReturn} is set, the pool will
119     *    attempt to validate each object before it is returned to the pool in the
120     *    {@link #returnObject returnObject} method. (Using the provided factory's
121     *    {@link KeyedPoolableObjectFactory#validateObject validateObject}
122     *    method.)  Objects that fail to validate will be dropped from the pool.
123     *    The default setting for this parameter is <code>false.</code>
124     *  </li>
125     * </ul>
126     * <p>
127     * Optionally, one may configure the pool to examine and possibly evict objects
128     * as they sit idle in the pool and to ensure that a minimum number of idle
129     * objects is maintained for each key. This is performed by an
130     * "idle object eviction" thread, which runs asynchronously. Caution should be
131     * used when configuring this optional feature. Eviction runs contend with client
132     * threads for access to objects in the pool, so if they run too frequently
133     * performance issues may result.  The idle object eviction thread may be
134     * configured using the following attributes:
135     * <ul>
136     *  <li>
137     *   {@link #setTimeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis}
138     *   indicates how long the eviction thread should sleep before "runs" of examining
139     *   idle objects.  When non-positive, no eviction thread will be launched. The
140     *   default setting for this parameter is -1 (i.e., by default, idle object
141     *   eviction is disabled).
142     *  </li>
143     *  <li>
144     *   {@link #setMinEvictableIdleTimeMillis minEvictableIdleTimeMillis}
145     *   specifies the minimum amount of time that an object may sit idle in the
146     *   pool before it is eligible for eviction due to idle time.  When
147     *   non-positive, no object will be dropped from the pool due to idle time
148     *   alone.  This setting has no effect unless
149     *   <code>timeBetweenEvictionRunsMillis > 0.</code>  The default setting
150     *   for this parameter is 30 minutes.
151     *  </li>
152     *  <li>
153     *   {@link #setTestWhileIdle testWhileIdle} indicates whether or not idle
154     *   objects should be validated using the factory's
155     *   {@link KeyedPoolableObjectFactory#validateObject validateObject} method
156     *   during idle object eviction runs.  Objects that fail to validate will be
157     *   dropped from the pool. This setting has no effect unless
158     *   <code>timeBetweenEvictionRunsMillis > 0.</code>  The default setting
159     *   for this parameter is <code>false.</code>
160     *  </li>
161     *  <li>
162     *    {@link #setMinIdle minIdle} sets a target value for the minimum number of
163     *    idle objects (per key) that should always be available. If this parameter
164     *    is set to a positive number and
165     *    <code>timeBetweenEvictionRunsMillis > 0,</code> each time the idle object
166     *    eviction thread runs, it will try to create enough idle instances so that
167     *    there will be <code>minIdle</code> idle instances available under each
168     *    key. This parameter is also used by {@link #preparePool preparePool}
169     *    if <code>true</code> is provided as that method's
170     *    <code>populateImmediately</code> parameter. The default setting for this
171     *    parameter is 0.
172     *  </li>
173     * </ul>
174     * <p>
175     * The pools can be configured to behave as LIFO queues with respect to idle
176     * objects - always returning the most recently used object from the pool,
177     * or as FIFO queues, where borrowObject always returns the oldest object
178     * in the idle object pool.
179     * <ul>
180     *  <li>
181     *   {@link #setLifo <i>Lifo</i>}
182     *   determines whether or not the pools return idle objects in
183     *   last-in-first-out order. The default setting for this parameter is
184     *   <code>true.</code>
185     *  </li>
186     * </ul>
187     * <p>
188     * GenericKeyedObjectPool is not usable without a {@link KeyedPoolableObjectFactory}.  A
189     * non-<code>null</code> factory must be provided either as a constructor argument
190     * or via a call to {@link #setFactory setFactory} before the pool is used.
191     * </p>
192     * <p>
193     * Implementation note: To prevent possible deadlocks, care has been taken to
194     * ensure that no call to a factory method will occur within a synchronization
195     * block. See POOL-125 and DBCP-44 for more information.
196     * </p>
197     * @see GenericObjectPool
198     * @author Rodney Waldhoff
199     * @author Dirk Verbeeck
200     * @author Sandy McArthur
201     * @version $Revision: 1086190 $ $Date: 2011-03-28 04:22:08 -0700 (Mon, 28 Mar 2011) $
202     * @since Pool 1.0
203     */
204    public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
205    
206        //--- public constants -------------------------------------------
207    
208        /**
209         * A "when exhausted action" type indicating that when the pool is
210         * exhausted (i.e., the maximum number of active objects has
211         * been reached), the {@link #borrowObject}
212         * method should fail, throwing a {@link NoSuchElementException}.
213         * @see #WHEN_EXHAUSTED_BLOCK
214         * @see #WHEN_EXHAUSTED_GROW
215         * @see #setWhenExhaustedAction
216         */
217        public static final byte WHEN_EXHAUSTED_FAIL   = 0;
218    
219        /**
220         * A "when exhausted action" type indicating that when the pool
221         * is exhausted (i.e., the maximum number
222         * of active objects has been reached), the {@link #borrowObject}
223         * method should block until a new object is available, or the
224         * {@link #getMaxWait maximum wait time} has been reached.
225         * @see #WHEN_EXHAUSTED_FAIL
226         * @see #WHEN_EXHAUSTED_GROW
227         * @see #setMaxWait
228         * @see #getMaxWait
229         * @see #setWhenExhaustedAction
230         */
231        public static final byte WHEN_EXHAUSTED_BLOCK  = 1;
232    
233        /**
234         * A "when exhausted action" type indicating that when the pool is
235         * exhausted (i.e., the maximum number
236         * of active objects has been reached), the {@link #borrowObject}
237         * method should simply create a new object anyway.
238         * @see #WHEN_EXHAUSTED_FAIL
239         * @see #WHEN_EXHAUSTED_GROW
240         * @see #setWhenExhaustedAction
241         */
242        public static final byte WHEN_EXHAUSTED_GROW   = 2;
243    
244        /**
245         * The default cap on the number of idle instances (per key) in the pool.
246         * @see #getMaxIdle
247         * @see #setMaxIdle
248         */
249        public static final int DEFAULT_MAX_IDLE  = 8;
250    
251        /**
252         * The default cap on the total number of active instances (per key)
253         * from the pool.
254         * @see #getMaxActive
255         * @see #setMaxActive
256         */
257        public static final int DEFAULT_MAX_ACTIVE  = 8;
258    
259        /**
260         * The default cap on the the overall maximum number of objects that can
261         * exist at one time.
262         * @see #getMaxTotal
263         * @see #setMaxTotal
264         */
265        public static final int DEFAULT_MAX_TOTAL  = -1;
266    
267        /**
268         * The default "when exhausted action" for the pool.
269         * @see #WHEN_EXHAUSTED_BLOCK
270         * @see #WHEN_EXHAUSTED_FAIL
271         * @see #WHEN_EXHAUSTED_GROW
272         * @see #setWhenExhaustedAction
273         */
274        public static final byte DEFAULT_WHEN_EXHAUSTED_ACTION = WHEN_EXHAUSTED_BLOCK;
275    
276        /**
277         * The default maximum amount of time (in milliseconds) the
278         * {@link #borrowObject} method should block before throwing
279         * an exception when the pool is exhausted and the
280         * {@link #getWhenExhaustedAction "when exhausted" action} is
281         * {@link #WHEN_EXHAUSTED_BLOCK}.
282         * @see #getMaxWait
283         * @see #setMaxWait
284         */
285        public static final long DEFAULT_MAX_WAIT = -1L;
286    
287        /**
288         * The default "test on borrow" value.
289         * @see #getTestOnBorrow
290         * @see #setTestOnBorrow
291         */
292        public static final boolean DEFAULT_TEST_ON_BORROW = false;
293    
294        /**
295         * The default "test on return" value.
296         * @see #getTestOnReturn
297         * @see #setTestOnReturn
298         */
299        public static final boolean DEFAULT_TEST_ON_RETURN = false;
300    
301        /**
302         * The default "test while idle" value.
303         * @see #getTestWhileIdle
304         * @see #setTestWhileIdle
305         * @see #getTimeBetweenEvictionRunsMillis
306         * @see #setTimeBetweenEvictionRunsMillis
307         */
308        public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
309    
310        /**
311         * The default "time between eviction runs" value.
312         * @see #getTimeBetweenEvictionRunsMillis
313         * @see #setTimeBetweenEvictionRunsMillis
314         */
315        public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
316    
317        /**
318         * The default number of objects to examine per run in the
319         * idle object evictor.
320         * @see #getNumTestsPerEvictionRun
321         * @see #setNumTestsPerEvictionRun
322         * @see #getTimeBetweenEvictionRunsMillis
323         * @see #setTimeBetweenEvictionRunsMillis
324         */
325        public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
326    
327        /**
328         * The default value for {@link #getMinEvictableIdleTimeMillis}.
329         * @see #getMinEvictableIdleTimeMillis
330         * @see #setMinEvictableIdleTimeMillis
331         */
332        public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
333    
334        /**
335         * The default minimum level of idle objects in the pool.
336         * @since Pool 1.3
337         * @see #setMinIdle
338         * @see #getMinIdle
339         */
340        public static final int DEFAULT_MIN_IDLE = 0;
341    
342        /**
343         * The default LIFO status. True means that borrowObject returns the
344         * most recently used ("last in") idle object in a pool (if there are
345         * idle instances available).  False means that pools behave as FIFO
346         * queues - objects are taken from idle object pools in the order that
347         * they are returned.
348         * @see #setLifo
349         */
350        public static final boolean DEFAULT_LIFO = true;
351    
352        //--- constructors -----------------------------------------------
353    
354        /**
355         * Create a new <code>GenericKeyedObjectPool</code> with no factory.
356         *
357         * @see #GenericKeyedObjectPool(KeyedPoolableObjectFactory)
358         * @see #setFactory(KeyedPoolableObjectFactory)
359         */
360        public GenericKeyedObjectPool() {
361            this(null, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE, 
362                    DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
363                    DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
364        }
365    
366        /**
367         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
368         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy
369         * objects if not <code>null</code>
370         */
371        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory) {
372            this(factory, DEFAULT_MAX_ACTIVE, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE,
373                    DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
374                    DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
375        }
376    
377        /**
378         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
379         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
380         * if not <code>null</code>
381         * @param config a non-<code>null</code> {@link GenericKeyedObjectPool.Config} describing the configuration
382         */
383        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, GenericKeyedObjectPool.Config config) {
384            this(factory, config.maxActive, config.whenExhaustedAction, config.maxWait, config.maxIdle, config.maxTotal,
385                    config.minIdle, config.testOnBorrow, config.testOnReturn, config.timeBetweenEvictionRunsMillis,
386                    config.numTestsPerEvictionRun, config.minEvictableIdleTimeMillis, config.testWhileIdle, config.lifo);
387        }
388    
389        /**
390         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
391         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
392         * 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         */
395        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive) {
396            this(factory,maxActive, DEFAULT_WHEN_EXHAUSTED_ACTION, DEFAULT_MAX_WAIT, DEFAULT_MAX_IDLE,
397                    DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 
398                    DEFAULT_NUM_TESTS_PER_EVICTION_RUN, DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
399        }
400    
401        /**
402         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
403         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
404         * if not <code>null</code>
405         * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
406         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
407         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
408         *  <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
409         */
410        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
411                long maxWait) {
412            this(factory, maxActive, whenExhaustedAction, maxWait, DEFAULT_MAX_IDLE, DEFAULT_TEST_ON_BORROW,
413                    DEFAULT_TEST_ON_RETURN, DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
414                    DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
415        }
416    
417        /**
418         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
419         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
420         * if not <code>null</code>
421         * @param maxActive the maximum number of objects that can be borrowed from me at one time (see {@link #setMaxActive})
422         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
423         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
424         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
425         * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
426         * method (see {@link #setTestOnBorrow})
427         * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
428         * method (see {@link #setTestOnReturn})
429         */
430        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
431                long maxWait, boolean testOnBorrow, boolean testOnReturn) {
432            this(factory, maxActive, whenExhaustedAction, maxWait, DEFAULT_MAX_IDLE,testOnBorrow,testOnReturn,
433                    DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
434                    DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
435        }
436    
437        /**
438         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
439         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
440         * if not <code>null</code>
441         * @param maxActive the maximum number of objects that can be borrowed from me at one time
442         * (see {@link #setMaxActive})
443         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
444         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
445         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
446         * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
447         */
448        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
449                long maxWait, int maxIdle) {
450            this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, DEFAULT_TEST_ON_BORROW, DEFAULT_TEST_ON_RETURN,
451                    DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
452                    DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
453        }
454    
455        /**
456         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
457         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
458         * if not <code>null</code>
459         * @param maxActive the maximum number of objects that can be borrowed from me at one time
460         * (see {@link #setMaxActive})
461         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
462         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
463         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #getMaxWait})
464         * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
465         * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
466         * method (see {@link #setTestOnBorrow})
467         * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
468         * method (see {@link #setTestOnReturn})
469         */
470        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
471                long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
472            this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, testOnBorrow, testOnReturn,
473                    DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
474                    DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, DEFAULT_TEST_WHILE_IDLE);
475        }
476    
477        /**
478         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
479         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
480         * if not <code>null</code>
481         * @param maxActive the maximum number of objects that can be borrowed from me at one time
482         * (see {@link #setMaxActive})
483         * @param whenExhaustedAction the action to take when the pool is exhausted 
484         * (see {@link #setWhenExhaustedAction})
485         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
486         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
487         * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
488         * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
489         * method (see {@link #setTestOnBorrow})
490         * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
491         * method (see {@link #setTestOnReturn})
492         * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
493         * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
494         * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
495         * thread (if any) (see {@link #setNumTestsPerEvictionRun})
496         * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before
497         * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
498         * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
499         * (see {@link #setTestWhileIdle})
500         */
501        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
502                long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis,
503                int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
504            this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,
505                    testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
506                    minEvictableIdleTimeMillis, testWhileIdle);
507        }
508    
509        /**
510         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
511         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
512         * if not <code>null</code>
513         * @param maxActive the maximum number of objects that can be borrowed from me at one time
514         * (see {@link #setMaxActive})
515         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
516         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
517         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
518         * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
519         * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
520         * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
521         * method (see {@link #setTestOnBorrow})
522         * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
523         * method (see {@link #setTestOnReturn})
524         * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
525         * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
526         * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
527         * thread (if any) (see {@link #setNumTestsPerEvictionRun})
528         * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool
529         * before it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
530         * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
531         * (see {@link #setTestWhileIdle})
532         */
533        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
534                long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn,
535                long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis,
536                boolean testWhileIdle) {
537            this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal,
538                    GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis,
539                    numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
540        }
541    
542        /**
543         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
544         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
545         * if not <code>null</code>
546         * @param maxActive the maximum number of objects that can be borrowed at one time (see {@link #setMaxActive})
547         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
548         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
549         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
550         * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
551         * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
552         * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
553         * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
554         * method (see {@link #setTestOnBorrow})
555         * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
556         * method (see {@link #setTestOnReturn})
557         * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
558         * objects
559         * for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
560         * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
561         * thread (if any) (see {@link #setNumTestsPerEvictionRun})
562         * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before
563         * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
564         * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
565         * (see {@link #setTestWhileIdle})
566         * @since Pool 1.3
567         */
568        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
569                long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn,
570                long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis,
571                boolean testWhileIdle) {
572            this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn,
573                    timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle,
574                    DEFAULT_LIFO);
575        }
576    
577        /**
578         * Create a new <code>GenericKeyedObjectPool</code> using the specified values.
579         * @param factory the <code>KeyedPoolableObjectFactory</code> to use to create, validate, and destroy objects
580         * if not <code>null</code>
581         * @param maxActive the maximum number of objects that can be borrowed at one time
582         *  (see {@link #setMaxActive})
583         * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
584         * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted and
585         * <code>whenExhaustedAction</code> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
586         * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
587         * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
588         * @param minIdle the minimum number of idle objects to have in the pool at any one time (see {@link #setMinIdle})
589         * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject}
590         * method (see {@link #setTestOnBorrow})
591         * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject}
592         * method (see {@link #setTestOnReturn})
593         * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle
594         * objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
595         * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction
596         * thread (if any) (see {@link #setNumTestsPerEvictionRun})
597         * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before
598         * it is eligible for eviction (see {@link #setMinEvictableIdleTimeMillis})
599         * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any
600         * (see {@link #setTestWhileIdle})
601         * @param lifo whether or not the pools behave as LIFO (last in first out) queues (see {@link #setLifo})
602         * @since Pool 1.4
603         */
604        public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction,
605                long maxWait, int maxIdle, int maxTotal, int minIdle, boolean testOnBorrow, boolean testOnReturn,
606                long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis,
607                boolean testWhileIdle, boolean lifo) {
608            _factory = factory;
609            _maxActive = maxActive;
610            _lifo = lifo;
611            switch (whenExhaustedAction) {
612                case WHEN_EXHAUSTED_BLOCK:
613                case WHEN_EXHAUSTED_FAIL:
614                case WHEN_EXHAUSTED_GROW:
615                    _whenExhaustedAction = whenExhaustedAction;
616                    break;
617                default:
618                    throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
619            }
620            _maxWait = maxWait;
621            _maxIdle = maxIdle;
622            _maxTotal = maxTotal;
623            _minIdle = minIdle;
624            _testOnBorrow = testOnBorrow;
625            _testOnReturn = testOnReturn;
626            _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
627            _numTestsPerEvictionRun = numTestsPerEvictionRun;
628            _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
629            _testWhileIdle = testWhileIdle;
630    
631            _poolMap = new HashMap();
632            _poolList = new CursorableLinkedList();
633    
634            startEvictor(_timeBetweenEvictionRunsMillis);
635        }
636    
637        //--- public methods ---------------------------------------------
638    
639        //--- configuration methods --------------------------------------
640    
641        /**
642         * Returns the cap on the number of object instances allocated by the pool
643         * (checked out or idle),  per key.
644         * A negative value indicates no limit.
645         *
646         * @return the cap on the number of active instances per key.
647         * @see #setMaxActive
648         */
649        public synchronized int getMaxActive() {
650            return _maxActive;
651        }
652    
653        /**
654         * Sets the cap on the number of object instances managed by the pool per key.
655         * @param maxActive The cap on the number of object instances per key.
656         * Use a negative value for no limit.
657         *
658         * @see #getMaxActive
659         */
660        public void setMaxActive(int maxActive) {
661            synchronized(this) {
662                _maxActive = maxActive;
663            }
664            allocate();
665        }
666    
667        /**
668         * Returns the overall maximum number of objects (across pools) that can
669         * exist at one time. A negative value indicates no limit.
670         * @return the maximum number of instances in circulation at one time.
671         * @see #setMaxTotal
672         */
673        public synchronized int getMaxTotal() {
674            return _maxTotal;
675        }
676    
677        /**
678         * Sets the cap on the total number of instances from all pools combined.
679         * When <code>maxTotal</code> is set to a
680         * positive value and {@link #borrowObject borrowObject} is invoked
681         * when at the limit with no idle instances available, an attempt is made to
682         * create room by clearing the oldest 15% of the elements from the keyed
683         * pools.
684         *
685         * @param maxTotal The cap on the total number of instances across pools.
686         * Use a negative value for no limit.
687         * @see #getMaxTotal
688         */
689        public void setMaxTotal(int maxTotal) {
690            synchronized(this) {
691                _maxTotal = maxTotal;
692            }
693            allocate();
694        }
695    
696        /**
697         * Returns the action to take when the {@link #borrowObject} method
698         * is invoked when the pool is exhausted (the maximum number
699         * of "active" objects has been reached).
700         *
701         * @return one of {@link #WHEN_EXHAUSTED_BLOCK},
702         * {@link #WHEN_EXHAUSTED_FAIL} or {@link #WHEN_EXHAUSTED_GROW}
703         * @see #setWhenExhaustedAction
704         */
705        public synchronized byte getWhenExhaustedAction() {
706            return _whenExhaustedAction;
707        }
708    
709        /**
710         * Sets the action to take when the {@link #borrowObject} method
711         * is invoked when the pool is exhausted (the maximum number
712         * of "active" objects has been reached).
713         *
714         * @param whenExhaustedAction the action code, which must be one of
715         *        {@link #WHEN_EXHAUSTED_BLOCK}, {@link #WHEN_EXHAUSTED_FAIL},
716         *        or {@link #WHEN_EXHAUSTED_GROW}
717         * @see #getWhenExhaustedAction
718         */
719        public void setWhenExhaustedAction(byte whenExhaustedAction) {
720            synchronized(this) {
721                switch(whenExhaustedAction) {
722                    case WHEN_EXHAUSTED_BLOCK:
723                    case WHEN_EXHAUSTED_FAIL:
724                    case WHEN_EXHAUSTED_GROW:
725                        _whenExhaustedAction = whenExhaustedAction;
726                        break;
727                    default:
728                        throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
729                }
730            }
731            allocate();
732        }
733    
734    
735        /**
736         * Returns the maximum amount of time (in milliseconds) the
737         * {@link #borrowObject} method should block before throwing
738         * an exception when the pool is exhausted and the
739         * {@link #setWhenExhaustedAction "when exhausted" action} is
740         * {@link #WHEN_EXHAUSTED_BLOCK}.
741         *
742         * When less than or equal to 0, the {@link #borrowObject} method
743         * may block indefinitely.
744         *
745         * @return the maximum number of milliseconds borrowObject will block.
746         * @see #setMaxWait
747         * @see #setWhenExhaustedAction
748         * @see #WHEN_EXHAUSTED_BLOCK
749         */
750        public synchronized long getMaxWait() {
751            return _maxWait;
752        }
753    
754        /**
755         * Sets the maximum amount of time (in milliseconds) the
756         * {@link #borrowObject} method should block before throwing
757         * an exception when the pool is exhausted and the
758         * {@link #setWhenExhaustedAction "when exhausted" action} is
759         * {@link #WHEN_EXHAUSTED_BLOCK}.
760         *
761         * When less than or equal to 0, the {@link #borrowObject} method
762         * may block indefinitely.
763         *
764         * @param maxWait the maximum number of milliseconds borrowObject will block or negative for indefinitely.
765         * @see #getMaxWait
766         * @see #setWhenExhaustedAction
767         * @see #WHEN_EXHAUSTED_BLOCK
768         */
769        public void setMaxWait(long maxWait) {
770            synchronized(this) {
771                _maxWait = maxWait;
772            }
773            allocate();
774        }
775    
776        /**
777         * Returns the cap on the number of "idle" instances per key.
778         * @return the maximum number of "idle" instances that can be held
779         * in a given keyed pool.
780         * @see #setMaxIdle
781         */
782        public synchronized int getMaxIdle() {
783            return _maxIdle;
784        }
785    
786        /**
787         * Sets the cap on the number of "idle" instances in the pool.
788         * If maxIdle is set too low on heavily loaded systems it is possible you
789         * will see objects being destroyed and almost immediately new objects
790         * being created. This is a result of the active threads momentarily
791         * returning objects faster than they are requesting them them, causing the
792         * number of idle objects to rise above maxIdle. The best value for maxIdle
793         * for heavily loaded system will vary but the default is a good starting
794         * point.
795         * @param maxIdle the maximum number of "idle" instances that can be held
796         * in a given keyed pool. Use a negative value for no limit.
797         * @see #getMaxIdle
798         * @see #DEFAULT_MAX_IDLE
799         */
800        public void setMaxIdle(int maxIdle) {
801            synchronized(this) {
802                _maxIdle = maxIdle;
803            }
804            allocate();
805        }
806    
807        /**
808         * Sets the minimum number of idle objects to maintain in each of the keyed
809         * pools. This setting has no effect unless
810         * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
811         * that each pool has the required minimum number of instances are only
812         * made during idle object eviction runs.
813         * @param poolSize - The minimum size of the each keyed pool
814         * @since Pool 1.3
815         * @see #getMinIdle
816         * @see #setTimeBetweenEvictionRunsMillis
817         */
818        public void setMinIdle(int poolSize) {
819            _minIdle = poolSize;
820        }
821    
822        /**
823         * Returns the minimum number of idle objects to maintain in each of the keyed
824         * pools. This setting has no effect unless
825         * <code>timeBetweenEvictionRunsMillis > 0</code> and attempts to ensure
826         * that each pool has the required minimum number of instances are only
827         * made during idle object eviction runs.
828         * @return minimum size of the each keyed pool
829         * @since Pool 1.3
830         * @see #setTimeBetweenEvictionRunsMillis
831         */
832        public int getMinIdle() {
833            return _minIdle;
834        }
835    
836        /**
837         * When <code>true</code>, objects will be
838         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
839         * before being returned by the {@link #borrowObject}
840         * method.  If the object fails to validate,
841         * it will be dropped from the pool, and we will attempt
842         * to borrow another.
843         *
844         * @return <code>true</code> if objects are validated before being borrowed.
845         * @see #setTestOnBorrow
846         */
847        public boolean getTestOnBorrow() {
848            return _testOnBorrow;
849        }
850    
851        /**
852         * When <code>true</code>, objects will be
853         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
854         * before being returned by the {@link #borrowObject}
855         * method.  If the object fails to validate,
856         * it will be dropped from the pool, and we will attempt
857         * to borrow another.
858         *
859         * @param testOnBorrow whether object should be validated before being returned by borrowObject.
860         * @see #getTestOnBorrow
861         */
862        public void setTestOnBorrow(boolean testOnBorrow) {
863            _testOnBorrow = testOnBorrow;
864        }
865    
866        /**
867         * When <code>true</code>, objects will be
868         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
869         * before being returned to the pool within the
870         * {@link #returnObject}.
871         *
872         * @return <code>true</code> when objects will be validated before being returned.
873         * @see #setTestOnReturn
874         */
875        public boolean getTestOnReturn() {
876            return _testOnReturn;
877        }
878    
879        /**
880         * When <code>true</code>, objects will be
881         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
882         * before being returned to the pool within the
883         * {@link #returnObject}.
884         *
885         * @param testOnReturn <code>true</code> so objects will be validated before being returned.
886         * @see #getTestOnReturn
887         */
888        public void setTestOnReturn(boolean testOnReturn) {
889            _testOnReturn = testOnReturn;
890        }
891    
892        /**
893         * Returns the number of milliseconds to sleep between runs of the
894         * idle object evictor thread.
895         * When non-positive, no idle object evictor thread will be
896         * run.
897         *
898         * @return milliseconds to sleep between evictor runs.
899         * @see #setTimeBetweenEvictionRunsMillis
900         */
901        public synchronized long getTimeBetweenEvictionRunsMillis() {
902            return _timeBetweenEvictionRunsMillis;
903        }
904    
905        /**
906         * Sets the number of milliseconds to sleep between runs of the
907         * idle object evictor thread.
908         * When non-positive, no idle object evictor thread will be
909         * run.
910         *
911         * @param timeBetweenEvictionRunsMillis milliseconds to sleep between evictor runs.
912         * @see #getTimeBetweenEvictionRunsMillis
913         */
914        public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
915            _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
916            startEvictor(_timeBetweenEvictionRunsMillis);
917        }
918    
919        /**
920         * Returns the max number of objects to examine during each run of the
921         * idle object evictor thread (if any).
922         *
923         * @return number of objects to examine each eviction run.
924         * @see #setNumTestsPerEvictionRun
925         * @see #setTimeBetweenEvictionRunsMillis
926         */
927        public synchronized int getNumTestsPerEvictionRun() {
928            return _numTestsPerEvictionRun;
929        }
930    
931        /**
932         * Sets the max number of objects to examine during each run of the
933         * idle object evictor thread (if any).
934         * <p>
935         * When a negative value is supplied, 
936         * <code>ceil({@link #getNumIdle()})/abs({@link #getNumTestsPerEvictionRun})</code>
937         * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
938         * idle objects will be tested per run.  When the value is positive, the number of tests
939         * actually performed in each run will be the minimum of this value and the number of instances
940         * idle in the pools.
941         *
942         * @param numTestsPerEvictionRun number of objects to examine each eviction run.
943         * @see #setNumTestsPerEvictionRun
944         * @see #setTimeBetweenEvictionRunsMillis
945         */
946        public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
947            _numTestsPerEvictionRun = numTestsPerEvictionRun;
948        }
949    
950        /**
951         * Returns the minimum amount of time an object may sit idle in the pool
952         * before it is eligible for eviction by the idle object evictor
953         * (if any).
954         *
955         * @return minimum amount of time an object may sit idle in the pool before it is eligible for eviction.
956         * @see #setMinEvictableIdleTimeMillis
957         * @see #setTimeBetweenEvictionRunsMillis
958         */
959        public synchronized long getMinEvictableIdleTimeMillis() {
960            return _minEvictableIdleTimeMillis;
961        }
962    
963        /**
964         * Sets the minimum amount of time an object may sit idle in the pool
965         * before it is eligible for eviction by the idle object evictor
966         * (if any).
967         * When non-positive, no objects will be evicted from the pool
968         * due to idle time alone.
969         *
970         * @param minEvictableIdleTimeMillis minimum amount of time an object may sit idle in the pool before
971         * it is eligible for eviction.
972         * @see #getMinEvictableIdleTimeMillis
973         * @see #setTimeBetweenEvictionRunsMillis
974         */
975        public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
976            _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
977        }
978    
979        /**
980         * When <code>true</code>, objects will be
981         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
982         * by the idle object evictor (if any).  If an object
983         * fails to validate, it will be dropped from the pool.
984         *
985         * @return <code>true</code> when objects are validated when borrowed.
986         * @see #setTestWhileIdle
987         * @see #setTimeBetweenEvictionRunsMillis
988         */
989        public synchronized boolean getTestWhileIdle() {
990            return _testWhileIdle;
991        }
992    
993        /**
994         * When <code>true</code>, objects will be
995         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
996         * by the idle object evictor (if any).  If an object
997         * fails to validate, it will be dropped from the pool.
998         *
999         * @param testWhileIdle <code>true</code> so objects are validated when borrowed.
1000         * @see #getTestWhileIdle
1001         * @see #setTimeBetweenEvictionRunsMillis
1002         */
1003        public synchronized void setTestWhileIdle(boolean testWhileIdle) {
1004            _testWhileIdle = testWhileIdle;
1005        }
1006    
1007        /**
1008         * Sets the configuration.
1009         * @param conf the new configuration to use.
1010         * @see GenericKeyedObjectPool.Config
1011         */
1012        public synchronized void setConfig(GenericKeyedObjectPool.Config conf) {
1013            setMaxIdle(conf.maxIdle);
1014            setMaxActive(conf.maxActive);
1015            setMaxTotal(conf.maxTotal);
1016            setMinIdle(conf.minIdle);
1017            setMaxWait(conf.maxWait);
1018            setWhenExhaustedAction(conf.whenExhaustedAction);
1019            setTestOnBorrow(conf.testOnBorrow);
1020            setTestOnReturn(conf.testOnReturn);
1021            setTestWhileIdle(conf.testWhileIdle);
1022            setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
1023            setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
1024            setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
1025        }
1026    
1027        /**
1028         * Whether or not the idle object pools act as LIFO queues. True means
1029         * that borrowObject returns the most recently used ("last in") idle object
1030         * in a pool (if there are idle instances available).  False means that
1031         * the pools behave as FIFO queues - objects are taken from idle object
1032         * pools in the order that they are returned.
1033         *
1034         * @return <code>true</code> if the pools are configured to act as LIFO queues
1035         * @since 1.4
1036         */
1037         public synchronized boolean getLifo() {
1038             return _lifo;
1039         }
1040    
1041         /**
1042          * Sets the LIFO property of the pools. True means that borrowObject returns
1043          * the most recently used ("last in") idle object in a pool (if there are
1044          * idle instances available).  False means that the pools behave as FIFO
1045          * queues - objects are taken from idle object pools in the order that
1046          * they are returned.
1047          *
1048          * @param lifo the new value for the lifo property
1049          * @since 1.4
1050          */
1051         public synchronized void setLifo(boolean lifo) {
1052             this._lifo = lifo;
1053         }
1054    
1055        //-- ObjectPool methods ------------------------------------------
1056    
1057        /**
1058         * <p>Borrows an object from the keyed pool associated with the given key.</p>
1059         * 
1060         * <p>If there is an idle instance available in the pool associated with the given key, then
1061         * either the most-recently returned (if {@link #getLifo() lifo} == true) or "oldest" (lifo == false)
1062         * instance sitting idle in the pool will be activated and returned.  If activation fails, or
1063         * {@link #getTestOnBorrow() testOnBorrow} is set to true and validation fails, the instance is destroyed and the
1064         * next available instance is examined.  This continues until either a valid instance is returned or there
1065         * are no more idle instances available.</p>
1066         * 
1067         * <p>If there are no idle instances available in the pool associated with the given key, behavior
1068         * depends on the {@link #getMaxActive() maxActive}, {@link #getMaxTotal() maxTotal}, and (if applicable)
1069         * {@link #getWhenExhaustedAction() whenExhaustedAction} and {@link #getMaxWait() maxWait} properties. If the
1070         * number of instances checked out from the pool under the given key is less than <code>maxActive</code> and
1071         * the total number of instances in circulation (under all keys) is less than <code>maxTotal</code>, a new instance
1072         * is created, activated and (if applicable) validated and returned to the caller.</p>
1073         * 
1074         * <p>If the associated keyed pool is exhausted (no available idle instances and no capacity to create new ones),
1075         * this method will either block ({@link #WHEN_EXHAUSTED_BLOCK}), throw a <code>NoSuchElementException</code>
1076         * ({@link #WHEN_EXHAUSTED_FAIL}), or grow ({@link #WHEN_EXHAUSTED_GROW} - ignoring maxActive, maxTotal properties).
1077         * The length of time that this method will block when <code>whenExhaustedAction == WHEN_EXHAUSTED_BLOCK</code>
1078         * is determined by the {@link #getMaxWait() maxWait} property.</p>
1079         * 
1080         * <p>When the pool is exhausted, multiple calling threads may be simultaneously blocked waiting for instances
1081         * to become available.  As of pool 1.5, a "fairness" algorithm has been implemented to ensure that threads receive
1082         * available instances in request arrival order.</p>
1083         * 
1084         * @param key pool key
1085         * @return object instance from the keyed pool
1086         * @throws NoSuchElementException if a keyed object instance cannot be returned.
1087         */
1088         public Object borrowObject(Object key) throws Exception {
1089            long starttime = System.currentTimeMillis();
1090            Latch latch = new Latch(key);
1091            byte whenExhaustedAction;
1092            long maxWait;
1093            synchronized (this) {
1094                // Get local copy of current config. Can't sync when used later as
1095                // it can result in a deadlock. Has the added advantage that config
1096                // is consistent for entire method execution
1097                whenExhaustedAction = _whenExhaustedAction;
1098                maxWait = _maxWait;
1099    
1100                // Add this request to the queue
1101                _allocationQueue.add(latch);
1102            }
1103            // Work the allocation queue, allocating idle instances and
1104            // instance creation permits in request arrival order
1105            allocate();
1106    
1107            for(;;) {
1108                synchronized (this) {
1109                    assertOpen();
1110                }
1111                // If no object was allocated
1112                if (null == latch.getPair()) {
1113                    // Check to see if we were allowed to create one
1114                    if (latch.mayCreate()) {
1115                        // allow new object to be created
1116                    } else {
1117                        // the pool is exhausted
1118                        switch(whenExhaustedAction) {
1119                            case WHEN_EXHAUSTED_GROW:
1120                                // allow new object to be created
1121                                synchronized (this) {
1122                                    // Make sure another thread didn't allocate us an object
1123                                    // or permit a new object to be created
1124                                    if (latch.getPair() == null && !latch.mayCreate()) {
1125                                        _allocationQueue.remove(latch);
1126                                        latch.getPool().incrementInternalProcessingCount();
1127                                    }
1128                                }
1129                            break;
1130                            case WHEN_EXHAUSTED_FAIL:
1131                                synchronized (this) {
1132                                    // Make sure allocate hasn't already assigned an object
1133                                    // in a different thread or permitted a new object to be created
1134                                    if (latch.getPair() != null || latch.mayCreate()) {
1135                                        break;
1136                                    }
1137                                    _allocationQueue.remove(latch);
1138                                }
1139                                throw new NoSuchElementException("Pool exhausted");
1140                            case WHEN_EXHAUSTED_BLOCK:
1141                                try {
1142                                    synchronized (latch) {
1143                                        // Before we wait, make sure another thread didn't allocate us an object
1144                                        // or permit a new object to be created
1145                                        if (latch.getPair() == null && !latch.mayCreate()) {
1146                                            if (maxWait <= 0) {
1147                                                latch.wait();
1148                                            } else {
1149                                                // this code may be executed again after a notify then continue cycle
1150                                                // so, need to calculate the amount of time to wait
1151                                                final long elapsed = (System.currentTimeMillis() - starttime);
1152                                                final long waitTime = maxWait - elapsed;
1153                                                if (waitTime > 0)
1154                                                {
1155                                                    latch.wait(waitTime);
1156                                                }
1157                                            }
1158                                        } else {
1159                                            break;
1160                                        }
1161                                    }
1162                                } catch(InterruptedException e) {
1163                                    boolean doAllocate = false;
1164                                    synchronized (this) {
1165                                        // Need to handle the all three possibilities
1166                                        if (latch.getPair() == null && !latch.mayCreate()) {
1167                                            // Case 1: latch still in allocation queue
1168                                            // Remove latch from the allocation queue
1169                                            _allocationQueue.remove(latch);
1170                                        } else if (latch.getPair() == null && latch.mayCreate()) {
1171                                            // Case 2: latch has been given permission to create
1172                                            //         a new object
1173                                            latch.getPool().decrementInternalProcessingCount();
1174                                            doAllocate = true;
1175                                        } else {
1176                                            // Case 3: An object has been allocated
1177                                            latch.getPool().decrementInternalProcessingCount();
1178                                            latch.getPool().incrementActiveCount();
1179                                            returnObject(latch.getkey(), latch.getPair().getValue());
1180                                        }
1181                                    }
1182                                    if (doAllocate) {
1183                                        allocate();
1184                                    }
1185                                    Thread.currentThread().interrupt();
1186                                    throw e;
1187                                }
1188                                if (maxWait > 0 && ((System.currentTimeMillis() - starttime) >= maxWait)) {
1189                                    synchronized (this) {
1190                                        // Make sure allocate hasn't already assigned an object
1191                                        // in a different thread or permitted a new object to be created
1192                                        if (latch.getPair() == null && !latch.mayCreate()) {
1193                                            _allocationQueue.remove(latch);
1194                                        } else {
1195                                            break;
1196                                        }
1197                                    }
1198                                    throw new NoSuchElementException("Timeout waiting for idle object");
1199                                } else {
1200                                    continue; // keep looping
1201                                }
1202                            default:
1203                                throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction +
1204                                        " not recognized.");
1205                        }
1206                    }
1207                }
1208    
1209                boolean newlyCreated = false;
1210                if (null == latch.getPair()) {
1211                    try {
1212                        Object obj = _factory.makeObject(key);
1213                        latch.setPair(new ObjectTimestampPair(obj));
1214                        newlyCreated = true;
1215                    } finally {
1216                        if (!newlyCreated) {
1217                            // object cannot be created
1218                            synchronized (this) {
1219                                latch.getPool().decrementInternalProcessingCount();
1220                                // No need to reset latch - about to throw exception
1221                            }
1222                            allocate();
1223                        }
1224                    }
1225                }
1226    
1227                // activate & validate the object
1228                try {
1229                    _factory.activateObject(key, latch.getPair().value);
1230                    if (_testOnBorrow && !_factory.validateObject(key, latch.getPair().value)) {
1231                        throw new Exception("ValidateObject failed");
1232                    }
1233                    synchronized (this) {
1234                        latch.getPool().decrementInternalProcessingCount();
1235                        latch.getPool().incrementActiveCount();
1236                    }
1237                    return latch.getPair().value;
1238                } catch (Throwable e) {
1239                    PoolUtils.checkRethrow(e);
1240                    // object cannot be activated or is invalid
1241                    try {
1242                        _factory.destroyObject(key, latch.getPair().value);
1243                    } catch (Throwable e2) {
1244                        PoolUtils.checkRethrow(e2);
1245                        // cannot destroy broken object
1246                    }
1247                    synchronized (this) {
1248                        latch.getPool().decrementInternalProcessingCount();
1249                        if (!newlyCreated) {
1250                            latch.reset();
1251                            _allocationQueue.add(0, latch);
1252                        }
1253                    }
1254                    allocate();
1255                    if (newlyCreated) {
1256                        throw new NoSuchElementException(
1257                           "Could not create a validated object, cause: " +
1258                                e.getMessage());
1259                    }
1260                    else {
1261                        continue; // keep looping
1262                    }
1263                }
1264            }
1265        }
1266    
1267        /**
1268         * Allocate available instances to latches in the allocation queue.  Then
1269         * set _mayCreate to true for as many additional latches remaining in queue
1270         * as _maxActive allows for each key. This method <b>MUST NOT</b> be called
1271         * from inside a sync block.
1272         */
1273        private void allocate() {
1274            boolean clearOldest = false;
1275    
1276            synchronized (this) {
1277                if (isClosed()) return;
1278                
1279                Iterator allocationQueueIter = _allocationQueue.iterator();
1280                
1281                while (allocationQueueIter.hasNext()) {
1282                    // First use any objects in the pool to clear the queue
1283                    Latch latch = (Latch) allocationQueueIter.next();
1284                    ObjectQueue pool = (ObjectQueue)(_poolMap.get(latch.getkey()));
1285                    if (null == pool) {
1286                        pool = new ObjectQueue();
1287                        _poolMap.put(latch.getkey(), pool);
1288                        _poolList.add(latch.getkey());
1289                    }
1290                    latch.setPool(pool);
1291                    if (!pool.queue.isEmpty()) {
1292                        allocationQueueIter.remove();
1293                        latch.setPair(
1294                                (ObjectTimestampPair) pool.queue.removeFirst());
1295                        pool.incrementInternalProcessingCount();
1296                        _totalIdle--;
1297                        synchronized (latch) {
1298                            latch.notify();
1299                        }
1300                        // Next item in queue
1301                        continue;
1302                    }
1303    
1304                    // If there is a totalMaxActive and we are at the limit then
1305                    // we have to make room
1306                    if ((_maxTotal > 0) &&
1307                            (_totalActive + _totalIdle + _totalInternalProcessing >= _maxTotal)) {
1308                        clearOldest = true;
1309                        break;
1310                    }
1311    
1312                    // Second utilise any spare capacity to create new objects
1313                    if ((_maxActive < 0 || pool.activeCount + pool.internalProcessingCount < _maxActive) &&
1314                            (_maxTotal < 0 || _totalActive + _totalIdle + _totalInternalProcessing < _maxTotal)) {
1315                        // allow new object to be created
1316                        allocationQueueIter.remove();
1317                        latch.setMayCreate(true);
1318                        pool.incrementInternalProcessingCount();
1319                        synchronized (latch) {
1320                            latch.notify();
1321                        }
1322                        // Next item in queue
1323                        continue;
1324                    }
1325    
1326                    // If there is no per-key limit and we reach this point we
1327                    // must have allocated all the objects we possibly can and there
1328                    // is no point looking at the rest of the allocation queue
1329                    if (_maxActive < 0) {
1330                        break;
1331                    }
1332                }
1333            }
1334            
1335            if (clearOldest) {
1336                /* Clear oldest calls factory methods so it must be called from
1337                 * outside the sync block.
1338                 * It also needs to be outside the sync block as it calls
1339                 * allocate(). If called inside the sync block, the call to
1340                 * allocate() would be able to enter the sync block (since the
1341                 * thread already has the lock) which may have unexpected,
1342                 * unpleasant results.
1343                 */
1344                clearOldest();
1345            }
1346        }
1347        
1348        /**
1349         * Clears any objects sitting idle in the pool by removing them from the
1350         * idle instance pool and then invoking the configured PoolableObjectFactory's
1351         * {@link KeyedPoolableObjectFactory#destroyObject(Object, Object)} method on
1352         * each idle instance.
1353         *  
1354         * <p> Implementation notes:
1355         * <ul><li>This method does not destroy or effect in any way instances that are
1356         * checked out when it is invoked.</li>
1357         * <li>Invoking this method does not prevent objects being
1358         * returned to the idle instance pool, even during its execution. It locks
1359         * the pool only during instance removal. Additional instances may be returned
1360         * while removed items are being destroyed.</li>
1361         * <li>Exceptions encountered destroying idle instances are swallowed.</li></ul></p>
1362         */
1363        public void clear() {
1364            Map toDestroy = new HashMap();
1365            synchronized (this) {
1366                for (Iterator it = _poolMap.keySet().iterator(); it.hasNext();) {
1367                    Object key = it.next();
1368                    ObjectQueue pool = (ObjectQueue)_poolMap.get(key);
1369                    // Copy objects to new list so pool.queue can be cleared inside
1370                    // the sync
1371                    List objects = new ArrayList();
1372                    objects.addAll(pool.queue);
1373                    toDestroy.put(key, objects);
1374                    it.remove();
1375                    _poolList.remove(key);
1376                    _totalIdle = _totalIdle - pool.queue.size();
1377                    _totalInternalProcessing =
1378                        _totalInternalProcessing + pool.queue.size();
1379                    pool.queue.clear();
1380                }
1381            }
1382            destroy(toDestroy, _factory);
1383        }
1384    
1385        /**
1386         * Clears oldest 15% of objects in pool.  The method sorts the
1387         * objects into a TreeMap and then iterates the first 15% for removal.
1388         * 
1389         * @since Pool 1.3
1390         */
1391        public void clearOldest() {
1392            // Map of objects to destroy my key
1393            final Map toDestroy = new HashMap();
1394    
1395            // build sorted map of idle objects
1396            final Map map = new TreeMap();
1397            synchronized (this) {
1398                for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
1399                    final Object key = keyiter.next();
1400                    final CursorableLinkedList list = ((ObjectQueue)_poolMap.get(key)).queue;
1401                    for (Iterator it = list.iterator(); it.hasNext();) {
1402                        // each item into the map uses the objectimestamppair object
1403                        // as the key.  It then gets sorted based on the timstamp field
1404                        // each value in the map is the parent list it belongs in.
1405                        map.put(it.next(), key);
1406                    }
1407                }
1408    
1409                // Now iterate created map and kill the first 15% plus one to account for zero
1410                Set setPairKeys = map.entrySet();
1411                int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
1412    
1413                Iterator iter = setPairKeys.iterator();
1414                while (iter.hasNext() && itemsToRemove > 0) {
1415                    Map.Entry entry = (Map.Entry) iter.next();
1416                    // kind of backwards on naming.  In the map, each key is the objecttimestamppair
1417                    // because it has the ordering with the timestamp value.  Each value that the
1418                    // key references is the key of the list it belongs to.
1419                    Object key = entry.getValue();
1420                    ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
1421                    ObjectQueue objectQueue = (ObjectQueue)_poolMap.get(key);
1422                    final CursorableLinkedList list = objectQueue.queue;
1423                    list.remove(pairTimeStamp);
1424    
1425                    if (toDestroy.containsKey(key)) {
1426                        ((List)toDestroy.get(key)).add(pairTimeStamp);
1427                    } else {
1428                        List listForKey = new ArrayList();
1429                        listForKey.add(pairTimeStamp);
1430                        toDestroy.put(key, listForKey);
1431                    }
1432                    objectQueue.incrementInternalProcessingCount();
1433                    _totalIdle--;
1434                    itemsToRemove--;
1435                }
1436    
1437            }
1438            destroy(toDestroy, _factory);
1439        }
1440    
1441        /**
1442         * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
1443         *
1444         * @param key the key to clear
1445         */
1446        public void clear(Object key) {
1447            Map toDestroy = new HashMap();
1448    
1449            final ObjectQueue pool;
1450            synchronized (this) {
1451                pool = (ObjectQueue)(_poolMap.remove(key));
1452                if (pool == null) {
1453                    return;
1454                } else {
1455                    _poolList.remove(key);
1456                }
1457                // Copy objects to new list so pool.queue can be cleared inside
1458                // the sync
1459                List objects = new ArrayList();
1460                objects.addAll(pool.queue);
1461                toDestroy.put(key, objects);
1462                _totalIdle = _totalIdle - pool.queue.size();
1463                _totalInternalProcessing =
1464                    _totalInternalProcessing + pool.queue.size();
1465                pool.queue.clear();
1466            }
1467            destroy(toDestroy, _factory);
1468        }
1469    
1470        /**
1471         * Assuming Map<Object,Collection<ObjectTimestampPair>>, destroy all
1472         * ObjectTimestampPair.value using the supplied factory.
1473         * 
1474         * @param m Map containing keyed pools to clear
1475         * @param factory KeyedPoolableObjectFactory used to destroy the objects
1476         */
1477        private void destroy(Map m, KeyedPoolableObjectFactory factory) {
1478            for (Iterator entries = m.entrySet().iterator(); entries.hasNext();) {
1479                Map.Entry entry = (Entry) entries.next();
1480                Object key = entry.getKey();
1481                Collection c = (Collection) entry.getValue();
1482                for (Iterator it = c.iterator(); it.hasNext();) {
1483                    try {
1484                        factory.destroyObject(
1485                                key,((ObjectTimestampPair)(it.next())).value);
1486                    } catch(Exception e) {
1487                        // ignore error, keep destroying the rest
1488                    } finally {
1489                        synchronized(this) {
1490                            ObjectQueue objectQueue =
1491                                    (ObjectQueue) _poolMap.get(key);
1492                            if (objectQueue != null) {
1493                                objectQueue.decrementInternalProcessingCount();
1494                                if (objectQueue.internalProcessingCount == 0 &&
1495                                        objectQueue.activeCount == 0 &&
1496                                        objectQueue.queue.isEmpty()) {
1497                                    _poolMap.remove(key);
1498                                    _poolList.remove(key);
1499                                }
1500                            }
1501                        }
1502                        allocate();
1503                    }
1504                }
1505    
1506            }
1507        }
1508    
1509        /**
1510         * Returns the total number of instances current borrowed from this pool but not yet returned.
1511         *
1512         * @return the total number of instances currently borrowed from this pool
1513         */
1514        public synchronized int getNumActive() {
1515            return _totalActive;
1516        }
1517    
1518        /**
1519         * Returns the total number of instances currently idle in this pool.
1520         *
1521         * @return the total number of instances currently idle in this pool
1522         */
1523        public synchronized int getNumIdle() {
1524            return _totalIdle;
1525        }
1526    
1527        /**
1528         * Returns the number of instances currently borrowed from but not yet returned
1529         * to the pool corresponding to the given <code>key</code>.
1530         *
1531         * @param key the key to query
1532         * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
1533         */
1534        public synchronized int getNumActive(Object key) {
1535            final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1536            return pool != null ? pool.activeCount : 0;
1537        }
1538    
1539        /**
1540         * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
1541         *
1542         * @param key the key to query
1543         * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
1544         */
1545        public synchronized int getNumIdle(Object key) {
1546            final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1547            return pool != null ? pool.queue.size() : 0;
1548        }
1549    
1550        /**
1551         * <p>Returns an object to a keyed pool.</p>
1552         * 
1553         * <p>For the pool to function correctly, the object instance <strong>must</strong> have been borrowed
1554         * from the pool (under the same key) and not yet returned. Repeated <code>returnObject</code> calls on
1555         * the same object/key pair (with no <code>borrowObject</code> calls in between) will result in multiple
1556         * references to the object in the idle instance pool.</p>
1557         * 
1558         * <p>If {@link #getMaxIdle() maxIdle} is set to a positive value and the number of idle instances under the given
1559         * key has reached this value, the returning instance is destroyed.</p>
1560         * 
1561         * <p>If {@link #getTestOnReturn() testOnReturn} == true, the returning instance is validated before being returned
1562         * to the idle instance pool under the given key.  In this case, if validation fails, the instance is destroyed.</p>
1563         * 
1564         * @param key pool key
1565         * @param obj instance to return to the keyed pool
1566         * @throws Exception
1567         */
1568        public void returnObject(Object key, Object obj) throws Exception {
1569            try {
1570                addObjectToPool(key, obj, true);
1571            } catch (Exception e) {
1572                if (_factory != null) {
1573                    try {
1574                        _factory.destroyObject(key, obj);
1575                    } catch (Exception e2) {
1576                        // swallowed
1577                    }
1578                    // TODO: Correctness here depends on control in addObjectToPool.
1579                    // These two methods should be refactored, removing the
1580                    // "behavior flag", decrementNumActive, from addObjectToPool.
1581                    ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1582                    if (pool != null) {
1583                        synchronized(this) {
1584                            pool.decrementActiveCount();
1585                            if (pool.queue.isEmpty() &&
1586                                    pool.activeCount == 0 &&
1587                                    pool.internalProcessingCount == 0) {
1588                                _poolMap.remove(key);
1589                                _poolList.remove(key);
1590                            }
1591                        }
1592                        allocate();
1593                    }
1594                }
1595            }
1596        }
1597    
1598        /**
1599         * <p>Adds an object to the keyed pool.</p>
1600         * 
1601         * <p>Validates the object if testOnReturn == true and passivates it before returning it to the pool.
1602         * if validation or passivation fails, or maxIdle is set and there is no room in the pool, the instance
1603         * is destroyed.</p>
1604         * 
1605         * <p>Calls {@link #allocate()} on successful completion</p>
1606         * 
1607         * @param key pool key
1608         * @param obj instance to add to the keyed pool
1609         * @param decrementNumActive whether or not to decrement the active count associated with the keyed pool
1610         * @throws Exception
1611         */
1612        private void addObjectToPool(Object key, Object obj,
1613                boolean decrementNumActive) throws Exception {
1614    
1615            // if we need to validate this object, do so
1616            boolean success = true; // whether or not this object passed validation
1617            if (_testOnReturn && !_factory.validateObject(key, obj)) {
1618                success = false;
1619            } else {
1620                _factory.passivateObject(key, obj);
1621            }
1622    
1623            boolean shouldDestroy = !success;
1624            ObjectQueue pool;
1625    
1626            // Add instance to pool if there is room and it has passed validation
1627            // (if testOnreturn is set)
1628            boolean doAllocate = false;
1629            synchronized (this) {
1630                // grab the pool (list) of objects associated with the given key
1631                pool = (ObjectQueue) (_poolMap.get(key));
1632                // if it doesn't exist, create it
1633                if (null == pool) {
1634                    pool = new ObjectQueue();
1635                    _poolMap.put(key, pool);
1636                    _poolList.add(key);
1637                }
1638                if (isClosed()) {
1639                    shouldDestroy = true;
1640                } else {
1641                    // if there's no space in the pool, flag the object for destruction
1642                    // else if we passivated successfully, return it to the pool
1643                    if (_maxIdle >= 0 && (pool.queue.size() >= _maxIdle)) {
1644                        shouldDestroy = true;
1645                    } else if (success) {
1646                        // borrowObject always takes the first element from the queue,
1647                        // so for LIFO, push on top, FIFO add to end
1648                        if (_lifo) {
1649                            pool.queue.addFirst(new ObjectTimestampPair(obj));
1650                        } else {
1651                            pool.queue.addLast(new ObjectTimestampPair(obj));
1652                        }
1653                        _totalIdle++;
1654                        if (decrementNumActive) {
1655                            pool.decrementActiveCount();
1656                        }
1657                        doAllocate = true;
1658                    }
1659                }
1660            }
1661            if (doAllocate) {
1662                allocate();
1663            }
1664    
1665            // Destroy the instance if necessary
1666            if (shouldDestroy) {
1667                try {
1668                    _factory.destroyObject(key, obj);
1669                } catch(Exception e) {
1670                    // ignored?
1671                }
1672                // Decrement active count *after* destroy if applicable
1673                if (decrementNumActive) {
1674                    synchronized(this) {
1675                        pool.decrementActiveCount();
1676                        if (pool.queue.isEmpty() &&
1677                                pool.activeCount == 0 &&
1678                                pool.internalProcessingCount == 0) {
1679                            _poolMap.remove(key);
1680                            _poolList.remove(key);
1681                        }
1682                    }
1683                    allocate();
1684                }
1685            }
1686        }
1687    
1688        /**
1689         * {@inheritDoc}
1690         * <p>Activation of this method decrements the active count associated with the given keyed pool 
1691         * and attempts to destroy <code>obj.</code></p>
1692         * 
1693         * @param key pool key
1694         * @param obj instance to invalidate
1695         * @throws Exception if an exception occurs destroying the object
1696         */
1697        public void invalidateObject(Object key, Object obj) throws Exception {
1698            try {
1699                _factory.destroyObject(key, obj);
1700            } finally {
1701                synchronized (this) {
1702                    ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
1703                    if (null == pool) {
1704                        pool = new ObjectQueue();
1705                        _poolMap.put(key, pool);
1706                        _poolList.add(key);
1707                    }
1708                    pool.decrementActiveCount();
1709                }
1710                allocate(); // _totalActive has changed
1711            }
1712        }
1713    
1714        /**
1715         * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
1716         * passivate it, and then place it in the idle object pool.
1717         * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
1718         *
1719         * @param key the key a new instance should be added to
1720         * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
1721         * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been
1722         * called on this pool.
1723         */
1724        public void addObject(Object key) throws Exception {
1725            assertOpen();
1726            if (_factory == null) {
1727                throw new IllegalStateException("Cannot add objects without a factory.");
1728            }
1729            Object obj = _factory.makeObject(key);
1730            try {
1731                assertOpen();
1732                addObjectToPool(key, obj, false);
1733            } catch (IllegalStateException ex) { // Pool closed
1734                try {
1735                    _factory.destroyObject(key, obj);
1736                } catch (Exception ex2) {
1737                    // swallow
1738                }
1739                throw ex;
1740            }
1741        }
1742    
1743        /**
1744         * Registers a key for pool control.
1745         *
1746         * If <code>populateImmediately</code> is <code>true</code> and
1747         * <code>minIdle > 0,</code> the pool under the given key will be
1748         * populated immediately with <code>minIdle</code> idle instances.
1749         *
1750         * @param key - The key to register for pool control.
1751         * @param populateImmediately - If this is <code>true</code>, the pool
1752         * will be populated immediately.
1753         * @since Pool 1.3
1754         */
1755        public synchronized void preparePool(Object key, boolean populateImmediately) {
1756            ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
1757            if (null == pool) {
1758                pool = new ObjectQueue();
1759                _poolMap.put(key,pool);
1760                _poolList.add(key);
1761            }
1762    
1763            if (populateImmediately) {
1764                try {
1765                    // Create the pooled objects
1766                    ensureMinIdle(key);
1767                }
1768                catch (Exception e) {
1769                    //Do nothing
1770                }
1771            }
1772        }
1773    
1774        /**
1775         * <p>Closes the keyed object pool.  Once the pool is closed, {@link #borrowObject(Object)}
1776         * will fail with IllegalStateException, but {@link #returnObject(Object, Object)} and
1777         * {@link #invalidateObject(Object, Object)} will continue to work, with returned objects
1778         * destroyed on return.</p>
1779         * 
1780         * <p>Destroys idle instances in the pool by invoking {@link #clear()}.</p> 
1781         * 
1782         * @throws Exception
1783         */
1784        public void close() throws Exception {
1785            super.close();
1786            synchronized (this) {
1787                clear();
1788                if (null != _evictionCursor) {
1789                    _evictionCursor.close();
1790                    _evictionCursor = null;
1791                }
1792                if (null != _evictionKeyCursor) {
1793                    _evictionKeyCursor.close();
1794                    _evictionKeyCursor = null;
1795                }
1796                startEvictor(-1L);
1797            }
1798        }
1799    
1800        /**
1801         * <p>Sets the keyed poolable object factory associated with this pool.</p>
1802         * 
1803         * <p>If this method is called when objects are checked out of any of the keyed pools,
1804         * an IllegalStateException is thrown.  Calling this method also has the side effect of
1805         * destroying any idle instances in existing keyed pools, using the original factory.</p>
1806         * 
1807         * @param factory KeyedPoolableObjectFactory to use when creating keyed object pool instances
1808         * @throws IllegalStateException if there are active (checked out) instances associated with this keyed object pool
1809         * @deprecated to be removed in version 2.0
1810         */
1811        public void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
1812            Map toDestroy = new HashMap();
1813            final KeyedPoolableObjectFactory oldFactory = _factory;
1814            synchronized (this) {
1815                assertOpen();
1816                if (0 < getNumActive()) {
1817                    throw new IllegalStateException("Objects are already active");
1818                } else {
1819                    for (Iterator it = _poolMap.keySet().iterator(); it.hasNext();) {
1820                        Object key = it.next();
1821                        ObjectQueue pool = (ObjectQueue)_poolMap.get(key);
1822                        if (pool != null) {
1823                            // Copy objects to new list so pool.queue can be cleared
1824                            // inside the sync
1825                            List objects = new ArrayList();
1826                            objects.addAll(pool.queue);
1827                            toDestroy.put(key, objects);
1828                            it.remove();
1829                            _poolList.remove(key);
1830                            _totalIdle = _totalIdle - pool.queue.size();
1831                            _totalInternalProcessing =
1832                                _totalInternalProcessing + pool.queue.size();
1833                            pool.queue.clear();
1834                        }
1835                    }
1836                    _factory = factory;
1837                }
1838            }
1839            destroy(toDestroy, oldFactory);
1840        }
1841    
1842        /**
1843         * <p>Perform <code>numTests</code> idle object eviction tests, evicting
1844         * examined objects that meet the criteria for eviction. If
1845         * <code>testWhileIdle</code> is true, examined objects are validated
1846         * when visited (and removed if invalid); otherwise only objects that
1847         * have been idle for more than <code>minEvicableIdletimeMillis</code>
1848         * are removed.</p>
1849         *
1850         * <p>Successive activations of this method examine objects in keyed pools
1851         * in sequence, cycling through the keys and examining objects in
1852         * oldest-to-youngest order within the keyed pools.</p>
1853         *
1854         * @throws Exception when there is a problem evicting idle objects.
1855         */
1856        public void evict() throws Exception {
1857            Object key = null;
1858            boolean testWhileIdle;
1859            long minEvictableIdleTimeMillis;
1860    
1861            synchronized (this) {
1862                // Get local copy of current config. Can't sync when used later as
1863                // it can result in a deadlock. Has the added advantage that config
1864                // is consistent for entire method execution
1865                testWhileIdle = _testWhileIdle;
1866                minEvictableIdleTimeMillis = _minEvictableIdleTimeMillis;
1867    
1868                // Initialize key to last key value
1869                if (_evictionKeyCursor != null &&
1870                        _evictionKeyCursor._lastReturned != null) {
1871                    key = _evictionKeyCursor._lastReturned.value();
1872                }
1873            }
1874    
1875            for (int i=0, m=getNumTests(); i<m; i++) {
1876                final ObjectTimestampPair pair;
1877                synchronized (this) {
1878                    // make sure pool map is not empty; otherwise do nothing
1879                    if (_poolMap == null || _poolMap.size() == 0) {
1880                        continue;
1881                    }
1882    
1883                    // if we don't have a key cursor, then create one
1884                    if (null == _evictionKeyCursor) {
1885                        resetEvictionKeyCursor();
1886                        key = null;
1887                    }
1888    
1889                    // if we don't have an object cursor, create one
1890                    if (null == _evictionCursor) {
1891                        // if the _evictionKeyCursor has a next value, use this key
1892                        if (_evictionKeyCursor.hasNext()) {
1893                            key = _evictionKeyCursor.next();
1894                            resetEvictionObjectCursor(key);
1895                        } else {
1896                            // Reset the key cursor and try again
1897                            resetEvictionKeyCursor();
1898                            if (_evictionKeyCursor != null) {
1899                                if (_evictionKeyCursor.hasNext()) {
1900                                    key = _evictionKeyCursor.next();
1901                                    resetEvictionObjectCursor(key);
1902                                }
1903                            }
1904                        }
1905                    }
1906    
1907                    if (_evictionCursor == null) {
1908                        continue; // should never happen; do nothing
1909                    }
1910    
1911                    // If eviction cursor is exhausted, try to move
1912                    // to the next key and reset
1913                    if ((_lifo && !_evictionCursor.hasPrevious()) ||
1914                            (!_lifo && !_evictionCursor.hasNext())) {
1915                        if (_evictionKeyCursor != null) {
1916                            if (_evictionKeyCursor.hasNext()) {
1917                                key = _evictionKeyCursor.next();
1918                                resetEvictionObjectCursor(key);
1919                            } else { // Need to reset Key cursor
1920                                resetEvictionKeyCursor();
1921                                if (_evictionKeyCursor != null) {
1922                                    if (_evictionKeyCursor.hasNext()) {
1923                                        key = _evictionKeyCursor.next();
1924                                        resetEvictionObjectCursor(key);
1925                                    }
1926                                }
1927                            }
1928                        }
1929                    }
1930    
1931                    if ((_lifo && !_evictionCursor.hasPrevious()) ||
1932                            (!_lifo && !_evictionCursor.hasNext())) {
1933                        continue; // reset failed, do nothing
1934                    }
1935    
1936                    // if LIFO and the _evictionCursor has a previous object,
1937                    // or FIFO and _evictionCursor has a next object, test it
1938                    pair = _lifo ?
1939                            (ObjectTimestampPair) _evictionCursor.previous() :
1940                            (ObjectTimestampPair) _evictionCursor.next();
1941                    _evictionCursor.remove();
1942                    ObjectQueue objectQueue = (ObjectQueue) _poolMap.get(key);
1943                    objectQueue.incrementInternalProcessingCount();
1944                    _totalIdle--;
1945                }
1946    
1947                boolean removeObject=false;
1948                if ((minEvictableIdleTimeMillis > 0) &&
1949                   (System.currentTimeMillis() - pair.tstamp >
1950                   minEvictableIdleTimeMillis)) {
1951                    removeObject=true;
1952                }
1953                if (testWhileIdle && removeObject == false) {
1954                    boolean active = false;
1955                    try {
1956                        _factory.activateObject(key,pair.value);
1957                        active = true;
1958                    } catch(Exception e) {
1959                        removeObject=true;
1960                    }
1961                    if (active) {
1962                        if (!_factory.validateObject(key,pair.value)) {
1963                            removeObject=true;
1964                        } else {
1965                            try {
1966                                _factory.passivateObject(key,pair.value);
1967                            } catch(Exception e) {
1968                                removeObject=true;
1969                            }
1970                        }
1971                    }
1972                }
1973    
1974                if (removeObject) {
1975                    try {
1976                        _factory.destroyObject(key, pair.value);
1977                    } catch(Exception e) {
1978                        // ignored
1979                    }
1980                }
1981                synchronized (this) {
1982                    ObjectQueue objectQueue =
1983                        (ObjectQueue)_poolMap.get(key);
1984                    objectQueue.decrementInternalProcessingCount();
1985                    if (removeObject) {
1986                        if (objectQueue.queue.isEmpty() &&
1987                                objectQueue.activeCount == 0 &&
1988                                objectQueue.internalProcessingCount == 0) {
1989                            _poolMap.remove(key);
1990                            _poolList.remove(key);
1991                        }
1992                    } else {
1993                        _evictionCursor.add(pair);
1994                        _totalIdle++;
1995                        if (_lifo) {
1996                            // Skip over the element we just added back
1997                            _evictionCursor.previous();
1998                        }
1999                    }
2000                }
2001            }
2002            allocate();
2003        }
2004    
2005        /**
2006         * Resets the eviction key cursor and closes any
2007         * associated eviction object cursor
2008         */
2009        private void resetEvictionKeyCursor() {
2010            if (_evictionKeyCursor != null) {
2011                _evictionKeyCursor.close();
2012            }
2013            _evictionKeyCursor = _poolList.cursor();
2014            if (null != _evictionCursor) {
2015                _evictionCursor.close();
2016                _evictionCursor = null;
2017            }
2018        }
2019    
2020        /**
2021         * Resets the eviction object cursor for the given key
2022         *
2023         * @param key eviction key
2024         */
2025        private void resetEvictionObjectCursor(Object key) {
2026            if (_evictionCursor != null) {
2027                _evictionCursor.close();
2028            }
2029            if (_poolMap == null) {
2030                return;
2031            }
2032            ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
2033            if (pool != null) {
2034                CursorableLinkedList queue = pool.queue;
2035                _evictionCursor = queue.cursor(_lifo ? queue.size() : 0);
2036            }
2037        }
2038    
2039        /**
2040         * Iterates through all the known keys and creates any necessary objects to maintain
2041         * the minimum level of pooled objects.
2042         * @see #getMinIdle
2043         * @see #setMinIdle
2044         * @throws Exception If there was an error whilst creating the pooled objects.
2045         */
2046        private void ensureMinIdle() throws Exception {
2047            //Check if should sustain the pool
2048            if (_minIdle > 0) {
2049                Object[] keysCopy;
2050                synchronized(this) {
2051                    // Get the current set of keys
2052                    keysCopy = _poolMap.keySet().toArray();
2053                }
2054    
2055                // Loop through all elements in _poolList
2056                // Find out the total number of max active and max idle for that class
2057                // If the number is less than the minIdle, do creation loop to boost numbers
2058                for (int i=0; i < keysCopy.length; i++) {
2059                    //Get the next key to process
2060                    ensureMinIdle(keysCopy[i]);
2061                }
2062            }
2063        }
2064    
2065        /**
2066         * Re-creates any needed objects to maintain the minimum levels of
2067         * pooled objects for the specified key.
2068         *
2069         * This method uses {@link #calculateDeficit} to calculate the number
2070         * of objects to be created. {@link #calculateDeficit} can be overridden to
2071         * provide a different method of calculating the number of objects to be
2072         * created.
2073         * @param key The key to process
2074         * @throws Exception If there was an error whilst creating the pooled objects
2075         */
2076        private void ensureMinIdle(Object key) throws Exception {
2077            // Calculate current pool objects
2078            ObjectQueue pool;
2079            synchronized(this) {
2080                pool = (ObjectQueue)(_poolMap.get(key));
2081            }
2082            if (pool == null) {
2083                return;
2084            }
2085    
2086            // this method isn't synchronized so the
2087            // calculateDeficit is done at the beginning
2088            // as a loop limit and a second time inside the loop
2089            // to stop when another thread already returned the
2090            // needed objects
2091            int objectDeficit = calculateDeficit(pool, false);
2092    
2093            for (int i = 0; i < objectDeficit && calculateDeficit(pool, true) > 0; i++) {
2094                try {
2095                    addObject(key);
2096                } finally {
2097                    synchronized (this) {
2098                        pool.decrementInternalProcessingCount();
2099                    }
2100                    allocate();
2101                }
2102            }
2103        }
2104    
2105        //--- non-public methods ----------------------------------------
2106    
2107        /**
2108         * Start the eviction thread or service, or when
2109         * <code>delay</code> is non-positive, stop it
2110         * if it is already running.
2111         *
2112         * @param delay milliseconds between evictor runs.
2113         */
2114        protected synchronized void startEvictor(long delay) {
2115            if (null != _evictor) {
2116                EvictionTimer.cancel(_evictor);
2117                _evictor = null;
2118            }
2119            if (delay > 0) {
2120                _evictor = new Evictor();
2121                EvictionTimer.schedule(_evictor, delay, delay);
2122            }
2123        }
2124    
2125        /**
2126         * Returns pool info including {@link #getNumActive()}, {@link #getNumIdle()}
2127         * and currently defined keys.
2128         * 
2129         * @return string containing debug information
2130         */
2131        synchronized String debugInfo() {
2132            StringBuffer buf = new StringBuffer();
2133            buf.append("Active: ").append(getNumActive()).append("\n");
2134            buf.append("Idle: ").append(getNumIdle()).append("\n");
2135            Iterator it = _poolMap.keySet().iterator();
2136            while (it.hasNext()) {
2137                Object key = it.next();
2138                buf.append("\t").append(key).append(" ").append(_poolMap.get(key)).append("\n");
2139            }
2140            return buf.toString();
2141        }
2142    
2143        /** 
2144         * Returns the number of tests to be performed in an Evictor run,
2145         * based on the current values of <code>_numTestsPerEvictionRun</code>
2146         * and <code>_totalIdle</code>.
2147         * 
2148         * @see #setNumTestsPerEvictionRun
2149         * @return the number of tests for the Evictor to run
2150         */
2151        private synchronized int getNumTests() {
2152            if (_numTestsPerEvictionRun >= 0) {
2153                return Math.min(_numTestsPerEvictionRun, _totalIdle);
2154            } else {
2155                return(int)(Math.ceil(_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
2156            }
2157        }
2158    
2159        /**
2160         * This returns the number of objects to create during the pool
2161         * sustain cycle. This will ensure that the minimum number of idle
2162         * instances is maintained without going past the maxActive value.
2163         * 
2164         * @param pool the ObjectPool to calculate the deficit for
2165         * @param incrementInternal - Should the count of objects currently under
2166         *                            some form of internal processing be
2167         *                            incremented?
2168         * @return The number of objects to be created
2169         */
2170        private synchronized int calculateDeficit(ObjectQueue pool,
2171                boolean incrementInternal) {
2172            int objectDefecit = 0;
2173    
2174            //Calculate no of objects needed to be created, in order to have
2175            //the number of pooled objects < maxActive();
2176            objectDefecit = getMinIdle() - pool.queue.size();
2177            if (getMaxActive() > 0) {
2178                int growLimit = Math.max(0, getMaxActive() - pool.activeCount - pool.queue.size() - pool.internalProcessingCount);
2179                objectDefecit = Math.min(objectDefecit, growLimit);
2180            }
2181    
2182            // Take the maxTotal limit into account
2183            if (getMaxTotal() > 0) {
2184                int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle() - _totalInternalProcessing);
2185                objectDefecit = Math.min(objectDefecit, growLimit);
2186            }
2187    
2188            if (incrementInternal && objectDefecit > 0) {
2189                pool.incrementInternalProcessingCount();
2190            }
2191            return objectDefecit;
2192        }
2193    
2194        //--- inner classes ----------------------------------------------
2195    
2196        /**
2197         * A "struct" that keeps additional information about the actual queue of pooled objects.
2198         */
2199        private class ObjectQueue {
2200            /** Number of instances checked out to clients from this queue */
2201            private int activeCount = 0;
2202            
2203            /** Idle instance queue */
2204            private final CursorableLinkedList queue = new CursorableLinkedList();
2205            
2206            /** Number of instances in process of being created */
2207            private int internalProcessingCount = 0;
2208    
2209            /** Increment the active count for this queue */
2210            void incrementActiveCount() {
2211                synchronized (GenericKeyedObjectPool.this) {
2212                    _totalActive++;
2213                }
2214                activeCount++;
2215            }
2216    
2217            /** Decrement the active count for this queue */
2218            void decrementActiveCount() {
2219                synchronized (GenericKeyedObjectPool.this) {
2220                    _totalActive--;
2221                }
2222                if (activeCount > 0) {
2223                    activeCount--;
2224                }
2225            }
2226    
2227            /** Record the fact that one more instance is queued for creation */
2228            void incrementInternalProcessingCount() {
2229                synchronized (GenericKeyedObjectPool.this) {
2230                    _totalInternalProcessing++;
2231                }
2232                internalProcessingCount++;
2233            }
2234    
2235            /** Decrement the number of instances in process of being created */
2236            void decrementInternalProcessingCount() {
2237                synchronized (GenericKeyedObjectPool.this) {
2238                    _totalInternalProcessing--;
2239                }
2240                internalProcessingCount--;
2241            }
2242        }
2243    
2244        /**
2245         * A simple "struct" encapsulating an object instance and a timestamp.
2246         *
2247         * Implements Comparable, objects are sorted from old to new.
2248         *
2249         * This is also used by {@link GenericObjectPool}.
2250         */
2251        static class ObjectTimestampPair implements Comparable {
2252            //CHECKSTYLE: stop VisibilityModifier
2253            /** 
2254             * Object instance 
2255             * @deprecated this field will be made private and final in version 2.0
2256             */
2257            Object value;
2258            
2259            /**
2260             * timestamp
2261             * @deprecated this field will be made private and final in version 2.0
2262             */
2263            long tstamp;
2264            //CHECKSTYLE: resume VisibilityModifier
2265    
2266            /**
2267             * Create a new ObjectTimestampPair using the given object and the current system time.
2268             * @param val object instance
2269             */
2270            ObjectTimestampPair(Object val) {
2271                this(val, System.currentTimeMillis());
2272            }
2273    
2274            /**
2275             * Create a new ObjectTimeStampPair using the given object and timestamp value.
2276             * @param val object instance
2277             * @param time long representation of timestamp
2278             */
2279            ObjectTimestampPair(Object val, long time) {
2280                value = val;
2281                tstamp = time;
2282            }
2283    
2284            /**
2285             * Returns a string representation.
2286             * 
2287             * @return String representing this ObjectTimestampPair
2288             */
2289            public String toString() {
2290                return value + ";" + tstamp;
2291            }
2292    
2293            /**
2294             * Compares this to another object by casting the argument to an
2295             * ObjectTimestampPair.
2296             * 
2297             * @param obj object to cmpare
2298             * @return result of comparison
2299             */
2300            public int compareTo(Object obj) {
2301                return compareTo((ObjectTimestampPair) obj);
2302            }
2303    
2304            /**
2305             * Compares this to another ObjectTimestampPair, using the timestamp as basis for comparison.
2306             * Implementation is consistent with equals.
2307             * 
2308             * @param other object to compare
2309             * @return result of comparison
2310             */
2311            public int compareTo(ObjectTimestampPair other) {
2312                final long tstampdiff = this.tstamp - other.tstamp;
2313                if (tstampdiff == 0) {
2314                    // make sure the natural ordering is consistent with equals
2315                    // see java.lang.Comparable Javadocs
2316                    return System.identityHashCode(this) - System.identityHashCode(other);
2317                } else {
2318                    // handle int overflow
2319                    return (int)Math.min(Math.max(tstampdiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
2320                }
2321            }
2322    
2323            /**
2324             * @return the value
2325             */
2326            public Object getValue() {
2327                return value;
2328            }
2329    
2330            /**
2331             * @return the tstamp
2332             */
2333            public long getTstamp() {
2334                return tstamp;
2335            }
2336        }
2337    
2338        /**
2339         * The idle object evictor {@link TimerTask}.
2340         * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
2341         */
2342        private class Evictor extends TimerTask {
2343            /**
2344             * Run pool maintenance.  Evict objects qualifying for eviction and then
2345             * invoke {@link GenericKeyedObjectPool#ensureMinIdle()}.
2346             */
2347            public void run() {
2348                //Evict from the pool
2349                try {
2350                    evict();
2351                } catch(Exception e) {
2352                    // ignored
2353                } catch(OutOfMemoryError oome) {
2354                    // Log problem but give evictor thread a chance to continue in
2355                    // case error is recoverable
2356                    oome.printStackTrace(System.err);
2357                }
2358                //Re-create idle instances.
2359                try {
2360                    ensureMinIdle();
2361                } catch (Exception e) {
2362                    // ignored
2363                }
2364            }
2365        }
2366    
2367        /**
2368         * A simple "struct" encapsulating the
2369         * configuration information for a <code>GenericKeyedObjectPool</code>.
2370         * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
2371         * @see GenericKeyedObjectPool#setConfig
2372         */
2373        public static class Config {
2374            //CHECKSTYLE: stop VisibilityModifier
2375            /**
2376             * @see GenericKeyedObjectPool#setMaxIdle
2377             */
2378            public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
2379            /**
2380             * @see GenericKeyedObjectPool#setMaxActive
2381             */
2382            public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
2383            /**
2384             * @see GenericKeyedObjectPool#setMaxTotal
2385             */
2386            public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
2387            /**
2388             * @see GenericKeyedObjectPool#setMinIdle
2389             */
2390            public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
2391            /**
2392             * @see GenericKeyedObjectPool#setMaxWait
2393             */
2394            public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
2395            /**
2396             * @see GenericKeyedObjectPool#setWhenExhaustedAction
2397             */
2398            public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
2399            /**
2400             * @see GenericKeyedObjectPool#setTestOnBorrow
2401             */
2402            public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
2403            /**
2404             * @see GenericKeyedObjectPool#setTestOnReturn
2405             */
2406            public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
2407            /**
2408             * @see GenericKeyedObjectPool#setTestWhileIdle
2409             */
2410            public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
2411            /**
2412             * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
2413             */
2414            public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
2415            /**
2416             * @see GenericKeyedObjectPool#setNumTestsPerEvictionRun
2417             */
2418            public int numTestsPerEvictionRun =  GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
2419            /**
2420             * @see GenericKeyedObjectPool#setMinEvictableIdleTimeMillis
2421             */
2422            public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
2423            /**
2424             * @see GenericKeyedObjectPool#setLifo
2425             */
2426            public boolean lifo = GenericKeyedObjectPool.DEFAULT_LIFO;
2427            //CHECKSTYLE: resume VisibilityModifier
2428        }
2429    
2430        /**
2431         * Latch used to control allocation order of objects to threads to ensure
2432         * fairness. That is, for each key, objects are allocated to threads in the order
2433         * that threads request objects.
2434         * 
2435         * @since 1.5
2436         */
2437        private static final class Latch {
2438            
2439            /** key of associated pool */
2440            private final Object _key;
2441            
2442            /** keyed pool associated with this latch */
2443            private ObjectQueue _pool;
2444            
2445            /** holds an ObjectTimestampPair when this latch has been allocated an instance */
2446            private ObjectTimestampPair _pair;
2447            
2448            /** indicates that this latch can create an instance */
2449            private boolean _mayCreate = false;
2450    
2451            /**
2452             * Create a latch with the given key
2453             * @param key key of the pool associated with this latch
2454             */
2455            private Latch(Object key) {
2456                _key = key;
2457            }
2458    
2459            /**
2460             * Retuns the key of the associated pool
2461             * @return associated pool key
2462             */
2463            private synchronized Object getkey() {
2464                return _key;
2465            }
2466    
2467            /**
2468             * Returns the pool associated with this latch
2469             * @return pool
2470             */
2471            private synchronized ObjectQueue getPool() {
2472                return _pool;
2473            }
2474            
2475            /**
2476             * Sets the pool associated with this latch
2477             * @param pool the pool
2478             */
2479            private synchronized void setPool(ObjectQueue pool) {
2480                _pool = pool;
2481            }
2482    
2483            /**
2484             * Gets the ObjectTimestampPair allocated to this latch.
2485             * Returns null if this latch does not have an instance allocated to it. 
2486             * @return the associated ObjectTimestampPair
2487             */
2488            private synchronized ObjectTimestampPair getPair() {
2489                return _pair;
2490            }
2491            
2492            /**
2493             * Allocate an ObjectTimestampPair to this latch.
2494             * @param pair ObjectTimestampPair on this latch
2495             */
2496            private synchronized void setPair(ObjectTimestampPair pair) {
2497                _pair = pair;
2498            }
2499    
2500            /**
2501             * Whether or not this latch can create an instance
2502             * @return true if this latch has an instance creation permit
2503             */
2504            private synchronized boolean mayCreate() {
2505                return _mayCreate;
2506            }
2507            
2508            /**
2509             * Sets the mayCreate property
2510             * 
2511             * @param mayCreate true means this latch can create an instance
2512             */
2513            private synchronized void setMayCreate(boolean mayCreate) {
2514                _mayCreate = mayCreate;
2515            }
2516    
2517            /**
2518             * Reset the latch data. Used when an allocation fails and the latch
2519             * needs to be re-added to the queue.
2520             */
2521            private synchronized void reset() {
2522                _pair = null;
2523                _mayCreate = false;
2524            }
2525        }
2526    
2527        //--- protected attributes ---------------------------------------
2528    
2529        /**
2530         * The cap on the number of idle instances in the pool.
2531         * @see #setMaxIdle
2532         * @see #getMaxIdle
2533         */
2534        private int _maxIdle = DEFAULT_MAX_IDLE;
2535    
2536        /**
2537         * The minimum no of idle objects to keep in the pool.
2538         * @see #setMinIdle
2539         * @see #getMinIdle
2540         */
2541        private volatile int _minIdle = DEFAULT_MIN_IDLE;
2542    
2543        /**
2544         * The cap on the number of active instances from the pool.
2545         * @see #setMaxActive
2546         * @see #getMaxActive
2547         */
2548        private int _maxActive = DEFAULT_MAX_ACTIVE;
2549    
2550        /**
2551         * The cap on the total number of instances from the pool if non-positive.
2552         * @see #setMaxTotal
2553         * @see #getMaxTotal
2554         */
2555        private int _maxTotal = DEFAULT_MAX_TOTAL;
2556    
2557        /**
2558         * The maximum amount of time (in millis) the
2559         * {@link #borrowObject} method should block before throwing
2560         * an exception when the pool is exhausted and the
2561         * {@link #getWhenExhaustedAction "when exhausted" action} is
2562         * {@link #WHEN_EXHAUSTED_BLOCK}.
2563         *
2564         * When less than or equal to 0, the {@link #borrowObject} method
2565         * may block indefinitely.
2566         *
2567         * @see #setMaxWait
2568         * @see #getMaxWait
2569         * @see #WHEN_EXHAUSTED_BLOCK
2570         * @see #setWhenExhaustedAction
2571         * @see #getWhenExhaustedAction
2572         */
2573        private long _maxWait = DEFAULT_MAX_WAIT;
2574    
2575        /**
2576         * The action to take when the {@link #borrowObject} method
2577         * is invoked when the pool is exhausted (the maximum number
2578         * of "active" objects has been reached).
2579         *
2580         * @see #WHEN_EXHAUSTED_BLOCK
2581         * @see #WHEN_EXHAUSTED_FAIL
2582         * @see #WHEN_EXHAUSTED_GROW
2583         * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
2584         * @see #setWhenExhaustedAction
2585         * @see #getWhenExhaustedAction
2586         */
2587        private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
2588    
2589        /**
2590         * When <code>true</code>, objects will be
2591         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
2592         * before being returned by the {@link #borrowObject}
2593         * method.  If the object fails to validate,
2594         * it will be dropped from the pool, and we will attempt
2595         * to borrow another.
2596         *
2597         * @see #setTestOnBorrow
2598         * @see #getTestOnBorrow
2599         */
2600        private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
2601    
2602        /**
2603         * When <code>true</code>, objects will be
2604         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
2605         * before being returned to the pool within the
2606         * {@link #returnObject}.
2607         *
2608         * @see #getTestOnReturn
2609         * @see #setTestOnReturn
2610         */
2611        private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
2612    
2613        /**
2614         * When <code>true</code>, objects will be
2615         * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
2616         * by the idle object evictor (if any).  If an object
2617         * fails to validate, it will be dropped from the pool.
2618         *
2619         * @see #setTestWhileIdle
2620         * @see #getTestWhileIdle
2621         * @see #getTimeBetweenEvictionRunsMillis
2622         * @see #setTimeBetweenEvictionRunsMillis
2623         */
2624        private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
2625    
2626        /**
2627         * The number of milliseconds to sleep between runs of the
2628         * idle object evictor thread.
2629         * When non-positive, no idle object evictor thread will be
2630         * run.
2631         *
2632         * @see #setTimeBetweenEvictionRunsMillis
2633         * @see #getTimeBetweenEvictionRunsMillis
2634         */
2635        private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
2636    
2637        /**
2638         * The number of objects to examine during each run of the
2639         * idle object evictor thread (if any).
2640         * <p>
2641         * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
2642         * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
2643         * idle objects will be tested per run.
2644         *
2645         * @see #setNumTestsPerEvictionRun
2646         * @see #getNumTestsPerEvictionRun
2647         * @see #getTimeBetweenEvictionRunsMillis
2648         * @see #setTimeBetweenEvictionRunsMillis
2649         */
2650        private int _numTestsPerEvictionRun =  DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
2651    
2652        /**
2653         * The minimum amount of time an object may sit idle in the pool
2654         * before it is eligible for eviction by the idle object evictor
2655         * (if any).
2656         * When non-positive, no objects will be evicted from the pool
2657         * due to idle time alone.
2658         *
2659         * @see #setMinEvictableIdleTimeMillis
2660         * @see #getMinEvictableIdleTimeMillis
2661         * @see #getTimeBetweenEvictionRunsMillis
2662         * @see #setTimeBetweenEvictionRunsMillis
2663         */
2664        private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
2665    
2666        /** My hash of pools (ObjectQueue). */
2667        private Map _poolMap = null;
2668    
2669        /** The total number of active instances. */
2670        private int _totalActive = 0;
2671    
2672        /** The total number of idle instances. */
2673        private int _totalIdle = 0;
2674    
2675        /**
2676         * The number of objects subject to some form of internal processing
2677         * (usually creation or destruction) that should be included in the total
2678         * number of objects but are neither active nor idle.
2679         */
2680        private int _totalInternalProcessing = 0;
2681    
2682        /** My {@link KeyedPoolableObjectFactory}. */
2683        private KeyedPoolableObjectFactory _factory = null;
2684    
2685        /**
2686         * My idle object eviction {@link TimerTask}, if any.
2687         */
2688        private Evictor _evictor = null;
2689    
2690        /**
2691         * A cursorable list of my pools.
2692         * @see GenericKeyedObjectPool.Evictor#run
2693         */
2694        private CursorableLinkedList _poolList = null;
2695    
2696        /** Eviction cursor (over instances within-key) */
2697        private CursorableLinkedList.Cursor _evictionCursor = null;
2698        
2699        /** Eviction cursor (over keys) */
2700        private CursorableLinkedList.Cursor _evictionKeyCursor = null;
2701    
2702        /** Whether or not the pools behave as LIFO queues (last in first out) */
2703        private boolean _lifo = DEFAULT_LIFO;
2704    
2705        /**
2706         * Used to track the order in which threads call {@link #borrowObject()} so
2707         * that objects can be allocated in the order in which the threads requested
2708         * them.
2709         */
2710        private LinkedList _allocationQueue = new LinkedList();
2711    
2712    }