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