You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ps...@apache.org on 2010/06/21 19:54:03 UTC

svn commit: r956656 - /commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java

Author: psteitz
Date: Mon Jun 21 17:54:03 2010
New Revision: 956656

URL: http://svn.apache.org/viewvc?rev=956656&view=rev
Log:
Javadoc.

Modified:
    commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java

Modified: commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java?rev=956656&r1=956655&r2=956656&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java (original)
+++ commons/proper/pool/trunk/src/java/org/apache/commons/pool/PoolUtils.java Mon Jun 21 17:54:03 2010
@@ -1399,11 +1399,30 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * Timer task that adds objects to the pool until the number of idle
+     * instances for the given key reaches the configured minIdle.  Note that this is not the
+     * same as the pool's minIdle setting.
+     * 
+     */
     private static class KeyedObjectPoolMinIdleTimerTask extends TimerTask {
+        /** Minimum number of idle instances.  Not the same as pool.getMinIdle(). */
         private final int minIdle;
+        
+        /** Key to ensure minIdle for */
         private final Object key;
+        
+        /** Keyed object pool */
         private final KeyedObjectPool keyedPool;
 
+        /**
+         * Create a new KeyedObjecPoolMinIdleTimerTask.
+         * 
+         * @param keyedPool keyed object pool
+         * @param key key to ensure minimum number of idle instances
+         * @param minIdle minimum number of idle instances 
+         * @throws IllegalArgumentException if the key is null
+         */
         KeyedObjectPoolMinIdleTimerTask(final KeyedObjectPool keyedPool, final Object key, final int minIdle) throws IllegalArgumentException {
             if (keyedPool == null) {
                 throw new IllegalArgumentException("keyedPool must not be null.");
@@ -1413,6 +1432,9 @@ public final class PoolUtils {
             this.minIdle = minIdle;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void run() {
             boolean success = false;
             try {
@@ -1432,6 +1454,9 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             final StringBuffer sb = new StringBuffer();
             sb.append("KeyedObjectPoolMinIdleTimerTask");
@@ -1443,10 +1468,30 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * A synchronized (thread-safe) ObjectPool backed by the specified ObjectPool.
+     *
+     * <p><b>Note:</b>
+     * This should not be used on pool implementations that already provide proper synchronization
+     * such as the pools provided in the Commons Pool library. Wrapping a pool that
+     * {@link #wait() waits} for poolable objects to be returned before allowing another one to be
+     * borrowed with another layer of synchronization will cause liveliness issues or a deadlock.
+     * </p>
+     */
     private static class SynchronizedObjectPool implements ObjectPool {
+        
+        /** Object whose monitor is used to synchronize methods on the wrapped pool. */
         private final Object lock;
+        
+        /** the underlying object pool */
         private final ObjectPool pool;
 
+        /**
+         * Create a new SynchronizedObjectPool wrapping the given pool.
+         * 
+         * @param pool the ObjectPool to be "wrapped" in a synchronized ObjectPool.
+         * @throws IllegalArgumentException if the pool is null
+         */
         SynchronizedObjectPool(final ObjectPool pool) throws IllegalArgumentException {
             if (pool == null) {
                 throw new IllegalArgumentException("pool must not be null.");
@@ -1455,12 +1500,18 @@ public final class PoolUtils {
             lock = new Object();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
             synchronized (lock) {
                 return pool.borrowObject();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void returnObject(final Object obj) {
             synchronized (lock) {
                 try {
@@ -1471,6 +1522,9 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void invalidateObject(final Object obj) {
             synchronized (lock) {
                 try {
@@ -1481,30 +1535,45 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
             synchronized (lock) {
                 pool.addObject();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumIdle() throws UnsupportedOperationException {
             synchronized (lock) {
                 return pool.getNumIdle();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumActive() throws UnsupportedOperationException {
             synchronized (lock) {
                 return pool.getNumActive();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void clear() throws Exception, UnsupportedOperationException {
             synchronized (lock) {
                 pool.clear();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void close() {
             try {
                 synchronized (lock) {
@@ -1515,12 +1584,21 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * Sets the factory used by the pool.
+         * 
+         * @param factory new PoolableObjectFactory
+         * @deprecated to be removed in pool 2.0
+         */
         public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
             synchronized (lock) {
                 pool.setFactory(factory);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             final StringBuffer sb = new StringBuffer();
             sb.append("SynchronizedObjectPool");
@@ -1530,10 +1608,30 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * A synchronized (thread-safe) KeyedObjectPool backed by the specified KeyedObjectPool.
+     *
+     * <p><b>Note:</b>
+     * This should not be used on pool implementations that already provide proper synchronization
+     * such as the pools provided in the Commons Pool library. Wrapping a pool that
+     * {@link #wait() waits} for poolable objects to be returned before allowing another one to be
+     * borrowed with another layer of synchronization will cause liveliness issues or a deadlock.
+     * </p>
+     */
     private static class SynchronizedKeyedObjectPool implements KeyedObjectPool {
+        
+        /** Object whose monitor is used to synchronize methods on the wrapped pool. */
         private final Object lock;
+        
+        /** Underlying object pool */
         private final KeyedObjectPool keyedPool;
 
+        /**
+         * Create a new SynchronizedKeyedObjectPool wrapping the given pool
+         * 
+         * @param keyedPool KeyedObjectPool to wrap
+         * @throws IllegalArgumentException if keyedPool is null
+         */
         SynchronizedKeyedObjectPool(final KeyedObjectPool keyedPool) throws IllegalArgumentException {
             if (keyedPool == null) {
                 throw new IllegalArgumentException("keyedPool must not be null.");
@@ -1542,12 +1640,18 @@ public final class PoolUtils {
             lock = new Object();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
             synchronized (lock) {
                 return keyedPool.borrowObject(key);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void returnObject(final Object key, final Object obj) {
             synchronized (lock) {
                 try {
@@ -1558,6 +1662,9 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void invalidateObject(final Object key, final Object obj) {
             synchronized (lock) {
                 try {
@@ -1568,48 +1675,72 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void addObject(final Object key) throws Exception, IllegalStateException, UnsupportedOperationException {
             synchronized (lock) {
                 keyedPool.addObject(key);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumIdle(final Object key) throws UnsupportedOperationException {
             synchronized (lock) {
                 return keyedPool.getNumIdle(key);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumActive(final Object key) throws UnsupportedOperationException {
             synchronized (lock) {
                 return keyedPool.getNumActive(key);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumIdle() throws UnsupportedOperationException {
             synchronized (lock) {
                 return keyedPool.getNumIdle();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumActive() throws UnsupportedOperationException {
             synchronized (lock) {
                 return keyedPool.getNumActive();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void clear() throws Exception, UnsupportedOperationException {
             synchronized (lock) {
                 keyedPool.clear();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void clear(final Object key) throws Exception, UnsupportedOperationException {
             synchronized (lock) {
                 keyedPool.clear(key);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void close() {
             try {
                 synchronized (lock) {
@@ -1620,12 +1751,21 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * Sets the object factory used by the pool.
+         * 
+         * @param factory KeyedPoolableObjectFactory used by the pool
+         * @deprecated to be removed in pool 2.0
+         */
         public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
             synchronized (lock) {
                 keyedPool.setFactory(factory);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             final StringBuffer sb = new StringBuffer();
             sb.append("SynchronizedKeyedObjectPool");
@@ -1635,10 +1775,27 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * A fully synchronized PoolableObjectFactory that wraps a PoolableObjectFactory and synchronizes
+     * access to the wrapped factory methods.
+     *
+     * <p><b>Note:</b>
+     * This should not be used on pool implementations that already provide proper synchronization
+     * such as the pools provided in the Commons Pool library. </p>
+     */
     private static class SynchronizedPoolableObjectFactory implements PoolableObjectFactory {
+        /** Synchronization lock */
         private final Object lock;
+        
+        /** Wrapped factory */
         private final PoolableObjectFactory factory;
 
+        /** 
+         * Create a SynchronizedPoolableObjectFactory wrapping the given factory.
+         * 
+         * @param factory underlying factory to wrap
+         * @throws IllegalArgumentException if the factory is null
+         */
         SynchronizedPoolableObjectFactory(final PoolableObjectFactory factory) throws IllegalArgumentException {
             if (factory == null) {
                 throw new IllegalArgumentException("factory must not be null.");
@@ -1647,36 +1804,54 @@ public final class PoolUtils {
             lock = new Object();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public Object makeObject() throws Exception {
             synchronized (lock) {
                 return factory.makeObject();
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void destroyObject(final Object obj) throws Exception {
             synchronized (lock) {
                 factory.destroyObject(obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public boolean validateObject(final Object obj) {
             synchronized (lock) {
                 return factory.validateObject(obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void activateObject(final Object obj) throws Exception {
             synchronized (lock) {
                 factory.activateObject(obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void passivateObject(final Object obj) throws Exception {
             synchronized (lock) {
                 factory.passivateObject(obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             final StringBuffer sb = new StringBuffer();
             sb.append("SynchronizedPoolableObjectFactory");
@@ -1686,10 +1861,27 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * A fully synchronized KeyedPoolableObjectFactory that wraps a KeyedPoolableObjectFactory and synchronizes
+     * access to the wrapped factory methods.
+     *
+     * <p><b>Note:</b>
+     * This should not be used on pool implementations that already provide proper synchronization
+     * such as the pools provided in the Commons Pool library. </p>
+     */
     private static class SynchronizedKeyedPoolableObjectFactory implements KeyedPoolableObjectFactory {
+        /** Synchronization lock */
         private final Object lock;
+        
+        /** Wrapped factory */
         private final KeyedPoolableObjectFactory keyedFactory;
 
+        /** 
+         * Create a SynchronizedKeyedPoolableObjectFactory wrapping the given factory.
+         * 
+         * @param keyedFactory underlying factory to wrap
+         * @throws IllegalArgumentException if the factory is null
+         */
         SynchronizedKeyedPoolableObjectFactory(final KeyedPoolableObjectFactory keyedFactory) throws IllegalArgumentException {
             if (keyedFactory == null) {
                 throw new IllegalArgumentException("keyedFactory must not be null.");
@@ -1698,36 +1890,54 @@ public final class PoolUtils {
             lock = new Object();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public Object makeObject(final Object key) throws Exception {
             synchronized (lock) {
                 return keyedFactory.makeObject(key);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void destroyObject(final Object key, final Object obj) throws Exception {
             synchronized (lock) {
                 keyedFactory.destroyObject(key, obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public boolean validateObject(final Object key, final Object obj) {
             synchronized (lock) {
                 return keyedFactory.validateObject(key, obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void activateObject(final Object key, final Object obj) throws Exception {
             synchronized (lock) {
                 keyedFactory.activateObject(key, obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void passivateObject(final Object key, final Object obj) throws Exception {
             synchronized (lock) {
                 keyedFactory.passivateObject(key, obj);
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             final StringBuffer sb = new StringBuffer();
             sb.append("SynchronizedKeyedPoolableObjectFactory");
@@ -1739,22 +1949,49 @@ public final class PoolUtils {
 
     /**
      * Encapsulate the logic for when the next poolable object should be discarded.
+     * Each time update is called, the next time to shrink is recomputed, based on
+     * the float factor, number of idle instances in the pool and high water mark.
+     * Float factor is assumed to be between 0 and 1.  Values closer to 1 cause
+     * less frequent erosion events.  Erosion event timing also depends on numIdle.
+     * When this value is relatively high (close to previously established high water
+     * mark), erosion occurs more frequently.
      */
     private static class ErodingFactor {
+        /** Determines frequency of "erosion" events */
         private final float factor;
+        
+        /** Time of next shrink event */
         private transient volatile long nextShrink;
+        
+        /** High water mark - largest numIdle encountered */
         private transient volatile int idleHighWaterMark;
 
+        /**
+         * Create a new ErodingFactor with the given erosion factor.
+         * 
+         * @param factor erosion factor
+         */
         public ErodingFactor(final float factor) {
             this.factor = factor;
             nextShrink = System.currentTimeMillis() + (long)(900000 * factor); // now + 15 min * factor
             idleHighWaterMark = 1;
         }
 
+        /**
+         * Updates internal state based on numIdle and the current time.
+         * 
+         * @param numIdle number of idle elements in the pool
+         */
         public void update(final int numIdle) {
             update(System.currentTimeMillis(), numIdle);
         }
 
+        /**
+         * Updates internal state using the supplied time and numIdle.
+         * 
+         * @param now current time
+         * @param numIdle number of idle elements in the pool
+         */
         public void update(final long now, final int numIdle) {
             final int idle = Math.max(0, numIdle);
             idleHighWaterMark = Math.max(idle, idleHighWaterMark);
@@ -1763,10 +2000,18 @@ public final class PoolUtils {
             nextShrink = now + (long)(minutes * 60000f * factor);
         }
 
+        /**
+         * Returns the time of the next erosion event.
+         * 
+         * @return next shrink time
+         */
         public long getNextShrink() {
             return nextShrink;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             return "ErodingFactor{" +
                     "factor=" + factor +
@@ -1775,19 +2020,47 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * Decorates an object pool, adding "eroding" behavior.  Based on the
+     * configured {@link #factor erosion factor}, objects returning to the pool
+     * may be invalidated instead of being added to idle capacity.
+     *
+     */
     private static class ErodingObjectPool implements ObjectPool {
+        /** Underlying object pool */
         private final ObjectPool pool;
+        
+        /** Erosion factor */
         private final ErodingFactor factor;
 
+        /** 
+         * Create an ErodingObjectPool wrapping the given pool using the specified erosion factor.
+         * 
+         * @param pool underlying pool
+         * @param factor erosion factor - determines the frequency of erosion events
+         * @see #factor
+         */
         public ErodingObjectPool(final ObjectPool pool, final float factor) {
             this.pool = pool;
             this.factor = new ErodingFactor(factor);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
             return pool.borrowObject();
         }
 
+        /**
+         * Returns obj to the pool, unless erosion is triggered, in which
+         * case obj is invalidated.  Erosion is triggered when there are idle instances in 
+         * the pool and more than the {@link #factor erosion factor}-determined time has elapsed
+         * since the last returnObject activation. 
+         * 
+         * @param obj object to return or invalidate
+         * @see #factor
+         */
         public void returnObject(final Object obj) {
             boolean discard = false;
             final long now = System.currentTimeMillis();
@@ -1812,6 +2085,9 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void invalidateObject(final Object obj) {
             try {
                 pool.invalidateObject(obj);
@@ -1820,22 +2096,37 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
             pool.addObject();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumIdle() throws UnsupportedOperationException {
             return pool.getNumIdle();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumActive() throws UnsupportedOperationException {
             return pool.getNumActive();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void clear() throws Exception, UnsupportedOperationException {
             pool.clear();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void close() {
             try {
                 pool.close();
@@ -1844,10 +2135,17 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         * @deprecated to be removed in pool 2.0
+         */
         public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
             pool.setFactory(factory);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             return "ErodingObjectPool{" +
                     "factor=" + factor +
@@ -1856,14 +2154,37 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * Decorates a keyed object pool, adding "eroding" behavior.  Based on the
+     * configured {@link #factor erosion factor}, objects returning to the pool
+     * may be invalidated instead of being added to idle capacity.
+     *
+     */
     private static class ErodingKeyedObjectPool implements KeyedObjectPool {
+        /** Underlying pool */
         private final KeyedObjectPool keyedPool;
+        
+        /** Erosion factor */
         private final ErodingFactor erodingFactor;
 
+        /** 
+         * Create an ErodingObjectPool wrapping the given pool using the specified erosion factor.
+         * 
+         * @param keyedPool underlying pool
+         * @param factor erosion factor - determines the frequency of erosion events
+         * @see #factor
+         */
         public ErodingKeyedObjectPool(final KeyedObjectPool keyedPool, final float factor) {
             this(keyedPool, new ErodingFactor(factor));
         }
 
+        /** 
+         * Create an ErodingObjectPool wrapping the given pool using the specified erosion factor.
+         * 
+         * @param keyedPool underlying pool - must not be null
+         * @param erodingFactor erosion factor - determines the frequency of erosion events
+         * @see #factor
+         */
         protected ErodingKeyedObjectPool(final KeyedObjectPool keyedPool, final ErodingFactor erodingFactor) {
             if (keyedPool == null) {
                 throw new IllegalArgumentException("keyedPool must not be null.");
@@ -1872,10 +2193,23 @@ public final class PoolUtils {
             this.erodingFactor = erodingFactor;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
             return keyedPool.borrowObject(key);
         }
 
+        /**
+         * Returns obj to the pool, unless erosion is triggered, in which
+         * case obj is invalidated.  Erosion is triggered when there are idle instances in 
+         * the pool associated with the given key and more than the configured {@link #factor erosion factor}
+         * time has elapsed since the last returnObject activation. 
+         * 
+         * @param obj object to return or invalidate
+         * @param key key
+         * @see #factor
+         */
         public void returnObject(final Object key, final Object obj) throws Exception {
             boolean discard = false;
             final long now = System.currentTimeMillis();
@@ -1901,14 +2235,25 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         protected int numIdle(final Object key) {
             return getKeyedPool().getNumIdle();
         }
 
+        /**
+         * Returns the eroding factor for the given key
+         * @param key key
+         * @return eroding factor for the given keyed pool
+         */
         protected ErodingFactor getErodingFactor(final Object key) {
             return erodingFactor;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void invalidateObject(final Object key, final Object obj) {
             try {
                 keyedPool.invalidateObject(key, obj);
@@ -1917,34 +2262,58 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void addObject(final Object key) throws Exception, IllegalStateException, UnsupportedOperationException {
             keyedPool.addObject(key);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumIdle() throws UnsupportedOperationException {
             return keyedPool.getNumIdle();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumIdle(final Object key) throws UnsupportedOperationException {
             return keyedPool.getNumIdle(key);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumActive() throws UnsupportedOperationException {
             return keyedPool.getNumActive();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public int getNumActive(final Object key) throws UnsupportedOperationException {
             return keyedPool.getNumActive(key);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void clear() throws Exception, UnsupportedOperationException {
             keyedPool.clear();
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void clear(final Object key) throws Exception, UnsupportedOperationException {
             keyedPool.clear(key);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public void close() {
             try {
                 keyedPool.close();
@@ -1953,14 +2322,26 @@ public final class PoolUtils {
             }
         }
 
+        /**
+         * {@inheritDoc}
+         * @deprecated to be removed in pool 2.0
+         */
         public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
             keyedPool.setFactory(factory);
         }
 
+        /**
+         * Returns the underlying pool
+         * 
+         * @return the keyed pool that this ErodingKeyedObjectPool wraps
+         */
         protected KeyedObjectPool getKeyedPool() {
             return keyedPool;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             return "ErodingKeyedObjectPool{" +
                     "erodingFactor=" + erodingFactor +
@@ -1969,19 +2350,38 @@ public final class PoolUtils {
         }
     }
 
+    /**
+     * Extends ErodingKeyedObjectPool to allow erosion to take place on a per-key
+     * basis.  Timing of erosion events is tracked separately for separate keyed pools.
+     */
     private static class ErodingPerKeyKeyedObjectPool extends ErodingKeyedObjectPool {
+        /** Erosion factor - same for all pools */
         private final float factor;
+        
+        /** Map of ErodingFactor instances keyed on pool keys */
         private final Map factors = Collections.synchronizedMap(new HashMap());
 
+        /**
+         * Create a new ErordingPerKeyKeyedObjectPool decorating the given keyed pool with
+         * the specified erosion factor.
+         * @param keyedPool underlying keyed pool
+         * @param factor erosion factor
+         */
         public ErodingPerKeyKeyedObjectPool(final KeyedObjectPool keyedPool, final float factor) {
             super(keyedPool, null);
             this.factor = factor;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         protected int numIdle(final Object key) {
             return getKeyedPool().getNumIdle(key);
         }
 
+        /**
+         * {@inheritDoc}
+         */
         protected ErodingFactor getErodingFactor(final Object key) {
             ErodingFactor factor = (ErodingFactor)factors.get(key);
             // this may result in two ErodingFactors being created for a key
@@ -1993,6 +2393,9 @@ public final class PoolUtils {
             return factor;
         }
 
+        /**
+         * {@inheritDoc}
+         */
         public String toString() {
             return "ErodingPerKeyKeyedObjectPool{" +
                     "factor=" + factor +