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