/** * Destroys all instances in the stack and clears the stack. * * @param key key passed to factory when destroying instances * @param stack stack to destroy */ private void destroyStack(K key, java.util.Stack <V> stack) { lock (this) { if (null == stack) { return; } else { if (null != _factory) { java.util.Iterator <V> it = stack.iterator(); while (it.hasNext()) { try { _factory.destroyObject(key, it.next()); } catch (Exception e) { // ignore error, keep destroying the rest } } } _totIdle -= stack.size(); _activeCount.remove(key); stack.clear(); } } }
/** * Clears the specified pool, removing all pooled instances corresponding to the given <code>key</code>. * * @param key the key to clear */ public void clear(K key) { lock (this) { java.util.Stack <V> stack = _pools.remove(key); destroyStack(key, stack); } }
/** * <p>Create a new <tt>StackObjectPool</tt> using the specified <code>factory</code> to create new instances, * capping the number of "sleeping" instances to <code>maxIdle</code>, and initially allocating a container * capable of containing at least <code>initIdleCapacity</code> instances. The pool is not pre-populated. * The <code>initIdleCapacity</code> parameter just determines the initial size of the underlying * container, which can increase beyond this value if <code>maxIdle > initIdleCapacity.</code></p> * * <p>Negative values of <code>maxIdle</code> are ignored (i.e., the pool is created using * {@link #DEFAULT_MAX_SLEEPING}) as are non-positive values for <code>initIdleCapacity.</code> * * @param factory the {@link PoolableObjectFactory} used to populate the pool * @param maxIdle cap on the number of "sleeping" instances in the pool * @param initIdleCapacity initial size of the pool (this specifies the size of the container, * it does not cause the pool to be pre-populated.) */ public StackObjectPool(PoolableObjectFactory <T> factory, int maxIdle, int initIdleCapacity) { _factory = factory; _maxSleeping = (maxIdle < 0 ? DEFAULT_MAX_SLEEPING : maxIdle); int initcapacity = (initIdleCapacity < 1 ? DEFAULT_INIT_SLEEPING_CAPACITY : initIdleCapacity); _pool = new java.util.Stack <T>(); _pool.ensureCapacity(initcapacity > _maxSleeping ? _maxSleeping : initcapacity); }
/** * Clears the pool, removing all pooled instances. */ public void clear() { lock (this) { java.util.Iterator <K> it = _pools.keySet().iterator(); while (it.hasNext()) { K key = it.next(); java.util.Stack <V> stack = _pools.get(key); destroyStack(key, stack); } _totIdle = 0; _pools.clear(); _activeCount.clear(); } }
/** * Returns a string representation of this StackKeyedObjectPool, including * the number of pools, the keys and the size of each keyed pool. * * @return Keys and pool sizes */ public override String ToString() { lock (this) { java.lang.StringBuffer buf = new java.lang.StringBuffer(); buf.append(this.getClass().getName()); buf.append(" contains ").append(_pools.size()).append(" distinct pools: "); java.util.Iterator <K> it = _pools.keySet().iterator(); while (it.hasNext()) { K key = it.next(); buf.append(" |").append(key).append("|="); java.util.Stack <V> s = _pools.get(key); buf.append(s.size()); } return(buf.toString()); } }
/** * Create an object using the {@link KeyedPoolableObjectFactory#makeObject factory}, * passivate it, and then placed in the idle object pool. * <code>addObject</code> is useful for "pre-loading" a pool with idle objects. * * @param key the key a new instance should be added to * @throws Exception when {@link KeyedPoolableObjectFactory#makeObject} fails. * @throws IllegalStateException when no {@link #setFactory factory} has been set or after {@link #close} has been called on this pool. */ public void addObject(K key) {//throws Exception { lock (this) { assertOpen(); if (_factory == null) { throw new java.lang.IllegalStateException("Cannot add objects without a factory."); } V obj = _factory.makeObject(key); try { if (!_factory.validateObject(key, obj)) { return; } } catch (Exception e) { try { _factory.destroyObject(key, obj); } catch (Exception e2) { // swallowed } return; } _factory.passivateObject(key, obj); java.util.Stack <V> stack = _pools.get(key); if (null == stack) { stack = new java.util.Stack <V>(); stack.ensureCapacity(_initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity); _pools.put(key, stack); } int stackSize = stack.size(); if (stackSize >= _maxSleeping) { V staleObj; if (stackSize > 0) { staleObj = stack.remove(0); _totIdle--; } else { staleObj = obj; } try { _factory.destroyObject(key, staleObj); } catch (Exception e) { // Don't swallow destroying the newly created object. Object o1 = (Object)obj; Object o2 = (Object)staleObj; if (o1 == o2) { throw e; } } } else { stack.push(obj); _totIdle++; } } }
/** * Returns <code>obj</code> to the pool under <code>key</code>. If adding the * returning instance to the pool results in {@link #_maxSleeping maxSleeping} * exceeded for the given key, the oldest instance in the idle object pool * is destroyed to make room for the returning instance. * * @param key the pool key * @param obj returning instance */ public override void returnObject(K key, V obj) {//throws Exception { lock (this) { decrementActiveCount(key); if (null != _factory) { if (_factory.validateObject(key, obj)) { try { _factory.passivateObject(key, obj); } catch (Exception ex) { _factory.destroyObject(key, obj); return; } } else { return; } } if (isClosed()) { if (null != _factory) { try { _factory.destroyObject(key, obj); } catch (Exception e) { // swallowed } } return; } java.util.Stack <V> stack = _pools.get(key); if (null == stack) { stack = new java.util.Stack <V>(); stack.ensureCapacity(_initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity); _pools.put(key, stack); } int stackSize = stack.size(); if (stackSize >= _maxSleeping) { V staleObj; if (stackSize > 0) { staleObj = stack.remove(0); _totIdle--; } else { staleObj = obj; } if (null != _factory) { try { _factory.destroyObject(key, staleObj); } catch (Exception e) { // swallowed } } } stack.push(obj); _totIdle++; } }
/** * Borrows an object with the given key. If there are no idle instances under the * given key, a new one is created. * * @param key the pool key * @return keyed poolable object instance */ public override V borrowObject(K key) {//throws Exception { lock (this) { assertOpen(); java.util.Stack <V> stack = (_pools.get(key)); if (null == stack) { stack = new java.util.Stack <V>(); stack.ensureCapacity(_initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity); _pools.put(key, stack); } V obj = default(V); do { bool newlyMade = false; if (!stack.empty()) { obj = stack.pop(); _totIdle--; } else { if (null == _factory) { throw new java.util.NoSuchElementException("pools without a factory cannot create new objects as needed."); } else { obj = _factory.makeObject(key); newlyMade = true; } } if (null != _factory && null != obj) { try { _factory.activateObject(key, obj); if (!_factory.validateObject(key, obj)) { throw new java.lang.Exception("ValidateObject failed"); } } catch (java.lang.Throwable t) { PoolUtils.checkRethrow(t); try { _factory.destroyObject(key, obj); } catch (java.lang.Throwable t2) { PoolUtils.checkRethrow(t2); // swallowed } finally { obj = default(V); } if (newlyMade) { throw new java.util.NoSuchElementException( "Could not create a validated object, cause: " + t.getMessage()); } } } } while (obj == null); incrementActiveCount(key); return(obj); } }