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