You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by di...@apache.org on 2003/08/26 16:14:16 UTC

cvs commit: jakarta-commons/pool/src/java/org/apache/commons/pool/impl GenericKeyedObjectPoolFactory.java GenericKeyedObjectPool.java

dirkv       2003/08/26 07:14:16

  Modified:    pool/src/java/org/apache/commons/pool/impl
                        GenericKeyedObjectPoolFactory.java
                        GenericKeyedObjectPool.java
  Log:
  implemented maxTotal feature: ( _totalActive + _totalIdle <= _maxTotal)
  - when limit reached the idle objects are cleared to make room for objects with different key
  - existing behaviour/limits remain: maxActive, maxIdle, maxWait, WhenExhaustedAction
  
  Revision  Changes    Path
  1.4       +21 -10    jakarta-commons/pool/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPoolFactory.java
  
  Index: GenericKeyedObjectPoolFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/pool/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPoolFactory.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- GenericKeyedObjectPoolFactory.java	22 Aug 2003 14:33:30 -0000	1.3
  +++ GenericKeyedObjectPoolFactory.java	26 Aug 2003 14:14:15 -0000	1.4
  @@ -72,6 +72,7 @@
    * @see KeyedObjectPoolFactory
    *
    * @author Rodney Waldhoff
  + * @author Dirk Verbeeck
    * @version $Id$
    */
   public class GenericKeyedObjectPoolFactory implements KeyedObjectPoolFactory {
  @@ -84,28 +85,37 @@
       }
   
       public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive) {
  -        this(factory,maxActive,GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,GenericKeyedObjectPool.DEFAULT_MAX_WAIT,GenericKeyedObjectPool.DEFAULT_MAX_IDLE,GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
  +        this(factory,maxActive,GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,GenericKeyedObjectPool.DEFAULT_MAX_WAIT,GenericKeyedObjectPool.DEFAULT_MAX_IDLE, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
       }
   
       public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait) {
  -        this(factory,maxActive,whenExhaustedAction,maxWait,GenericKeyedObjectPool.DEFAULT_MAX_IDLE,GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
  +        this(factory,maxActive,whenExhaustedAction,maxWait,GenericKeyedObjectPool.DEFAULT_MAX_IDLE, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
       }
   
       public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn) {
  -        this(factory,maxActive,whenExhaustedAction,maxWait,GenericKeyedObjectPool.DEFAULT_MAX_IDLE,testOnBorrow,testOnReturn,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
  +        this(factory,maxActive,whenExhaustedAction,maxWait,GenericKeyedObjectPool.DEFAULT_MAX_IDLE, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,testOnBorrow,testOnReturn,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
       }
   
       public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle) {
  -        this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
  +        this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
  +    }
  +
  +    public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal) {
  +        this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle, maxTotal, GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
       }
   
       public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn) {
  -        this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle,testOnBorrow,testOnReturn,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
  +        this(factory,maxActive,whenExhaustedAction,maxWait,maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL,testOnBorrow,testOnReturn,GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE);
       }
   
       public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
  +        this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
  +    }
  +
  +    public GenericKeyedObjectPoolFactory(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
           _maxIdle = maxIdle;
           _maxActive = maxActive;
  +        _maxTotal = maxTotal;
           _maxWait = maxWait;
           _whenExhaustedAction = whenExhaustedAction;
           _testOnBorrow = testOnBorrow;
  @@ -118,13 +128,14 @@
       }
   
       public KeyedObjectPool createPool() {
  -        return new GenericKeyedObjectPool(_factory,_maxActive,_whenExhaustedAction,_maxWait,_maxIdle,_testOnBorrow,_testOnReturn,_timeBetweenEvictionRunsMillis,_numTestsPerEvictionRun,_minEvictableIdleTimeMillis,_testWhileIdle);
  +        return new GenericKeyedObjectPool(_factory,_maxActive,_whenExhaustedAction,_maxWait,_maxIdle,_maxTotal,_testOnBorrow,_testOnReturn,_timeBetweenEvictionRunsMillis,_numTestsPerEvictionRun,_minEvictableIdleTimeMillis,_testWhileIdle);
       }
   
       //--- protected attributes ---------------------------------------
   
       protected int _maxIdle = GenericKeyedObjectPool.DEFAULT_MAX_IDLE;
       protected int _maxActive = GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE;
  +    protected int _maxTotal = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL;
       protected long _maxWait = GenericKeyedObjectPool.DEFAULT_MAX_WAIT;
       protected byte _whenExhaustedAction = GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
       protected boolean _testOnBorrow = GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW;
  
  
  
  1.20      +75 -10    jakarta-commons/pool/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
  
  Index: GenericKeyedObjectPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/pool/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- GenericKeyedObjectPool.java	22 Aug 2003 14:33:30 -0000	1.19
  +++ GenericKeyedObjectPool.java	26 Aug 2003 14:14:15 -0000	1.20
  @@ -164,6 +164,7 @@
    * </p>
    * @see GenericObjectPool
    * @author Rodney Waldhoff
  + * @author Dirk Verbeeck
    * @version $Revision$ $Date$
    */
   public class GenericKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
  @@ -223,6 +224,13 @@
       public static final int DEFAULT_MAX_ACTIVE  = 8;
   
       /**
  +     * The default cap on the the maximum number of objects that can exists at one time.
  +     * @see #getMaxTotal
  +     * @see #setMaxTotal
  +     */
  +    public static final int DEFAULT_MAX_TOTAL  = -1;
  +
  +    /**
        * The default "when exhausted action" for the pool.
        * @see #WHEN_EXHAUSTED_BLOCK
        * @see #WHEN_EXHAUSTED_FAIL
  @@ -389,6 +397,25 @@
        * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
        */
       public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
  +        this(factory, maxActive, whenExhaustedAction, maxWait, maxIdle, GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, testOnBorrow, testOnReturn, timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, minEvictableIdleTimeMillis, testWhileIdle);
  +    }
  +
  +    /**
  +     * Create a new <tt>GenericKeyedObjectPool</tt> using the specified values.
  +     * @param factory the (possibly <tt>null</tt>)PoolableObjectFactory to use to create, validate and destroy objects
  +     * @param maxActive the maximum number of objects that can be borrowed from me at one time (per key) (see {@link #setMaxActive})
  +     * @param whenExhaustedAction the action to take when the pool is exhausted (see {@link #setWhenExhaustedAction})
  +     * @param maxWait the maximum amount of time to wait for an idle object when the pool is exhausted an and <i>whenExhaustedAction</i> is {@link #WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see {@link #setMaxWait})
  +     * @param maxIdle the maximum number of idle objects in my pool (see {@link #setMaxIdle})
  +     * @param maxTotal the maximum number of objects that can exists at one time (see {@link #setMaxTotal})
  +     * @param testOnBorrow whether or not to validate objects before they are returned by the {@link #borrowObject} method (see {@link #setTestOnBorrow})
  +     * @param testOnReturn whether or not to validate objects after they are returned to the {@link #returnObject} method (see {@link #setTestOnReturn})
  +     * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to sleep between examining idle objects for eviction (see {@link #setTimeBetweenEvictionRunsMillis})
  +     * @param numTestsPerEvictionRun the number of idle objects to examine per run within the idle object eviction thread (if any) (see {@link #setNumTestsPerEvictionRun})
  +     * @param minEvictableIdleTimeMillis the minimum number of milliseconds an object can sit idle in the pool before it is eligable for evcition (see {@link #setMinEvictableIdleTimeMillis})
  +     * @param testWhileIdle whether or not to validate objects in the idle object eviction thread, if any (see {@link #setTestWhileIdle})
  +     */
  +    public GenericKeyedObjectPool(KeyedPoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, int maxTotal, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle) {
           _factory = factory;
           _maxActive = maxActive;
           switch(whenExhaustedAction) {
  @@ -402,6 +429,7 @@
           }
           _maxWait = maxWait;
           _maxIdle = maxIdle;
  +        _maxTotal = maxTotal;
           _testOnBorrow = testOnBorrow;
           _testOnReturn = testOnReturn;
           _timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
  @@ -426,8 +454,8 @@
       //--- configuration methods --------------------------------------
   
       /**
  -     * Returns the cap on the total number of active instances from my pool.
  -     * @return the cap on the total number of active instances from my pool.
  +     * Returns the cap on the number of active instances from my pool (per key).
  +     * @return the cap on the number of active instances from my pool (per key).
        * @see #setMaxActive
        */
       public int getMaxActive() {
  @@ -435,8 +463,8 @@
       }
   
       /**
  -     * Sets the cap on the total number of active instances from my pool.
  -     * @param maxActive The cap on the total number of active instances from my pool.
  +     * Sets the cap on the number of active instances from my pool (per key).
  +     * @param maxActive The cap on the number of active instances from my pool (per key).
        *                  Use a negative value for an infinite number of instances.
        * @see #getMaxActive
        */
  @@ -448,6 +476,28 @@
       }
   
       /**
  +     * Returns the cap on the total number of instances from my pool.
  +     * @return the cap on the total number of instances from my pool.
  +     * @see #setMaxTotal
  +     */
  +    public int getMaxTotal() {
  +        return _maxTotal;
  +    }
  +
  +    /**
  +     * Sets the cap on the total number of instances from my pool.
  +     * @param maxTotal The cap on the total number of instances from my pool.
  +     *                  Use a negative value for an infinite number of instances.
  +     * @see #getMaxTotal
  +     */
  +    public void setMaxTotal(int maxTotal) {
  +        _maxTotal = maxTotal;
  +        synchronized(this) {
  +            notifyAll();
  +        }
  +    }
  +
  +    /**
        * Returns the action to take when the {@link #borrowObject} method
        * is invoked when the pool is exhausted (the maximum number
        * of "active" objects has been reached).
  @@ -748,10 +798,18 @@
               }
               // otherwise
               if(null == pair) {
  +                // if there is a totalMaxActive and we are at the limit then
  +                // we have to make room
  +                // TODO: this could be improved by only removing the oldest object
  +                if ((_maxTotal > 0) && (_totalActive + _totalIdle >= _maxTotal)) {
  +                    clear();
  +                }
  +                
                   // check if we can create one
                   // (note we know that the num sleeping is 0, else we wouldn't be here)
                   int active = getActiveCount(key);
  -                if(_maxActive <= 0 || active < _maxActive) {
  +                if ((_maxActive <= 0 || active < _maxActive) &&
  +                    (_maxTotal <= 0 || _totalActive + _totalIdle < _maxTotal)) {
                       Object obj = _factory.makeObject(key);
                       pair = new ObjectTimestampPair(obj);
                       newlyCreated = true;
  @@ -1179,12 +1237,19 @@
       private int _maxIdle = DEFAULT_MAX_IDLE;
   
       /**
  -     * The cap on the total number of active instances from the pool (per key).
  +     * The cap on the number of active instances from the pool (per key).
        * @see #setMaxActive
        * @see #getMaxActive
        */
       private int _maxActive = DEFAULT_MAX_ACTIVE;
   
  +    /**
  +     * The cap on the total number of instances from the pool.
  +     * @see #setMaxTotal
  +     * @see #getMaxTotal
  +     */
  +    private int _maxTotal = DEFAULT_MAX_TOTAL;
  +    
       /**
        * The maximum amount of time (in millis) the
        * {@link #borrowObject} method should block before throwing