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