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