Coverage Report - org.apache.commons.pool.impl.GenericKeyedObjectPool
 
Classes in this File Line Coverage Branch Coverage Complexity
GenericKeyedObjectPool
0%
0/646
0%
0/290
3.151
GenericKeyedObjectPool$1
N/A
N/A
3.151
GenericKeyedObjectPool$Config
0%
0/14
N/A
3.151
GenericKeyedObjectPool$Evictor
0%
0/10
N/A
3.151
GenericKeyedObjectPool$Latch
0%
0/18
N/A
3.151
GenericKeyedObjectPool$ObjectQueue
0%
0/25
0%
0/2
3.151
GenericKeyedObjectPool$ObjectTimestampPair
0%
0/14
0%
0/2
3.151
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.commons.pool.impl;
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.HashMap;
 23  
 import java.util.Iterator;
 24  
 import java.util.LinkedList;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 import java.util.NoSuchElementException;
 28  
 import java.util.Set;
 29  
 import java.util.TreeMap;
 30  
 import java.util.TimerTask;
 31  
 import java.util.Map.Entry;
 32  
 
 33  
 import org.apache.commons.pool.BaseKeyedObjectPool;
 34  
 import org.apache.commons.pool.KeyedObjectPool;
 35  
 import org.apache.commons.pool.KeyedPoolableObjectFactory;
 36  
 import org.apache.commons.pool.PoolUtils;
 37  
 
 38  
 /**
 39  
  * A configurable <code>KeyedObjectPool</code> implementation.
 40  
  * <p>
 41  
  * When coupled with the appropriate {@link KeyedPoolableObjectFactory},
 42  
  * <code>GenericKeyedObjectPool</code> provides robust pooling functionality for
 43  
  * keyed objects. A <code>GenericKeyedObjectPool</code> can be viewed as a map
 44  
  * of pools, keyed on the (unique) key values provided to the
 45  
  * {@link #preparePool preparePool}, {@link #addObject addObject} or
 46  
  * {@link #borrowObject borrowObject} methods. Each time a new key value is
 47  
  * provided to one of these methods, a new pool is created under the given key
 48  
  * to be managed by the containing <code>GenericKeyedObjectPool.</code>
 49  
  * </p>
 50  
  * <p>A <code>GenericKeyedObjectPool</code> provides a number of configurable
 51  
  * parameters:</p>
 52  
  * <ul>
 53  
  *  <li>
 54  
  *    {@link #setMaxActive maxActive} controls the maximum number of objects
 55  
  *    (per key) that can allocated by the pool (checked out to client threads,
 56  
  *    or idle in the pool) at one time.  When non-positive, there is no limit
 57  
  *    to the number of objects per key. When {@link #setMaxActive maxActive} is
 58  
  *    reached, the keyed pool is said to be exhausted.  The default setting for
 59  
  *    this parameter is 8.
 60  
  *  </li>
 61  
  *  <li>
 62  
  *    {@link #setMaxTotal maxTotal} sets a global limit on the number of objects
 63  
  *    that can be in circulation (active or idle) within the combined set of
 64  
  *    pools.  When non-positive, there is no limit to the total number of
 65  
  *    objects in circulation. When {@link #setMaxTotal maxTotal} is exceeded,
 66  
  *    all keyed pools are exhausted. When <code>maxTotal</code> is set to a
 67  
  *    positive value and {@link #borrowObject borrowObject} is invoked
 68  
  *    when at the limit with no idle instances available, an attempt is made to
 69  
  *    create room by clearing the oldest 15% of the elements from the keyed
 70  
  *    pools. The default setting for this parameter is -1 (no limit).
 71  
  *  </li>
 72  
  *  <li>
 73  
  *    {@link #setMaxIdle maxIdle} controls the maximum number of objects that can
 74  
  *    sit idle in the pool (per key) at any time.  When negative, there
 75  
  *    is no limit to the number of objects that may be idle per key. The
 76  
  *    default setting for this parameter is 8.
 77  
  *  </li>
 78  
  *  <li>
 79  
  *    {@link #setWhenExhaustedAction whenExhaustedAction} specifies the
 80  
  *    behavior of the {@link #borrowObject borrowObject} method when a keyed
 81  
  *    pool is exhausted:
 82  
  *    <ul>
 83  
  *    <li>
 84  
  *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
 85  
  *      {@link #WHEN_EXHAUSTED_FAIL}, {@link #borrowObject borrowObject} will throw
 86  
  *      a {@link NoSuchElementException}
 87  
  *    </li>
 88  
  *    <li>
 89  
  *      When {@link #setWhenExhaustedAction whenExhaustedAction} is
 90  
  *      {@link #WHEN_EXHAUSTED_GROW}, {@link #borrowObject borrowObject} will create a new
 91  
  *      object and return it (essentially making {@link #setMaxActive maxActive}
 92  
  *      meaningless.)
 93  
  *    </li>
 94  
  *    <li>
 95  
  *      When {@link #setWhenExhaustedAction whenExhaustedAction}
 96  
  *      is {@link #WHEN_EXHAUSTED_BLOCK}, {@link #borrowObject borrowObject} will block
 97  
  *      (invoke {@link Object#wait() wait} until a new or idle object is available.
 98  
  *      If a positive {@link #setMaxWait maxWait}
 99  
  *      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: 1206500 $ $Date: 2011-11-26 10:09:06 -0700 (Sat, 26 Nov 2011) $
 202  
  * @since Pool 1.0
 203  
  */
 204  0
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         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  0
     }
 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  0
         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,
 505  
                 testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
 506  
                 minEvictableIdleTimeMillis, testWhileIdle);
 507  0
     }
 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  0
         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal,
 538  
                 GenericKeyedObjectPool.DEFAULT_MIN_IDLE, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis,
 539  
                 numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
 540  0
     }
 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  0
         this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn,
 573  
                 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle,
 574  
                 DEFAULT_LIFO);
 575  0
     }
 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  0
             boolean testWhileIdle, boolean lifo) {
 608  0
         _factory = factory;
 609  0
         _maxActive = maxActive;
 610  0
         _lifo = lifo;
 611  0
         switch (whenExhaustedAction) {
 612  
             case WHEN_EXHAUSTED_BLOCK:
 613  
             case WHEN_EXHAUSTED_FAIL:
 614  
             case WHEN_EXHAUSTED_GROW:
 615  0
                 _whenExhaustedAction = whenExhaustedAction;
 616  0
                 break;
 617  
             default:
 618  0
                 throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
 619  
         }
 620  0
         _maxWait = maxWait;
 621  0
         _maxIdle = maxIdle;
 622  0
         _maxTotal = maxTotal;
 623  0
         _minIdle = minIdle;
 624  0
         _testOnBorrow = testOnBorrow;
 625  0
         _testOnReturn = testOnReturn;
 626  0
         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
 627  0
         _numTestsPerEvictionRun = numTestsPerEvictionRun;
 628  0
         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
 629  0
         _testWhileIdle = testWhileIdle;
 630  
 
 631  0
         _poolMap = new HashMap();
 632  0
         _poolList = new CursorableLinkedList();
 633  
 
 634  0
         startEvictor(_timeBetweenEvictionRunsMillis);
 635  0
     }
 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  0
         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  0
         synchronized(this) {
 662  0
             _maxActive = maxActive;
 663  0
         }
 664  0
         allocate();
 665  0
     }
 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  0
         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  0
         synchronized(this) {
 691  0
             _maxTotal = maxTotal;
 692  0
         }
 693  0
         allocate();
 694  0
     }
 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  0
         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  0
         synchronized(this) {
 721  0
             switch(whenExhaustedAction) {
 722  
                 case WHEN_EXHAUSTED_BLOCK:
 723  
                 case WHEN_EXHAUSTED_FAIL:
 724  
                 case WHEN_EXHAUSTED_GROW:
 725  0
                     _whenExhaustedAction = whenExhaustedAction;
 726  0
                     break;
 727  
                 default:
 728  0
                     throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction + " not recognized.");
 729  
             }
 730  0
         }
 731  0
         allocate();
 732  0
     }
 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  0
         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  0
         synchronized(this) {
 771  0
             _maxWait = maxWait;
 772  0
         }
 773  0
         allocate();
 774  0
     }
 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  0
         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  0
         synchronized(this) {
 802  0
             _maxIdle = maxIdle;
 803  0
         }
 804  0
         allocate();
 805  0
     }
 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  0
         _minIdle = poolSize;
 820  0
     }
 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  0
         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  0
         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  0
         _testOnBorrow = testOnBorrow;
 864  0
     }
 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  0
         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  0
         _testOnReturn = testOnReturn;
 890  0
     }
 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  0
         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  0
         _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
 916  0
         startEvictor(_timeBetweenEvictionRunsMillis);
 917  0
     }
 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  0
         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  0
         _numTestsPerEvictionRun = numTestsPerEvictionRun;
 948  0
     }
 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  0
         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  0
         _minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
 977  0
     }
 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  0
         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  0
         _testWhileIdle = testWhileIdle;
 1005  0
     }
 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  0
         setMaxIdle(conf.maxIdle);
 1014  0
         setMaxActive(conf.maxActive);
 1015  0
         setMaxTotal(conf.maxTotal);
 1016  0
         setMinIdle(conf.minIdle);
 1017  0
         setMaxWait(conf.maxWait);
 1018  0
         setWhenExhaustedAction(conf.whenExhaustedAction);
 1019  0
         setTestOnBorrow(conf.testOnBorrow);
 1020  0
         setTestOnReturn(conf.testOnReturn);
 1021  0
         setTestWhileIdle(conf.testWhileIdle);
 1022  0
         setNumTestsPerEvictionRun(conf.numTestsPerEvictionRun);
 1023  0
         setMinEvictableIdleTimeMillis(conf.minEvictableIdleTimeMillis);
 1024  0
         setTimeBetweenEvictionRunsMillis(conf.timeBetweenEvictionRunsMillis);
 1025  0
     }
 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  0
          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  0
          this._lifo = lifo;
 1053  0
      }
 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  0
         long starttime = System.currentTimeMillis();
 1090  0
         Latch latch = new Latch(key);
 1091  
         byte whenExhaustedAction;
 1092  
         long maxWait;
 1093  0
         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  0
             whenExhaustedAction = _whenExhaustedAction;
 1098  0
             maxWait = _maxWait;
 1099  
 
 1100  
             // Add this request to the queue
 1101  0
             _allocationQueue.add(latch);
 1102  0
         }
 1103  
         // Work the allocation queue, allocating idle instances and
 1104  
         // instance creation permits in request arrival order
 1105  0
         allocate();
 1106  
 
 1107  
         for(;;) {
 1108  0
             synchronized (this) {
 1109  0
                 assertOpen();
 1110  0
             }
 1111  
             // If no object was allocated
 1112  0
             if (null == latch.getPair()) {
 1113  
                 // Check to see if we were allowed to create one
 1114  0
                 if (latch.mayCreate()) {
 1115  
                     // allow new object to be created
 1116  
                 } else {
 1117  
                     // the pool is exhausted
 1118  0
                     switch(whenExhaustedAction) {
 1119  
                         case WHEN_EXHAUSTED_GROW:
 1120  
                             // allow new object to be created
 1121  0
                             synchronized (this) {
 1122  
                                 // Make sure another thread didn't allocate us an object
 1123  
                                 // or permit a new object to be created
 1124  0
                                 if (latch.getPair() == null && !latch.mayCreate()) {
 1125  0
                                     _allocationQueue.remove(latch);
 1126  0
                                     latch.getPool().incrementInternalProcessingCount();
 1127  
                                 }
 1128  0
                             }
 1129  0
                         break;
 1130  
                         case WHEN_EXHAUSTED_FAIL:
 1131  0
                             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  0
                                 if (latch.getPair() != null || latch.mayCreate()) {
 1135  0
                                     break;
 1136  
                                 }
 1137  0
                                 _allocationQueue.remove(latch);
 1138  0
                             }
 1139  0
                             throw new NoSuchElementException("Pool exhausted");
 1140  
                         case WHEN_EXHAUSTED_BLOCK:
 1141  
                             try {
 1142  0
                                 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  0
                                     if (latch.getPair() == null && !latch.mayCreate()) {
 1146  0
                                         if (maxWait <= 0) {
 1147  0
                                             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  0
                                             final long elapsed = (System.currentTimeMillis() - starttime);
 1152  0
                                             final long waitTime = maxWait - elapsed;
 1153  0
                                             if (waitTime > 0)
 1154  
                                             {
 1155  0
                                                 latch.wait(waitTime);
 1156  
                                             }
 1157  0
                                         }
 1158  
                                     } else {
 1159  0
                                         break;
 1160  
                                     }
 1161  0
                                 }
 1162  
                                 // see if we were awakened by a closing pool
 1163  0
                                 if(isClosed() == true) {
 1164  0
                                     throw new IllegalStateException("Pool closed");
 1165  
                                 }
 1166  0
                             } catch(InterruptedException e) {
 1167  0
                                 boolean doAllocate = false;
 1168  0
                                 synchronized (this) {
 1169  
                                     // Need to handle the all three possibilities
 1170  0
                                     if (latch.getPair() == null && !latch.mayCreate()) {
 1171  
                                         // Case 1: latch still in allocation queue
 1172  
                                         // Remove latch from the allocation queue
 1173  0
                                         _allocationQueue.remove(latch);
 1174  0
                                     } else if (latch.getPair() == null && latch.mayCreate()) {
 1175  
                                         // Case 2: latch has been given permission to create
 1176  
                                         //         a new object
 1177  0
                                         latch.getPool().decrementInternalProcessingCount();
 1178  0
                                         doAllocate = true;
 1179  
                                     } else {
 1180  
                                         // Case 3: An object has been allocated
 1181  0
                                         latch.getPool().decrementInternalProcessingCount();
 1182  0
                                         latch.getPool().incrementActiveCount();
 1183  0
                                         returnObject(latch.getkey(), latch.getPair().getValue());
 1184  
                                     }
 1185  0
                                 }
 1186  0
                                 if (doAllocate) {
 1187  0
                                     allocate();
 1188  
                                 }
 1189  0
                                 Thread.currentThread().interrupt();
 1190  0
                                 throw e;
 1191  0
                             }
 1192  0
                             if (maxWait > 0 && ((System.currentTimeMillis() - starttime) >= maxWait)) {
 1193  0
                                 synchronized (this) {
 1194  
                                     // Make sure allocate hasn't already assigned an object
 1195  
                                     // in a different thread or permitted a new object to be created
 1196  0
                                     if (latch.getPair() == null && !latch.mayCreate()) {
 1197  0
                                         _allocationQueue.remove(latch);
 1198  
                                     } else {
 1199  0
                                         break;
 1200  
                                     }
 1201  0
                                 }
 1202  0
                                 throw new NoSuchElementException("Timeout waiting for idle object");
 1203  
                             } else {
 1204  
                                 continue; // keep looping
 1205  
                             }
 1206  
                         default:
 1207  0
                             throw new IllegalArgumentException("whenExhaustedAction " + whenExhaustedAction +
 1208  
                                     " not recognized.");
 1209  
                     }
 1210  
                 }
 1211  
             }
 1212  
 
 1213  0
             boolean newlyCreated = false;
 1214  0
             if (null == latch.getPair()) {
 1215  
                 try {
 1216  0
                     Object obj = _factory.makeObject(key);
 1217  0
                     latch.setPair(new ObjectTimestampPair(obj));
 1218  0
                     newlyCreated = true;
 1219  
                 } finally {
 1220  0
                     if (!newlyCreated) {
 1221  
                         // object cannot be created
 1222  0
                         synchronized (this) {
 1223  0
                             latch.getPool().decrementInternalProcessingCount();
 1224  
                             // No need to reset latch - about to throw exception
 1225  0
                         }
 1226  0
                         allocate();
 1227  
                     }
 1228  
                 }
 1229  
             }
 1230  
 
 1231  
             // activate & validate the object
 1232  
             try {
 1233  0
                 _factory.activateObject(key, latch.getPair().value);
 1234  0
                 if (_testOnBorrow && !_factory.validateObject(key, latch.getPair().value)) {
 1235  0
                     throw new Exception("ValidateObject failed");
 1236  
                 }
 1237  0
                 synchronized (this) {
 1238  0
                     latch.getPool().decrementInternalProcessingCount();
 1239  0
                     latch.getPool().incrementActiveCount();
 1240  0
                 }
 1241  0
                 return latch.getPair().value;
 1242  0
             } catch (Throwable e) {
 1243  0
                 PoolUtils.checkRethrow(e);
 1244  
                 // object cannot be activated or is invalid
 1245  
                 try {
 1246  0
                     _factory.destroyObject(key, latch.getPair().value);
 1247  0
                 } catch (Throwable e2) {
 1248  0
                     PoolUtils.checkRethrow(e2);
 1249  
                     // cannot destroy broken object
 1250  0
                 }
 1251  0
                 synchronized (this) {
 1252  0
                     latch.getPool().decrementInternalProcessingCount();
 1253  0
                     if (!newlyCreated) {
 1254  0
                         latch.reset();
 1255  0
                         _allocationQueue.add(0, latch);
 1256  
                     }
 1257  0
                 }
 1258  0
                 allocate();
 1259  0
                 if (newlyCreated) {
 1260  0
                     throw new NoSuchElementException(
 1261  
                        "Could not create a validated object, cause: " +
 1262  
                             e.getMessage());
 1263  
                 }
 1264  
                 else {
 1265  0
                     continue; // keep looping
 1266  
                 }
 1267  
             }
 1268  
         }
 1269  
     }
 1270  
 
 1271  
     /**
 1272  
      * Allocate available instances to latches in the allocation queue.  Then
 1273  
      * set _mayCreate to true for as many additional latches remaining in queue
 1274  
      * as _maxActive allows for each key. This method <b>MUST NOT</b> be called
 1275  
      * from inside a sync block.
 1276  
      */
 1277  
     private void allocate() {
 1278  0
         boolean clearOldest = false;
 1279  
 
 1280  0
         synchronized (this) {
 1281  0
             if (isClosed()) return;
 1282  
             
 1283  0
             Iterator allocationQueueIter = _allocationQueue.iterator();
 1284  
             
 1285  0
             while (allocationQueueIter.hasNext()) {
 1286  
                 // First use any objects in the pool to clear the queue
 1287  0
                 Latch latch = (Latch) allocationQueueIter.next();
 1288  0
                 ObjectQueue pool = (ObjectQueue)(_poolMap.get(latch.getkey()));
 1289  0
                 if (null == pool) {
 1290  0
                     pool = new ObjectQueue();
 1291  0
                     _poolMap.put(latch.getkey(), pool);
 1292  0
                     _poolList.add(latch.getkey());
 1293  
                 }
 1294  0
                 latch.setPool(pool);
 1295  0
                 if (!pool.queue.isEmpty()) {
 1296  0
                     allocationQueueIter.remove();
 1297  0
                     latch.setPair(
 1298  
                             (ObjectTimestampPair) pool.queue.removeFirst());
 1299  0
                     pool.incrementInternalProcessingCount();
 1300  0
                     _totalIdle--;
 1301  0
                     synchronized (latch) {
 1302  0
                         latch.notify();
 1303  0
                     }
 1304  
                     // Next item in queue
 1305  0
                     continue;
 1306  
                 }
 1307  
 
 1308  
                 // If there is a totalMaxActive and we are at the limit then
 1309  
                 // we have to make room
 1310  0
                 if ((_maxTotal > 0) &&
 1311  
                         (_totalActive + _totalIdle + _totalInternalProcessing >= _maxTotal)) {
 1312  0
                     clearOldest = true;
 1313  0
                     break;
 1314  
                 }
 1315  
 
 1316  
                 // Second utilise any spare capacity to create new objects
 1317  0
                 if ((_maxActive < 0 || pool.activeCount + pool.internalProcessingCount < _maxActive) &&
 1318  
                         (_maxTotal < 0 || _totalActive + _totalIdle + _totalInternalProcessing < _maxTotal)) {
 1319  
                     // allow new object to be created
 1320  0
                     allocationQueueIter.remove();
 1321  0
                     latch.setMayCreate(true);
 1322  0
                     pool.incrementInternalProcessingCount();
 1323  0
                     synchronized (latch) {
 1324  0
                         latch.notify();
 1325  0
                     }
 1326  
                     // Next item in queue
 1327  0
                     continue;
 1328  
                 }
 1329  
 
 1330  
                 // If there is no per-key limit and we reach this point we
 1331  
                 // must have allocated all the objects we possibly can and there
 1332  
                 // is no point looking at the rest of the allocation queue
 1333  0
                 if (_maxActive < 0) {
 1334  0
                     break;
 1335  
                 }
 1336  0
             }
 1337  0
         }
 1338  
         
 1339  0
         if (clearOldest) {
 1340  
             /* Clear oldest calls factory methods so it must be called from
 1341  
              * outside the sync block.
 1342  
              * It also needs to be outside the sync block as it calls
 1343  
              * allocate(). If called inside the sync block, the call to
 1344  
              * allocate() would be able to enter the sync block (since the
 1345  
              * thread already has the lock) which may have unexpected,
 1346  
              * unpleasant results.
 1347  
              */
 1348  0
             clearOldest();
 1349  
         }
 1350  0
     }
 1351  
     
 1352  
     /**
 1353  
      * Clears any objects sitting idle in the pool by removing them from the
 1354  
      * idle instance pool and then invoking the configured PoolableObjectFactory's
 1355  
      * {@link KeyedPoolableObjectFactory#destroyObject(Object, Object)} method on
 1356  
      * each idle instance.
 1357  
      *  
 1358  
      * <p> Implementation notes:
 1359  
      * <ul><li>This method does not destroy or effect in any way instances that are
 1360  
      * checked out when it is invoked.</li>
 1361  
      * <li>Invoking this method does not prevent objects being
 1362  
      * returned to the idle instance pool, even during its execution. It locks
 1363  
      * the pool only during instance removal. Additional instances may be returned
 1364  
      * while removed items are being destroyed.</li>
 1365  
      * <li>Exceptions encountered destroying idle instances are swallowed.</li></ul></p>
 1366  
      */
 1367  
     public void clear() {
 1368  0
         Map toDestroy = new HashMap();
 1369  0
         synchronized (this) {
 1370  0
             for (Iterator it = _poolMap.keySet().iterator(); it.hasNext();) {
 1371  0
                 Object key = it.next();
 1372  0
                 ObjectQueue pool = (ObjectQueue)_poolMap.get(key);
 1373  
                 // Copy objects to new list so pool.queue can be cleared inside
 1374  
                 // the sync
 1375  0
                 List objects = new ArrayList();
 1376  0
                 objects.addAll(pool.queue);
 1377  0
                 toDestroy.put(key, objects);
 1378  0
                 it.remove();
 1379  0
                 _poolList.remove(key);
 1380  0
                 _totalIdle = _totalIdle - pool.queue.size();
 1381  0
                 _totalInternalProcessing =
 1382  
                     _totalInternalProcessing + pool.queue.size();
 1383  0
                 pool.queue.clear();
 1384  0
             }
 1385  0
         }
 1386  0
         destroy(toDestroy, _factory);
 1387  0
     }
 1388  
 
 1389  
     /**
 1390  
      * Clears oldest 15% of objects in pool.  The method sorts the
 1391  
      * objects into a TreeMap and then iterates the first 15% for removal.
 1392  
      * 
 1393  
      * @since Pool 1.3
 1394  
      */
 1395  
     public void clearOldest() {
 1396  
         // Map of objects to destroy my key
 1397  0
         final Map toDestroy = new HashMap();
 1398  
 
 1399  
         // build sorted map of idle objects
 1400  0
         final Map map = new TreeMap();
 1401  0
         synchronized (this) {
 1402  0
             for (Iterator keyiter = _poolMap.keySet().iterator(); keyiter.hasNext();) {
 1403  0
                 final Object key = keyiter.next();
 1404  0
                 final CursorableLinkedList list = ((ObjectQueue)_poolMap.get(key)).queue;
 1405  0
                 for (Iterator it = list.iterator(); it.hasNext();) {
 1406  
                     // each item into the map uses the objectimestamppair object
 1407  
                     // as the key.  It then gets sorted based on the timstamp field
 1408  
                     // each value in the map is the parent list it belongs in.
 1409  0
                     map.put(it.next(), key);
 1410  
                 }
 1411  0
             }
 1412  
 
 1413  
             // Now iterate created map and kill the first 15% plus one to account for zero
 1414  0
             Set setPairKeys = map.entrySet();
 1415  0
             int itemsToRemove = ((int) (map.size() * 0.15)) + 1;
 1416  
 
 1417  0
             Iterator iter = setPairKeys.iterator();
 1418  0
             while (iter.hasNext() && itemsToRemove > 0) {
 1419  0
                 Map.Entry entry = (Map.Entry) iter.next();
 1420  
                 // kind of backwards on naming.  In the map, each key is the objecttimestamppair
 1421  
                 // because it has the ordering with the timestamp value.  Each value that the
 1422  
                 // key references is the key of the list it belongs to.
 1423  0
                 Object key = entry.getValue();
 1424  0
                 ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) entry.getKey();
 1425  0
                 ObjectQueue objectQueue = (ObjectQueue)_poolMap.get(key);
 1426  0
                 final CursorableLinkedList list = objectQueue.queue;
 1427  0
                 list.remove(pairTimeStamp);
 1428  
 
 1429  0
                 if (toDestroy.containsKey(key)) {
 1430  0
                     ((List)toDestroy.get(key)).add(pairTimeStamp);
 1431  
                 } else {
 1432  0
                     List listForKey = new ArrayList();
 1433  0
                     listForKey.add(pairTimeStamp);
 1434  0
                     toDestroy.put(key, listForKey);
 1435  
                 }
 1436  0
                 objectQueue.incrementInternalProcessingCount();
 1437  0
                 _totalIdle--;
 1438  0
                 itemsToRemove--;
 1439  0
             }
 1440  
 
 1441  0
         }
 1442  0
         destroy(toDestroy, _factory);
 1443  0
     }
 1444  
 
 1445  
     /**
 1446  
      * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>.
 1447  
      *
 1448  
      * @param key the key to clear
 1449  
      */
 1450  
     public void clear(Object key) {
 1451  0
         Map toDestroy = new HashMap();
 1452  
 
 1453  
         final ObjectQueue pool;
 1454  0
         synchronized (this) {
 1455  0
             pool = (ObjectQueue)(_poolMap.remove(key));
 1456  0
             if (pool == null) {
 1457  0
                 return;
 1458  
             } else {
 1459  0
                 _poolList.remove(key);
 1460  
             }
 1461  
             // Copy objects to new list so pool.queue can be cleared inside
 1462  
             // the sync
 1463  0
             List objects = new ArrayList();
 1464  0
             objects.addAll(pool.queue);
 1465  0
             toDestroy.put(key, objects);
 1466  0
             _totalIdle = _totalIdle - pool.queue.size();
 1467  0
             _totalInternalProcessing =
 1468  
                 _totalInternalProcessing + pool.queue.size();
 1469  0
             pool.queue.clear();
 1470  0
         }
 1471  0
         destroy(toDestroy, _factory);
 1472  0
     }
 1473  
 
 1474  
     /**
 1475  
      * Assuming Map<Object,Collection<ObjectTimestampPair>>, destroy all
 1476  
      * ObjectTimestampPair.value using the supplied factory.
 1477  
      * 
 1478  
      * @param m Map containing keyed pools to clear
 1479  
      * @param factory KeyedPoolableObjectFactory used to destroy the objects
 1480  
      */
 1481  
     private void destroy(Map m, KeyedPoolableObjectFactory factory) {
 1482  0
         for (Iterator entries = m.entrySet().iterator(); entries.hasNext();) {
 1483  0
             Map.Entry entry = (Entry) entries.next();
 1484  0
             Object key = entry.getKey();
 1485  0
             Collection c = (Collection) entry.getValue();
 1486  0
             for (Iterator it = c.iterator(); it.hasNext();) {
 1487  
                 try {
 1488  0
                     factory.destroyObject(
 1489  
                             key,((ObjectTimestampPair)(it.next())).value);
 1490  0
                 } catch(Exception e) {
 1491  
                     // ignore error, keep destroying the rest
 1492  0
                 } finally {
 1493  0
                     synchronized(this) {
 1494  0
                         ObjectQueue objectQueue =
 1495  
                                 (ObjectQueue) _poolMap.get(key);
 1496  0
                         if (objectQueue != null) {
 1497  0
                             objectQueue.decrementInternalProcessingCount();
 1498  0
                             if (objectQueue.internalProcessingCount == 0 &&
 1499  
                                     objectQueue.activeCount == 0 &&
 1500  
                                     objectQueue.queue.isEmpty()) {
 1501  0
                                 _poolMap.remove(key);
 1502  0
                                 _poolList.remove(key);
 1503  
                             }
 1504  
                         } else {
 1505  0
                             _totalInternalProcessing--;
 1506  
                         }
 1507  0
                     }
 1508  0
                     allocate();
 1509  0
                 }
 1510  
             }
 1511  
 
 1512  0
         }
 1513  0
     }
 1514  
 
 1515  
     /**
 1516  
      * Returns the total number of instances current borrowed from this pool but not yet returned.
 1517  
      *
 1518  
      * @return the total number of instances currently borrowed from this pool
 1519  
      */
 1520  
     public synchronized int getNumActive() {
 1521  0
         return _totalActive;
 1522  
     }
 1523  
 
 1524  
     /**
 1525  
      * Returns the total number of instances currently idle in this pool.
 1526  
      *
 1527  
      * @return the total number of instances currently idle in this pool
 1528  
      */
 1529  
     public synchronized int getNumIdle() {
 1530  0
         return _totalIdle;
 1531  
     }
 1532  
 
 1533  
     /**
 1534  
      * Returns the number of instances currently borrowed from but not yet returned
 1535  
      * to the pool corresponding to the given <code>key</code>.
 1536  
      *
 1537  
      * @param key the key to query
 1538  
      * @return the number of instances corresponding to the given <code>key</code> currently borrowed in this pool
 1539  
      */
 1540  
     public synchronized int getNumActive(Object key) {
 1541  0
         final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
 1542  0
         return pool != null ? pool.activeCount : 0;
 1543  
     }
 1544  
 
 1545  
     /**
 1546  
      * Returns the number of instances corresponding to the given <code>key</code> currently idle in this pool.
 1547  
      *
 1548  
      * @param key the key to query
 1549  
      * @return the number of instances corresponding to the given <code>key</code> currently idle in this pool
 1550  
      */
 1551  
     public synchronized int getNumIdle(Object key) {
 1552  0
         final ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
 1553  0
         return pool != null ? pool.queue.size() : 0;
 1554  
     }
 1555  
 
 1556  
     /**
 1557  
      * <p>Returns an object to a keyed pool.</p>
 1558  
      * 
 1559  
      * <p>For the pool to function correctly, the object instance <strong>must</strong> have been borrowed
 1560  
      * from the pool (under the same key) and not yet returned. Repeated <code>returnObject</code> calls on
 1561  
      * the same object/key pair (with no <code>borrowObject</code> calls in between) will result in multiple
 1562  
      * references to the object in the idle instance pool.</p>
 1563  
      * 
 1564  
      * <p>If {@link #getMaxIdle() maxIdle} is set to a positive value and the number of idle instances under the given
 1565  
      * key has reached this value, the returning instance is destroyed.</p>
 1566  
      * 
 1567  
      * <p>If {@link #getTestOnReturn() testOnReturn} == true, the returning instance is validated before being returned
 1568  
      * to the idle instance pool under the given key.  In this case, if validation fails, the instance is destroyed.</p>
 1569  
      * 
 1570  
      * @param key pool key
 1571  
      * @param obj instance to return to the keyed pool
 1572  
      * @throws Exception
 1573  
      */
 1574  
     public void returnObject(Object key, Object obj) throws Exception {
 1575  
         try {
 1576  0
             addObjectToPool(key, obj, true);
 1577  0
         } catch (Exception e) {
 1578  0
             if (_factory != null) {
 1579  
                 try {
 1580  0
                     _factory.destroyObject(key, obj);
 1581  0
                 } catch (Exception e2) {
 1582  
                     // swallowed
 1583  0
                 }
 1584  
                 // TODO: Correctness here depends on control in addObjectToPool.
 1585  
                 // These two methods should be refactored, removing the
 1586  
                 // "behavior flag", decrementNumActive, from addObjectToPool.
 1587  0
                 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
 1588  0
                 if (pool != null) {
 1589  0
                     synchronized(this) {
 1590  0
                         pool.decrementActiveCount();
 1591  0
                         if (pool.queue.isEmpty() &&
 1592  
                                 pool.activeCount == 0 &&
 1593  
                                 pool.internalProcessingCount == 0) {
 1594  0
                             _poolMap.remove(key);
 1595  0
                             _poolList.remove(key);
 1596  
                         }
 1597  0
                     }
 1598  0
                     allocate();
 1599  
                 }
 1600  
             }
 1601  0
         }
 1602  0
     }
 1603  
 
 1604  
     /**
 1605  
      * <p>Adds an object to the keyed pool.</p>
 1606  
      * 
 1607  
      * <p>Validates the object if testOnReturn == true and passivates it before returning it to the pool.
 1608  
      * if validation or passivation fails, or maxIdle is set and there is no room in the pool, the instance
 1609  
      * is destroyed.</p>
 1610  
      * 
 1611  
      * <p>Calls {@link #allocate()} on successful completion</p>
 1612  
      * 
 1613  
      * @param key pool key
 1614  
      * @param obj instance to add to the keyed pool
 1615  
      * @param decrementNumActive whether or not to decrement the active count associated with the keyed pool
 1616  
      * @throws Exception
 1617  
      */
 1618  
     private void addObjectToPool(Object key, Object obj,
 1619  
             boolean decrementNumActive) throws Exception {
 1620  
 
 1621  
         // if we need to validate this object, do so
 1622  0
         boolean success = true; // whether or not this object passed validation
 1623  0
         if (_testOnReturn && !_factory.validateObject(key, obj)) {
 1624  0
             success = false;
 1625  
         } else {
 1626  0
             _factory.passivateObject(key, obj);
 1627  
         }
 1628  
 
 1629  0
         boolean shouldDestroy = !success;
 1630  
         ObjectQueue pool;
 1631  
 
 1632  
         // Add instance to pool if there is room and it has passed validation
 1633  
         // (if testOnreturn is set)
 1634  0
         boolean doAllocate = false;
 1635  0
         synchronized (this) {
 1636  
             // grab the pool (list) of objects associated with the given key
 1637  0
             pool = (ObjectQueue) (_poolMap.get(key));
 1638  
             // if it doesn't exist, create it
 1639  0
             if (null == pool) {
 1640  0
                 pool = new ObjectQueue();
 1641  0
                 _poolMap.put(key, pool);
 1642  0
                 _poolList.add(key);
 1643  
             }
 1644  0
             if (isClosed()) {
 1645  0
                 shouldDestroy = true;
 1646  
             } else {
 1647  
                 // if there's no space in the pool, flag the object for destruction
 1648  
                 // else if we passivated successfully, return it to the pool
 1649  0
                 if (_maxIdle >= 0 && (pool.queue.size() >= _maxIdle)) {
 1650  0
                     shouldDestroy = true;
 1651  0
                 } else if (success) {
 1652  
                     // borrowObject always takes the first element from the queue,
 1653  
                     // so for LIFO, push on top, FIFO add to end
 1654  0
                     if (_lifo) {
 1655  0
                         pool.queue.addFirst(new ObjectTimestampPair(obj));
 1656  
                     } else {
 1657  0
                         pool.queue.addLast(new ObjectTimestampPair(obj));
 1658  
                     }
 1659  0
                     _totalIdle++;
 1660  0
                     if (decrementNumActive) {
 1661  0
                         pool.decrementActiveCount();
 1662  
                     }
 1663  0
                     doAllocate = true;
 1664  
                 }
 1665  
             }
 1666  0
         }
 1667  0
         if (doAllocate) {
 1668  0
             allocate();
 1669  
         }
 1670  
 
 1671  
         // Destroy the instance if necessary
 1672  0
         if (shouldDestroy) {
 1673  
             try {
 1674  0
                 _factory.destroyObject(key, obj);
 1675  0
             } catch(Exception e) {
 1676  
                 // ignored?
 1677  0
             }
 1678  
             // Decrement active count *after* destroy if applicable
 1679  0
             if (decrementNumActive) {
 1680  0
                 synchronized(this) {
 1681  0
                     pool.decrementActiveCount();
 1682  0
                     if (pool.queue.isEmpty() &&
 1683  
                             pool.activeCount == 0 &&
 1684  
                             pool.internalProcessingCount == 0) {
 1685  0
                         _poolMap.remove(key);
 1686  0
                         _poolList.remove(key);
 1687  
                     }
 1688  0
                 }
 1689  0
                 allocate();
 1690  
             }
 1691  
         }
 1692  0
     }
 1693  
 
 1694  
     /**
 1695  
      * {@inheritDoc}
 1696  
      * <p>Activation of this method decrements the active count associated with the given keyed pool 
 1697  
      * and attempts to destroy <code>obj.</code></p>
 1698  
      * 
 1699  
      * @param key pool key
 1700  
      * @param obj instance to invalidate
 1701  
      * @throws Exception if an exception occurs destroying the object
 1702  
      */
 1703  
     public void invalidateObject(Object key, Object obj) throws Exception {
 1704  
         try {
 1705  0
             _factory.destroyObject(key, obj);
 1706  0
         } finally {
 1707  0
             synchronized (this) {
 1708  0
                 ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
 1709  0
                 if (null == pool) {
 1710  0
                     pool = new ObjectQueue();
 1711  0
                     _poolMap.put(key, pool);
 1712  0
                     _poolList.add(key);
 1713  
                 }
 1714  0
                 pool.decrementActiveCount();
 1715  0
             }
 1716  0
             allocate(); // _totalActive has changed
 1717  0
         }
 1718  0
     }
 1719  
 
 1720  
     /**
 1721  
      * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory},
 1722  
      * passivate it, and then place it in the idle object pool.
 1723  
      * <code>addObject</code> is useful for "pre-loading" a pool with idle objects.
 1724  
      *
 1725  
      * @param key the key a new instance should be added to
 1726  
      * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails.
 1727  
      * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been
 1728  
      * called on this pool.
 1729  
      */
 1730  
     public void addObject(Object key) throws Exception {
 1731  0
         assertOpen();
 1732  0
         if (_factory == null) {
 1733  0
             throw new IllegalStateException("Cannot add objects without a factory.");
 1734  
         }
 1735  0
         Object obj = _factory.makeObject(key);
 1736  
         try {
 1737  0
             assertOpen();
 1738  0
             addObjectToPool(key, obj, false);
 1739  0
         } catch (IllegalStateException ex) { // Pool closed
 1740  
             try {
 1741  0
                 _factory.destroyObject(key, obj);
 1742  0
             } catch (Exception ex2) {
 1743  
                 // swallow
 1744  0
             }
 1745  0
             throw ex;
 1746  0
         }
 1747  0
     }
 1748  
 
 1749  
     /**
 1750  
      * Registers a key for pool control.
 1751  
      *
 1752  
      * If <code>populateImmediately</code> is <code>true</code> and
 1753  
      * <code>minIdle > 0,</code> the pool under the given key will be
 1754  
      * populated immediately with <code>minIdle</code> idle instances.
 1755  
      *
 1756  
      * @param key - The key to register for pool control.
 1757  
      * @param populateImmediately - If this is <code>true</code>, the pool
 1758  
      * will be populated immediately.
 1759  
      * @since Pool 1.3
 1760  
      */
 1761  
     public synchronized void preparePool(Object key, boolean populateImmediately) {
 1762  0
         ObjectQueue pool = (ObjectQueue)(_poolMap.get(key));
 1763  0
         if (null == pool) {
 1764  0
             pool = new ObjectQueue();
 1765  0
             _poolMap.put(key,pool);
 1766  0
             _poolList.add(key);
 1767  
         }
 1768  
 
 1769  0
         if (populateImmediately) {
 1770  
             try {
 1771  
                 // Create the pooled objects
 1772  0
                 ensureMinIdle(key);
 1773  
             }
 1774  0
             catch (Exception e) {
 1775  
                 //Do nothing
 1776  0
             }
 1777  
         }
 1778  0
     }
 1779  
 
 1780  
     /**
 1781  
      * <p>Closes the keyed object pool.  Once the pool is closed, {@link #borrowObject(Object)}
 1782  
      * will fail with IllegalStateException, but {@link #returnObject(Object, Object)} and
 1783  
      * {@link #invalidateObject(Object, Object)} will continue to work, with returned objects
 1784  
      * destroyed on return.</p>
 1785  
      * 
 1786  
      * <p>Destroys idle instances in the pool by invoking {@link #clear()}.</p> 
 1787  
      * 
 1788  
      * @throws Exception
 1789  
      */
 1790  
     public void close() throws Exception {
 1791  0
         super.close();
 1792  0
         synchronized (this) {
 1793  0
             clear();
 1794  0
             if (null != _evictionCursor) {
 1795  0
                 _evictionCursor.close();
 1796  0
                 _evictionCursor = null;
 1797  
             }
 1798  0
             if (null != _evictionKeyCursor) {
 1799  0
                 _evictionKeyCursor.close();
 1800  0
                 _evictionKeyCursor = null;
 1801  
             }
 1802  0
             startEvictor(-1L);
 1803  
             
 1804  0
             while(_allocationQueue.size() > 0) {
 1805  0
                 Latch l = (Latch) _allocationQueue.removeFirst();
 1806  
                 
 1807  0
                 synchronized (l) {
 1808  
                     // notify the waiting thread
 1809  0
                     l.notify();
 1810  0
                 }
 1811  0
             }
 1812  0
         }
 1813  0
     }
 1814  
 
 1815  
     /**
 1816  
      * <p>Sets the keyed poolable object factory associated with this pool.</p>
 1817  
      * 
 1818  
      * <p>If this method is called when objects are checked out of any of the keyed pools,
 1819  
      * an IllegalStateException is thrown.  Calling this method also has the side effect of
 1820  
      * destroying any idle instances in existing keyed pools, using the original factory.</p>
 1821  
      * 
 1822  
      * @param factory KeyedPoolableObjectFactory to use when creating keyed object pool instances
 1823  
      * @throws IllegalStateException if there are active (checked out) instances associated with this keyed object pool
 1824  
      * @deprecated to be removed in version 2.0
 1825  
      */
 1826  
     public void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
 1827  0
         Map toDestroy = new HashMap();
 1828  0
         final KeyedPoolableObjectFactory oldFactory = _factory;
 1829  0
         synchronized (this) {
 1830  0
             assertOpen();
 1831  0
             if (0 < getNumActive()) {
 1832  0
                 throw new IllegalStateException("Objects are already active");
 1833  
             } else {
 1834  0
                 for (Iterator it = _poolMap.keySet().iterator(); it.hasNext();) {
 1835  0
                     Object key = it.next();
 1836  0
                     ObjectQueue pool = (ObjectQueue)_poolMap.get(key);
 1837  0
                     if (pool != null) {
 1838  
                         // Copy objects to new list so pool.queue can be cleared
 1839  
                         // inside the sync
 1840  0
                         List objects = new ArrayList();
 1841  0
                         objects.addAll(pool.queue);
 1842  0
                         toDestroy.put(key, objects);
 1843  0
                         it.remove();
 1844  0
                         _poolList.remove(key);
 1845  0
                         _totalIdle = _totalIdle - pool.queue.size();
 1846  0
                         _totalInternalProcessing =
 1847  
                             _totalInternalProcessing + pool.queue.size();
 1848  0
                         pool.queue.clear();
 1849  
                     }
 1850  0
                 }
 1851  0
                 _factory = factory;
 1852  
             }
 1853  0
         }
 1854  0
         destroy(toDestroy, oldFactory);
 1855  0
     }
 1856  
 
 1857  
     /**
 1858  
      * <p>Perform <code>numTests</code> idle object eviction tests, evicting
 1859  
      * examined objects that meet the criteria for eviction. If
 1860  
      * <code>testWhileIdle</code> is true, examined objects are validated
 1861  
      * when visited (and removed if invalid); otherwise only objects that
 1862  
      * have been idle for more than <code>minEvicableIdletimeMillis</code>
 1863  
      * are removed.</p>
 1864  
      *
 1865  
      * <p>Successive activations of this method examine objects in keyed pools
 1866  
      * in sequence, cycling through the keys and examining objects in
 1867  
      * oldest-to-youngest order within the keyed pools.</p>
 1868  
      *
 1869  
      * @throws Exception when there is a problem evicting idle objects.
 1870  
      */
 1871  
     public void evict() throws Exception {
 1872  0
         Object key = null;
 1873  
         boolean testWhileIdle;
 1874  
         long minEvictableIdleTimeMillis;
 1875  
 
 1876  0
         synchronized (this) {
 1877  
             // Get local copy of current config. Can't sync when used later as
 1878  
             // it can result in a deadlock. Has the added advantage that config
 1879  
             // is consistent for entire method execution
 1880  0
             testWhileIdle = _testWhileIdle;
 1881  0
             minEvictableIdleTimeMillis = _minEvictableIdleTimeMillis;
 1882  
 
 1883  
             // Initialize key to last key value
 1884  0
             if (_evictionKeyCursor != null &&
 1885  
                     _evictionKeyCursor._lastReturned != null) {
 1886  0
                 key = _evictionKeyCursor._lastReturned.value();
 1887  
             }
 1888  0
         }
 1889  
 
 1890  0
         for (int i=0, m=getNumTests(); i<m; i++) {
 1891  
             final ObjectTimestampPair pair;
 1892  0
             synchronized (this) {
 1893  
                 // make sure pool map is not empty; otherwise do nothing
 1894  0
                 if (_poolMap == null || _poolMap.size() == 0) {
 1895  0
                     continue;
 1896  
                 }
 1897  
 
 1898  
                 // if we don't have a key cursor, then create one
 1899  0
                 if (null == _evictionKeyCursor) {
 1900  0
                     resetEvictionKeyCursor();
 1901  0
                     key = null;
 1902  
                 }
 1903  
 
 1904  
                 // if we don't have an object cursor, create one
 1905  0
                 if (null == _evictionCursor) {
 1906  
                     // if the _evictionKeyCursor has a next value, use this key
 1907  0
                     if (_evictionKeyCursor.hasNext()) {
 1908  0
                         key = _evictionKeyCursor.next();
 1909  0
                         resetEvictionObjectCursor(key);
 1910  
                     } else {
 1911  
                         // Reset the key cursor and try again
 1912  0
                         resetEvictionKeyCursor();
 1913  0
                         if (_evictionKeyCursor != null) {
 1914  0
                             if (_evictionKeyCursor.hasNext()) {
 1915  0
                                 key = _evictionKeyCursor.next();
 1916  0
                                 resetEvictionObjectCursor(key);
 1917  
                             }
 1918  
                         }
 1919  
                     }
 1920  
                 }
 1921  
 
 1922  0
                 if (_evictionCursor == null) {
 1923  0
                     continue; // should never happen; do nothing
 1924  
                 }
 1925  
 
 1926  
                 // If eviction cursor is exhausted, try to move
 1927  
                 // to the next key and reset
 1928  0
                 if ((_lifo && !_evictionCursor.hasPrevious()) ||
 1929  
                         (!_lifo && !_evictionCursor.hasNext())) {
 1930  0
                     if (_evictionKeyCursor != null) {
 1931  0
                         if (_evictionKeyCursor.hasNext()) {
 1932  0
                             key = _evictionKeyCursor.next();
 1933  0
                             resetEvictionObjectCursor(key);
 1934  
                         } else { // Need to reset Key cursor
 1935  0
                             resetEvictionKeyCursor();
 1936  0
                             if (_evictionKeyCursor != null) {
 1937  0
                                 if (_evictionKeyCursor.hasNext()) {
 1938  0
                                     key = _evictionKeyCursor.next();
 1939  0
                                     resetEvictionObjectCursor(key);
 1940  
                                 }
 1941  
                             }
 1942  
                         }
 1943  
                     }
 1944  
                 }
 1945  
 
 1946  0
                 if ((_lifo && !_evictionCursor.hasPrevious()) ||
 1947  
                         (!_lifo && !_evictionCursor.hasNext())) {
 1948  0
                     continue; // reset failed, do nothing
 1949  
                 }
 1950  
 
 1951  
                 // if LIFO and the _evictionCursor has a previous object,
 1952  
                 // or FIFO and _evictionCursor has a next object, test it
 1953  0
                 pair = _lifo ?
 1954  
                         (ObjectTimestampPair) _evictionCursor.previous() :
 1955  
                         (ObjectTimestampPair) _evictionCursor.next();
 1956  0
                 _evictionCursor.remove();
 1957  0
                 ObjectQueue objectQueue = (ObjectQueue) _poolMap.get(key);
 1958  0
                 objectQueue.incrementInternalProcessingCount();
 1959  0
                 _totalIdle--;
 1960  0
             }
 1961  
 
 1962  0
             boolean removeObject=false;
 1963  0
             if ((minEvictableIdleTimeMillis > 0) &&
 1964  
                (System.currentTimeMillis() - pair.tstamp >
 1965  
                minEvictableIdleTimeMillis)) {
 1966  0
                 removeObject=true;
 1967  
             }
 1968  0
             if (testWhileIdle && removeObject == false) {
 1969  0
                 boolean active = false;
 1970  
                 try {
 1971  0
                     _factory.activateObject(key,pair.value);
 1972  0
                     active = true;
 1973  0
                 } catch(Exception e) {
 1974  0
                     removeObject=true;
 1975  0
                 }
 1976  0
                 if (active) {
 1977  0
                     if (!_factory.validateObject(key,pair.value)) {
 1978  0
                         removeObject=true;
 1979  
                     } else {
 1980  
                         try {
 1981  0
                             _factory.passivateObject(key,pair.value);
 1982  0
                         } catch(Exception e) {
 1983  0
                             removeObject=true;
 1984  0
                         }
 1985  
                     }
 1986  
                 }
 1987  
             }
 1988  
 
 1989  0
             if (removeObject) {
 1990  
                 try {
 1991  0
                     _factory.destroyObject(key, pair.value);
 1992  0
                 } catch(Exception e) {
 1993  
                     // ignored
 1994  0
                 }
 1995  
             }
 1996  0
             synchronized (this) {
 1997  0
                 ObjectQueue objectQueue =
 1998  
                     (ObjectQueue)_poolMap.get(key);
 1999  0
                 objectQueue.decrementInternalProcessingCount();
 2000  0
                 if (removeObject) {
 2001  0
                     if (objectQueue.queue.isEmpty() &&
 2002  
                             objectQueue.activeCount == 0 &&
 2003  
                             objectQueue.internalProcessingCount == 0) {
 2004  0
                         _poolMap.remove(key);
 2005  0
                         _poolList.remove(key);
 2006  
                     }
 2007  
                 } else {
 2008  0
                     _evictionCursor.add(pair);
 2009  0
                     _totalIdle++;
 2010  0
                     if (_lifo) {
 2011  
                         // Skip over the element we just added back
 2012  0
                         _evictionCursor.previous();
 2013  
                     }
 2014  
                 }
 2015  0
             }
 2016  
         }
 2017  0
         allocate();
 2018  0
     }
 2019  
 
 2020  
     /**
 2021  
      * Resets the eviction key cursor and closes any
 2022  
      * associated eviction object cursor
 2023  
      */
 2024  
     private void resetEvictionKeyCursor() {
 2025  0
         if (_evictionKeyCursor != null) {
 2026  0
             _evictionKeyCursor.close();
 2027  
         }
 2028  0
         _evictionKeyCursor = _poolList.cursor();
 2029  0
         if (null != _evictionCursor) {
 2030  0
             _evictionCursor.close();
 2031  0
             _evictionCursor = null;
 2032  
         }
 2033  0
     }
 2034  
 
 2035  
     /**
 2036  
      * Resets the eviction object cursor for the given key
 2037  
      *
 2038  
      * @param key eviction key
 2039  
      */
 2040  
     private void resetEvictionObjectCursor(Object key) {
 2041  0
         if (_evictionCursor != null) {
 2042  0
             _evictionCursor.close();
 2043  
         }
 2044  0
         if (_poolMap == null) {
 2045  0
             return;
 2046  
         }
 2047  0
         ObjectQueue pool = (ObjectQueue) (_poolMap.get(key));
 2048  0
         if (pool != null) {
 2049  0
             CursorableLinkedList queue = pool.queue;
 2050  0
             _evictionCursor = queue.cursor(_lifo ? queue.size() : 0);
 2051  
         }
 2052  0
     }
 2053  
 
 2054  
     /**
 2055  
      * Iterates through all the known keys and creates any necessary objects to maintain
 2056  
      * the minimum level of pooled objects.
 2057  
      * @see #getMinIdle
 2058  
      * @see #setMinIdle
 2059  
      * @throws Exception If there was an error whilst creating the pooled objects.
 2060  
      */
 2061  
     private void ensureMinIdle() throws Exception {
 2062  
         //Check if should sustain the pool
 2063  0
         if (_minIdle > 0) {
 2064  
             Object[] keysCopy;
 2065  0
             synchronized(this) {
 2066  
                 // Get the current set of keys
 2067  0
                 keysCopy = _poolMap.keySet().toArray();
 2068  0
             }
 2069  
 
 2070  
             // Loop through all elements in _poolList
 2071  
             // Find out the total number of max active and max idle for that class
 2072  
             // If the number is less than the minIdle, do creation loop to boost numbers
 2073  0
             for (int i=0; i < keysCopy.length; i++) {
 2074  
                 //Get the next key to process
 2075  0
                 ensureMinIdle(keysCopy[i]);
 2076  
             }
 2077  
         }
 2078  0
     }
 2079  
 
 2080  
     /**
 2081  
      * Re-creates any needed objects to maintain the minimum levels of
 2082  
      * pooled objects for the specified key.
 2083  
      *
 2084  
      * This method uses {@link #calculateDeficit} to calculate the number
 2085  
      * of objects to be created. {@link #calculateDeficit} can be overridden to
 2086  
      * provide a different method of calculating the number of objects to be
 2087  
      * created.
 2088  
      * @param key The key to process
 2089  
      * @throws Exception If there was an error whilst creating the pooled objects
 2090  
      */
 2091  
     private void ensureMinIdle(Object key) throws Exception {
 2092  
         // Calculate current pool objects
 2093  
         ObjectQueue pool;
 2094  0
         synchronized(this) {
 2095  0
             pool = (ObjectQueue)(_poolMap.get(key));
 2096  0
         }
 2097  0
         if (pool == null) {
 2098  0
             return;
 2099  
         }
 2100  
 
 2101  
         // this method isn't synchronized so the
 2102  
         // calculateDeficit is done at the beginning
 2103  
         // as a loop limit and a second time inside the loop
 2104  
         // to stop when another thread already returned the
 2105  
         // needed objects
 2106  0
         int objectDeficit = calculateDeficit(pool, false);
 2107  
 
 2108  0
         for (int i = 0; i < objectDeficit && calculateDeficit(pool, true) > 0; i++) {
 2109  
             try {
 2110  0
                 addObject(key);
 2111  0
             } finally {
 2112  0
                 synchronized (this) {
 2113  0
                     pool.decrementInternalProcessingCount();
 2114  0
                 }
 2115  0
                 allocate();
 2116  0
             }
 2117  
         }
 2118  0
     }
 2119  
 
 2120  
     //--- non-public methods ----------------------------------------
 2121  
 
 2122  
     /**
 2123  
      * Start the eviction thread or service, or when
 2124  
      * <code>delay</code> is non-positive, stop it
 2125  
      * if it is already running.
 2126  
      *
 2127  
      * @param delay milliseconds between evictor runs.
 2128  
      */
 2129  
     protected synchronized void startEvictor(long delay) {
 2130  0
         if (null != _evictor) {
 2131  0
             EvictionTimer.cancel(_evictor);
 2132  0
             _evictor = null;
 2133  
         }
 2134  0
         if (delay > 0) {
 2135  0
             _evictor = new Evictor();
 2136  0
             EvictionTimer.schedule(_evictor, delay, delay);
 2137  
         }
 2138  0
     }
 2139  
 
 2140  
     /**
 2141  
      * Returns pool info including {@link #getNumActive()}, {@link #getNumIdle()}
 2142  
      * and currently defined keys.
 2143  
      * 
 2144  
      * @return string containing debug information
 2145  
      */
 2146  
     synchronized String debugInfo() {
 2147  0
         StringBuffer buf = new StringBuffer();
 2148  0
         buf.append("Active: ").append(getNumActive()).append("\n");
 2149  0
         buf.append("Idle: ").append(getNumIdle()).append("\n");
 2150  0
         Iterator it = _poolMap.keySet().iterator();
 2151  0
         while (it.hasNext()) {
 2152  0
             Object key = it.next();
 2153  0
             buf.append("\t").append(key).append(" ").append(_poolMap.get(key)).append("\n");
 2154  0
         }
 2155  0
         return buf.toString();
 2156  
     }
 2157  
 
 2158  
     /** 
 2159  
      * Returns the number of tests to be performed in an Evictor run,
 2160  
      * based on the current values of <code>_numTestsPerEvictionRun</code>
 2161  
      * and <code>_totalIdle</code>.
 2162  
      * 
 2163  
      * @see #setNumTestsPerEvictionRun
 2164  
      * @return the number of tests for the Evictor to run
 2165  
      */
 2166  
     private synchronized int getNumTests() {
 2167  0
         if (_numTestsPerEvictionRun >= 0) {
 2168  0
             return Math.min(_numTestsPerEvictionRun, _totalIdle);
 2169  
         } else {
 2170  0
             return(int)(Math.ceil(_totalIdle/Math.abs((double)_numTestsPerEvictionRun)));
 2171  
         }
 2172  
     }
 2173  
 
 2174  
     /**
 2175  
      * This returns the number of objects to create during the pool
 2176  
      * sustain cycle. This will ensure that the minimum number of idle
 2177  
      * instances is maintained without going past the maxActive value.
 2178  
      * 
 2179  
      * @param pool the ObjectPool to calculate the deficit for
 2180  
      * @param incrementInternal - Should the count of objects currently under
 2181  
      *                            some form of internal processing be
 2182  
      *                            incremented?
 2183  
      * @return The number of objects to be created
 2184  
      */
 2185  
     private synchronized int calculateDeficit(ObjectQueue pool,
 2186  
             boolean incrementInternal) {
 2187  0
         int objectDefecit = 0;
 2188  
 
 2189  
         //Calculate no of objects needed to be created, in order to have
 2190  
         //the number of pooled objects < maxActive();
 2191  0
         objectDefecit = getMinIdle() - pool.queue.size();
 2192  0
         if (getMaxActive() > 0) {
 2193  0
             int growLimit = Math.max(0, getMaxActive() - pool.activeCount - pool.queue.size() - pool.internalProcessingCount);
 2194  0
             objectDefecit = Math.min(objectDefecit, growLimit);
 2195  
         }
 2196  
 
 2197  
         // Take the maxTotal limit into account
 2198  0
         if (getMaxTotal() > 0) {
 2199  0
             int growLimit = Math.max(0, getMaxTotal() - getNumActive() - getNumIdle() - _totalInternalProcessing);
 2200  0
             objectDefecit = Math.min(objectDefecit, growLimit);
 2201  
         }
 2202  
 
 2203  0
         if (incrementInternal && objectDefecit > 0) {
 2204  0
             pool.incrementInternalProcessingCount();
 2205  
         }
 2206  0
         return objectDefecit;
 2207  
     }
 2208  
 
 2209  
     //--- inner classes ----------------------------------------------
 2210  
 
 2211  
     /**
 2212  
      * A "struct" that keeps additional information about the actual queue of pooled objects.
 2213  
      */
 2214  0
     private class ObjectQueue {
 2215  
         /** Number of instances checked out to clients from this queue */
 2216  0
         private int activeCount = 0;
 2217  
         
 2218  
         /** Idle instance queue */
 2219  0
         private final CursorableLinkedList queue = new CursorableLinkedList();
 2220  
         
 2221  
         /** Number of instances in process of being created */
 2222  0
         private int internalProcessingCount = 0;
 2223  
 
 2224  
         /** Increment the active count for this queue */
 2225  
         void incrementActiveCount() {
 2226  0
             synchronized (GenericKeyedObjectPool.this) {
 2227  0
                 _totalActive++;
 2228  0
             }
 2229  0
             activeCount++;
 2230  0
         }
 2231  
 
 2232  
         /** Decrement the active count for this queue */
 2233  
         void decrementActiveCount() {
 2234  0
             synchronized (GenericKeyedObjectPool.this) {
 2235  0
                 _totalActive--;
 2236  0
             }
 2237  0
             if (activeCount > 0) {
 2238  0
                 activeCount--;
 2239  
             }
 2240  0
         }
 2241  
 
 2242  
         /** Record the fact that one more instance is queued for creation */
 2243  
         void incrementInternalProcessingCount() {
 2244  0
             synchronized (GenericKeyedObjectPool.this) {
 2245  0
                 _totalInternalProcessing++;
 2246  0
             }
 2247  0
             internalProcessingCount++;
 2248  0
         }
 2249  
 
 2250  
         /** Decrement the number of instances in process of being created */
 2251  
         void decrementInternalProcessingCount() {
 2252  0
             synchronized (GenericKeyedObjectPool.this) {
 2253  0
                 _totalInternalProcessing--;
 2254  0
             }
 2255  0
             internalProcessingCount--;
 2256  0
         }
 2257  
     }
 2258  
 
 2259  
     /**
 2260  
      * A simple "struct" encapsulating an object instance and a timestamp.
 2261  
      *
 2262  
      * Implements Comparable, objects are sorted from old to new.
 2263  
      *
 2264  
      * This is also used by {@link GenericObjectPool}.
 2265  
      */
 2266  
     static class ObjectTimestampPair implements Comparable {
 2267  
         //CHECKSTYLE: stop VisibilityModifier
 2268  
         /** 
 2269  
          * Object instance 
 2270  
          * @deprecated this field will be made private and final in version 2.0
 2271  
          */
 2272  
         Object value;
 2273  
         
 2274  
         /**
 2275  
          * timestamp
 2276  
          * @deprecated this field will be made private and final in version 2.0
 2277  
          */
 2278  
         long tstamp;
 2279  
         //CHECKSTYLE: resume VisibilityModifier
 2280  
 
 2281  
         /**
 2282  
          * Create a new ObjectTimestampPair using the given object and the current system time.
 2283  
          * @param val object instance
 2284  
          */
 2285  
         ObjectTimestampPair(Object val) {
 2286  0
             this(val, System.currentTimeMillis());
 2287  0
         }
 2288  
 
 2289  
         /**
 2290  
          * Create a new ObjectTimeStampPair using the given object and timestamp value.
 2291  
          * @param val object instance
 2292  
          * @param time long representation of timestamp
 2293  
          */
 2294  0
         ObjectTimestampPair(Object val, long time) {
 2295  0
             value = val;
 2296  0
             tstamp = time;
 2297  0
         }
 2298  
 
 2299  
         /**
 2300  
          * Returns a string representation.
 2301  
          * 
 2302  
          * @return String representing this ObjectTimestampPair
 2303  
          */
 2304  
         public String toString() {
 2305  0
             return value + ";" + tstamp;
 2306  
         }
 2307  
 
 2308  
         /**
 2309  
          * Compares this to another object by casting the argument to an
 2310  
          * ObjectTimestampPair.
 2311  
          * 
 2312  
          * @param obj object to cmpare
 2313  
          * @return result of comparison
 2314  
          */
 2315  
         public int compareTo(Object obj) {
 2316  0
             return compareTo((ObjectTimestampPair) obj);
 2317  
         }
 2318  
 
 2319  
         /**
 2320  
          * Compares this to another ObjectTimestampPair, using the timestamp as basis for comparison.
 2321  
          * Implementation is consistent with equals.
 2322  
          * 
 2323  
          * @param other object to compare
 2324  
          * @return result of comparison
 2325  
          */
 2326  
         public int compareTo(ObjectTimestampPair other) {
 2327  0
             final long tstampdiff = this.tstamp - other.tstamp;
 2328  0
             if (tstampdiff == 0) {
 2329  
                 // make sure the natural ordering is consistent with equals
 2330  
                 // see java.lang.Comparable Javadocs
 2331  0
                 return System.identityHashCode(this) - System.identityHashCode(other);
 2332  
             } else {
 2333  
                 // handle int overflow
 2334  0
                 return (int)Math.min(Math.max(tstampdiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
 2335  
             }
 2336  
         }
 2337  
 
 2338  
         /**
 2339  
          * @return the value
 2340  
          */
 2341  
         public Object getValue() {
 2342  0
             return value;
 2343  
         }
 2344  
 
 2345  
         /**
 2346  
          * @return the tstamp
 2347  
          */
 2348  
         public long getTstamp() {
 2349  0
             return tstamp;
 2350  
         }
 2351  
     }
 2352  
 
 2353  
     /**
 2354  
      * The idle object evictor {@link TimerTask}.
 2355  
      * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
 2356  
      */
 2357  0
     private class Evictor extends TimerTask {
 2358  
         /**
 2359  
          * Run pool maintenance.  Evict objects qualifying for eviction and then
 2360  
          * invoke {@link GenericKeyedObjectPool#ensureMinIdle()}.
 2361  
          */
 2362  
         public void run() {
 2363  
             //Evict from the pool
 2364  
             try {
 2365  0
                 evict();
 2366  0
             } catch(Exception e) {
 2367  
                 // ignored
 2368  0
             } catch(OutOfMemoryError oome) {
 2369  
                 // Log problem but give evictor thread a chance to continue in
 2370  
                 // case error is recoverable
 2371  0
                 oome.printStackTrace(System.err);
 2372  0
             }
 2373  
             //Re-create idle instances.
 2374  
             try {
 2375  0
                 ensureMinIdle();
 2376  0
             } catch (Exception e) {
 2377  
                 // ignored
 2378  0
             }
 2379  0
         }
 2380  
     }
 2381  
 
 2382  
     /**
 2383  
      * A simple "struct" encapsulating the
 2384  
      * configuration information for a <code>GenericKeyedObjectPool</code>.
 2385  
      * @see GenericKeyedObjectPool#GenericKeyedObjectPool(KeyedPoolableObjectFactory,GenericKeyedObjectPool.Config)
 2386  
      * @see GenericKeyedObjectPool#setConfig
 2387  
      */
 2388  0
     public static class Config {
 2389  
         //CHECKSTYLE: stop VisibilityModifier
 2390  
         /**
 2391  
          * @see GenericKeyedObjectPool#setMaxIdle
 2392  
          */
 2393  0
         public int maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
 2394  
         /**
 2395  
          * @see GenericKeyedObjectPool#setMaxActive
 2396  
          */
 2397  0
         public int maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
 2398  
         /**
 2399  
          * @see GenericKeyedObjectPool#setMaxTotal
 2400  
          */
 2401  0
         public int maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
 2402  
         /**
 2403  
          * @see GenericKeyedObjectPool#setMinIdle
 2404  
          */
 2405  0
         public int minIdle = GenericKeyedObjectPool.DEFAULT_MIN_IDLE;
 2406  
         /**
 2407  
          * @see GenericKeyedObjectPool#setMaxWait
 2408  
          */
 2409  0
         public long maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
 2410  
         /**
 2411  
          * @see GenericKeyedObjectPool#setWhenExhaustedAction
 2412  
          */
 2413  0
         public byte whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
 2414  
         /**
 2415  
          * @see GenericKeyedObjectPool#setTestOnBorrow
 2416  
          */
 2417  0
         public boolean testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
 2418  
         /**
 2419  
          * @see GenericKeyedObjectPool#setTestOnReturn
 2420  
          */
 2421  0
         public boolean testOnReturn = GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN;
 2422  
         /**
 2423  
          * @see GenericKeyedObjectPool#setTestWhileIdle
 2424  
          */
 2425  0
         public boolean testWhileIdle = GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE;
 2426  
         /**
 2427  
          * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
 2428  
          */
 2429  0
         public long timeBetweenEvictionRunsMillis = GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
 2430  
         /**
 2431  
          * @see GenericKeyedObjectPool#setNumTestsPerEvictionRun
 2432  
          */
 2433  0
         public int numTestsPerEvictionRun =  GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
 2434  
         /**
 2435  
          * @see GenericKeyedObjectPool#setMinEvictableIdleTimeMillis
 2436  
          */
 2437  0
         public long minEvictableIdleTimeMillis = GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
 2438  
         /**
 2439  
          * @see GenericKeyedObjectPool#setLifo
 2440  
          */
 2441  0
         public boolean lifo = GenericKeyedObjectPool.DEFAULT_LIFO;
 2442  
         //CHECKSTYLE: resume VisibilityModifier
 2443  
     }
 2444  
 
 2445  
     /**
 2446  
      * Latch used to control allocation order of objects to threads to ensure
 2447  
      * fairness. That is, for each key, objects are allocated to threads in the order
 2448  
      * that threads request objects.
 2449  
      * 
 2450  
      * @since 1.5
 2451  
      */
 2452  0
     private static final class Latch {
 2453  
         
 2454  
         /** key of associated pool */
 2455  
         private final Object _key;
 2456  
         
 2457  
         /** keyed pool associated with this latch */
 2458  
         private ObjectQueue _pool;
 2459  
         
 2460  
         /** holds an ObjectTimestampPair when this latch has been allocated an instance */
 2461  
         private ObjectTimestampPair _pair;
 2462  
         
 2463  
         /** indicates that this latch can create an instance */
 2464  0
         private boolean _mayCreate = false;
 2465  
 
 2466  
         /**
 2467  
          * Create a latch with the given key
 2468  
          * @param key key of the pool associated with this latch
 2469  
          */
 2470  0
         private Latch(Object key) {
 2471  0
             _key = key;
 2472  0
         }
 2473  
 
 2474  
         /**
 2475  
          * Retuns the key of the associated pool
 2476  
          * @return associated pool key
 2477  
          */
 2478  
         private synchronized Object getkey() {
 2479  0
             return _key;
 2480  
         }
 2481  
 
 2482  
         /**
 2483  
          * Returns the pool associated with this latch
 2484  
          * @return pool
 2485  
          */
 2486  
         private synchronized ObjectQueue getPool() {
 2487  0
             return _pool;
 2488  
         }
 2489  
         
 2490  
         /**
 2491  
          * Sets the pool associated with this latch
 2492  
          * @param pool the pool
 2493  
          */
 2494  
         private synchronized void setPool(ObjectQueue pool) {
 2495  0
             _pool = pool;
 2496  0
         }
 2497  
 
 2498  
         /**
 2499  
          * Gets the ObjectTimestampPair allocated to this latch.
 2500  
          * Returns null if this latch does not have an instance allocated to it. 
 2501  
          * @return the associated ObjectTimestampPair
 2502  
          */
 2503  
         private synchronized ObjectTimestampPair getPair() {
 2504  0
             return _pair;
 2505  
         }
 2506  
         
 2507  
         /**
 2508  
          * Allocate an ObjectTimestampPair to this latch.
 2509  
          * @param pair ObjectTimestampPair on this latch
 2510  
          */
 2511  
         private synchronized void setPair(ObjectTimestampPair pair) {
 2512  0
             _pair = pair;
 2513  0
         }
 2514  
 
 2515  
         /**
 2516  
          * Whether or not this latch can create an instance
 2517  
          * @return true if this latch has an instance creation permit
 2518  
          */
 2519  
         private synchronized boolean mayCreate() {
 2520  0
             return _mayCreate;
 2521  
         }
 2522  
         
 2523  
         /**
 2524  
          * Sets the mayCreate property
 2525  
          * 
 2526  
          * @param mayCreate true means this latch can create an instance
 2527  
          */
 2528  
         private synchronized void setMayCreate(boolean mayCreate) {
 2529  0
             _mayCreate = mayCreate;
 2530  0
         }
 2531  
 
 2532  
         /**
 2533  
          * Reset the latch data. Used when an allocation fails and the latch
 2534  
          * needs to be re-added to the queue.
 2535  
          */
 2536  
         private synchronized void reset() {
 2537  0
             _pair = null;
 2538  0
             _mayCreate = false;
 2539  0
         }
 2540  
     }
 2541  
 
 2542  
     //--- protected attributes ---------------------------------------
 2543  
 
 2544  
     /**
 2545  
      * The cap on the number of idle instances in the pool.
 2546  
      * @see #setMaxIdle
 2547  
      * @see #getMaxIdle
 2548  
      */
 2549  0
     private int _maxIdle = DEFAULT_MAX_IDLE;
 2550  
 
 2551  
     /**
 2552  
      * The minimum no of idle objects to keep in the pool.
 2553  
      * @see #setMinIdle
 2554  
      * @see #getMinIdle
 2555  
      */
 2556  0
     private volatile int _minIdle = DEFAULT_MIN_IDLE;
 2557  
 
 2558  
     /**
 2559  
      * The cap on the number of active instances from the pool.
 2560  
      * @see #setMaxActive
 2561  
      * @see #getMaxActive
 2562  
      */
 2563  0
     private int _maxActive = DEFAULT_MAX_ACTIVE;
 2564  
 
 2565  
     /**
 2566  
      * The cap on the total number of instances from the pool if non-positive.
 2567  
      * @see #setMaxTotal
 2568  
      * @see #getMaxTotal
 2569  
      */
 2570  0
     private int _maxTotal = DEFAULT_MAX_TOTAL;
 2571  
 
 2572  
     /**
 2573  
      * The maximum amount of time (in millis) the
 2574  
      * {@link #borrowObject} method should block before throwing
 2575  
      * an exception when the pool is exhausted and the
 2576  
      * {@link #getWhenExhaustedAction "when exhausted" action} is
 2577  
      * {@link #WHEN_EXHAUSTED_BLOCK}.
 2578  
      *
 2579  
      * When less than or equal to 0, the {@link #borrowObject} method
 2580  
      * may block indefinitely.
 2581  
      *
 2582  
      * @see #setMaxWait
 2583  
      * @see #getMaxWait
 2584  
      * @see #WHEN_EXHAUSTED_BLOCK
 2585  
      * @see #setWhenExhaustedAction
 2586  
      * @see #getWhenExhaustedAction
 2587  
      */
 2588  0
     private long _maxWait = DEFAULT_MAX_WAIT;
 2589  
 
 2590  
     /**
 2591  
      * The action to take when the {@link #borrowObject} method
 2592  
      * is invoked when the pool is exhausted (the maximum number
 2593  
      * of "active" objects has been reached).
 2594  
      *
 2595  
      * @see #WHEN_EXHAUSTED_BLOCK
 2596  
      * @see #WHEN_EXHAUSTED_FAIL
 2597  
      * @see #WHEN_EXHAUSTED_GROW
 2598  
      * @see #DEFAULT_WHEN_EXHAUSTED_ACTION
 2599  
      * @see #setWhenExhaustedAction
 2600  
      * @see #getWhenExhaustedAction
 2601  
      */
 2602  0
     private byte _whenExhaustedAction = DEFAULT_WHEN_EXHAUSTED_ACTION;
 2603  
 
 2604  
     /**
 2605  
      * When <code>true</code>, objects will be
 2606  
      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
 2607  
      * before being returned by the {@link #borrowObject}
 2608  
      * method.  If the object fails to validate,
 2609  
      * it will be dropped from the pool, and we will attempt
 2610  
      * to borrow another.
 2611  
      *
 2612  
      * @see #setTestOnBorrow
 2613  
      * @see #getTestOnBorrow
 2614  
      */
 2615  0
     private volatile boolean _testOnBorrow = DEFAULT_TEST_ON_BORROW;
 2616  
 
 2617  
     /**
 2618  
      * When <code>true</code>, objects will be
 2619  
      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
 2620  
      * before being returned to the pool within the
 2621  
      * {@link #returnObject}.
 2622  
      *
 2623  
      * @see #getTestOnReturn
 2624  
      * @see #setTestOnReturn
 2625  
      */
 2626  0
     private volatile boolean _testOnReturn = DEFAULT_TEST_ON_RETURN;
 2627  
 
 2628  
     /**
 2629  
      * When <code>true</code>, objects will be
 2630  
      * {@link org.apache.commons.pool.PoolableObjectFactory#validateObject validated}
 2631  
      * by the idle object evictor (if any).  If an object
 2632  
      * fails to validate, it will be dropped from the pool.
 2633  
      *
 2634  
      * @see #setTestWhileIdle
 2635  
      * @see #getTestWhileIdle
 2636  
      * @see #getTimeBetweenEvictionRunsMillis
 2637  
      * @see #setTimeBetweenEvictionRunsMillis
 2638  
      */
 2639  0
     private boolean _testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
 2640  
 
 2641  
     /**
 2642  
      * The number of milliseconds to sleep between runs of the
 2643  
      * idle object evictor thread.
 2644  
      * When non-positive, no idle object evictor thread will be
 2645  
      * run.
 2646  
      *
 2647  
      * @see #setTimeBetweenEvictionRunsMillis
 2648  
      * @see #getTimeBetweenEvictionRunsMillis
 2649  
      */
 2650  0
     private long _timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
 2651  
 
 2652  
     /**
 2653  
      * The number of objects to examine during each run of the
 2654  
      * idle object evictor thread (if any).
 2655  
      * <p>
 2656  
      * When a negative value is supplied, <code>ceil({@link #getNumIdle})/abs({@link #getNumTestsPerEvictionRun})</code>
 2657  
      * tests will be run.  I.e., when the value is <code>-n</code>, roughly one <code>n</code>th of the
 2658  
      * idle objects will be tested per run.
 2659  
      *
 2660  
      * @see #setNumTestsPerEvictionRun
 2661  
      * @see #getNumTestsPerEvictionRun
 2662  
      * @see #getTimeBetweenEvictionRunsMillis
 2663  
      * @see #setTimeBetweenEvictionRunsMillis
 2664  
      */
 2665  0
     private int _numTestsPerEvictionRun =  DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
 2666  
 
 2667  
     /**
 2668  
      * The minimum amount of time an object may sit idle in the pool
 2669  
      * before it is eligible for eviction by the idle object evictor
 2670  
      * (if any).
 2671  
      * When non-positive, no objects will be evicted from the pool
 2672  
      * due to idle time alone.
 2673  
      *
 2674  
      * @see #setMinEvictableIdleTimeMillis
 2675  
      * @see #getMinEvictableIdleTimeMillis
 2676  
      * @see #getTimeBetweenEvictionRunsMillis
 2677  
      * @see #setTimeBetweenEvictionRunsMillis
 2678  
      */
 2679  0
     private long _minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
 2680  
 
 2681  
     /** My hash of pools (ObjectQueue). */
 2682  0
     private Map _poolMap = null;
 2683  
 
 2684  
     /** The total number of active instances. */
 2685  0
     private int _totalActive = 0;
 2686  
 
 2687  
     /** The total number of idle instances. */
 2688  0
     private int _totalIdle = 0;
 2689  
 
 2690  
     /**
 2691  
      * The number of objects subject to some form of internal processing
 2692  
      * (usually creation or destruction) that should be included in the total
 2693  
      * number of objects but are neither active nor idle.
 2694  
      */
 2695  0
     private int _totalInternalProcessing = 0;
 2696  
 
 2697  
     /** My {@link KeyedPoolableObjectFactory}. */
 2698  0
     private KeyedPoolableObjectFactory _factory = null;
 2699  
 
 2700  
     /**
 2701  
      * My idle object eviction {@link TimerTask}, if any.
 2702  
      */
 2703  0
     private Evictor _evictor = null;
 2704  
 
 2705  
     /**
 2706  
      * A cursorable list of my pools.
 2707  
      * @see GenericKeyedObjectPool.Evictor#run
 2708  
      */
 2709  0
     private CursorableLinkedList _poolList = null;
 2710  
 
 2711  
     /** Eviction cursor (over instances within-key) */
 2712  0
     private CursorableLinkedList.Cursor _evictionCursor = null;
 2713  
     
 2714  
     /** Eviction cursor (over keys) */
 2715  0
     private CursorableLinkedList.Cursor _evictionKeyCursor = null;
 2716  
 
 2717  
     /** Whether or not the pools behave as LIFO queues (last in first out) */
 2718  0
     private boolean _lifo = DEFAULT_LIFO;
 2719  
 
 2720  
     /**
 2721  
      * Used to track the order in which threads call {@link #borrowObject()} so
 2722  
      * that objects can be allocated in the order in which the threads requested
 2723  
      * them.
 2724  
      */
 2725  0
     private LinkedList _allocationQueue = new LinkedList();
 2726  
 
 2727  
 }