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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #setMaxActive})
+ * @param whenExhaustedAction the action to take when the pool is exhausted
(see [EMAIL PROTECTED] #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 [EMAIL PROTECTED]
#WHEN_EXHAUSTED_BLOCK} (otherwise ignored) (see [EMAIL PROTECTED] #setMaxWait})
+ * @param maxIdle the maximum number of idle objects in my pool (see [EMAIL
PROTECTED] #setMaxIdle})
+ * @param maxTotal the maximum number of objects that can exists at one time
(see [EMAIL PROTECTED] #setMaxTotal})
+ * @param testOnBorrow whether or not to validate objects before they are
returned by the [EMAIL PROTECTED] #borrowObject} method (see [EMAIL PROTECTED]
#setTestOnBorrow})
+ * @param testOnReturn whether or not to validate objects after they are
returned to the [EMAIL PROTECTED] #returnObject} method (see [EMAIL PROTECTED]
#setTestOnReturn})
+ * @param timeBetweenEvictionRunsMillis the amount of time (in milliseconds) to
sleep between examining idle objects for eviction (see [EMAIL PROTECTED]
#setTimeBetweenEvictionRunsMillis})
+ * @param numTestsPerEvictionRun the number of idle objects to examine per run
within the idle object eviction thread (if any) (see [EMAIL PROTECTED]
#setNumTestsPerEvictionRun})
+ * @param minEvictableIdleTimeMillis the minimum number of milliseconds an
object can sit idle in the pool before it is eligable for evcition (see [EMAIL
PROTECTED] #setMinEvictableIdleTimeMillis})
+ * @param testWhileIdle whether or not to validate objects in the idle object
eviction thread, if any (see [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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
* [EMAIL PROTECTED] #borrowObject} method should block before throwing
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]