CVS: Tapestry/framework/src/net/sf/tapestry/util/pool StringBufferAdaptor.java,NONE,1.1.2.1 DefaultPoolableAdaptor.java,NONE,1.1.2.1 NullPoolableAdaptor.java,NONE,1.1.2.1 IPoolableAdaptor.java,NONE,1.1.2.1 IPoolable.java,1.6,1.6.2.1 PoolList.java,1.5,1.5.2.1 Pool.java,1.7.2.1,1.7.2.2
Howard Lewis Ship <[email protected]>
| Newsgroups | gmane.comp.java.tapestry.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/util/pool
In directory sc8-pr-cvs1:/tmp/cvs-serv17650/framework/src/net/sf/tapestry/util/pool
Modified Files:
Tag: hship-2-3
IPoolable.java PoolList.java Pool.java
Added Files:
Tag: hship-2-3
StringBufferAdaptor.java DefaultPoolableAdaptor.java
NullPoolableAdaptor.java IPoolableAdaptor.java
Log Message:
Add new functionality to Pool, to support creating JavaBeans on the fly, and to support adaptors to handle store and discard notifications.
--- NEW FILE: StringBufferAdaptor.java ---
package net.sf.tapestry.util.pool;
/**
* Adaptor for {@link java.lang.StringBuffer}, that clears
* the buffer as it is returned to the pool.
*
* @author Howard Lewis Ship
* @version $Id: StringBufferAdaptor.java,v 1.1.2.1 2003/01/03 20:54:18 hship Exp $
* @since 2.4
*
**/
public class StringBufferAdaptor extends NullPoolableAdaptor
{
/**
* Sets the length of the {@link java.lang.StringBuffer}
* to zero.
*
**/
public void resetForPool(Object object)
{
StringBuffer buffer = (StringBuffer)object;
buffer.setLength(0);
}
}
--- NEW FILE: DefaultPoolableAdaptor.java ---
package net.sf.tapestry.util.pool;
/**
* Implementation for objects that implement
* the {@link net.sf.tapestry.util.pool.IPoolable} interface.
*
* @author Howard Lewis Ship
* @version $Id: DefaultPoolableAdaptor.java,v 1.1.2.1 2003/01/03 20:54:18 hship Exp $
* @since 2.4
*
**/
public class DefaultPoolableAdaptor implements IPoolableAdaptor
{
public void resetForPool(Object object)
{
IPoolable poolable = (IPoolable)object;
poolable.resetForPool();
}
public void discardFromPool(Object object)
{
IPoolable poolable = (IPoolable)object;
poolable.discardFromPool();
}
}
--- NEW FILE: NullPoolableAdaptor.java ---
package net.sf.tapestry.util.pool;
/**
* A default, empty implementation, for objects that
* have no special behavior related to being pooled.
*
* @author Howard Lewis Ship
* @version $Id: NullPoolableAdaptor.java,v 1.1.2.1 2003/01/03 20:54:18 hship Exp $
* @since 2.4
*
**/
public class NullPoolableAdaptor implements IPoolableAdaptor
{
public void resetForPool(Object object)
{
}
public void discardFromPool(Object object)
{
}
}
--- NEW FILE: IPoolableAdaptor.java ---
package net.sf.tapestry.util.pool;
/**
* Defines methods that define an adaptor to provide
* {@link net.sf.tapestry.util.pool.IPoolable}
* type behavior to arbitrary objects.
*
* @author Howard Lewis Ship
* @version $Id: IPoolableAdaptor.java,v 1.1.2.1 2003/01/03 20:54:18 hship Exp $
* @since 2.4
*
**/
public interface IPoolableAdaptor
{
/**
* Invoked just as an object is returned to the pool; this
* allows it to reset any state back to newly initialized.
*
**/
public void resetForPool(Object object);
/**
* Invoked when a pooled object is discarded from the pool.
*
**/
public void discardFromPool(Object object);
}
Index: IPoolable.java
===================================================================
RCS file: /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/util/pool/IPoolable.java,v
retrieving revision 1.6
retrieving revision 1.6.2.1
diff -C2 -d -r1.6 -r1.6.2.1
*** IPoolable.java 27 Nov 2002 17:58:47 -0000 1.6
--- IPoolable.java 3 Jan 2003 20:54:18 -0000 1.6.2.1
***************
*** 23,25 ****
--- 23,34 ----
public void resetForPool();
+
+ /**
+ * Invoked just as a Pool discards an object (for lack of use).
+ * This allows a last chance to perform final cleanup
+ * on the object while it is still referencable.
+ *
+ **/
+
+ public void discardFromPool();
}
Index: PoolList.java
===================================================================
RCS file: /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/util/pool/PoolList.java,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -C2 -d -r1.5 -r1.5.2.1
*** PoolList.java 27 Nov 2002 17:58:47 -0000 1.5
--- PoolList.java 3 Jan 2003 20:54:18 -0000 1.5.2.1
***************
*** 21,24 ****
--- 21,28 ----
class PoolList
{
+ /** @since 2.4 **/
+
+ private Pool _pool;
+
/**
* Linked list of pooled objects.
***************
*** 27,31 ****
**/
! private Entry first;
/**
--- 31,35 ----
**/
! private Entry _first;
/**
***************
*** 35,39 ****
**/
! private Entry spare;
/**
--- 39,43 ----
**/
! private Entry _spare;
/**
***************
*** 42,46 ****
**/
! private int count;
/**
--- 46,50 ----
**/
! private int _count;
/**
***************
*** 48,51 ****
--- 52,56 ----
*
* @since 1.0.5
+ *
**/
***************
*** 58,61 ****
--- 63,76 ----
/**
+ * @since 2.4
+ *
+ **/
+
+ PoolList(Pool pool)
+ {
+ _pool = pool;
+ }
+
+ /**
* Returns the number of pooled objects currently stored.
*
***************
*** 65,69 ****
public int getPooledCount()
{
! return count;
}
--- 80,84 ----
public int getPooledCount()
{
! return _count;
}
***************
*** 76,93 ****
public Object retrieve()
{
! if (count == 0)
return null;
! count--;
! Entry e = first;
Object result = e.pooled;
// Okay, store e into the list of spare entries.
! first = e.next;
! e.next = spare;
! spare = e;
e.generation = 0;
e.pooled = null;
--- 91,108 ----
public Object retrieve()
{
! if (_count == 0)
return null;
! _count--;
! Entry e = _first;
Object result = e.pooled;
// Okay, store e into the list of spare entries.
! _first = e.next;
! e.next = _spare;
! _spare = e;
e.generation = 0;
e.pooled = null;
***************
*** 109,113 ****
Entry e;
! if (spare == null)
{
e = new Entry();
--- 124,128 ----
Entry e;
! if (_spare == null)
{
e = new Entry();
***************
*** 115,128 ****
else
{
! e = spare;
! spare = spare.next;
}
e.generation = generation;
e.pooled = object;
! e.next = first;
! first = e;
! return ++count;
}
--- 130,143 ----
else
{
! e = _spare;
! _spare = _spare.next;
}
e.generation = generation;
e.pooled = object;
! e.next = _first;
! _first = e;
! return ++_count;
}
***************
*** 138,144 ****
public int cleanup(int generation)
{
! spare = null;
! count = 0;
Entry prev = null;
--- 153,159 ----
public int cleanup(int generation)
{
! _spare = null;
! _count = 0;
Entry prev = null;
***************
*** 146,150 ****
// Walk through the list. They'll be sorted by generation.
! Entry e = first;
while (true)
{
--- 161,165 ----
// Walk through the list. They'll be sorted by generation.
! Entry e = _first;
while (true)
{
***************
*** 157,160 ****
--- 172,182 ----
if (e.generation <= generation)
{
+ Object pooled = e.pooled;
+
+ // Notify the object that it is being dropped
+ // through the cracks!
+
+ _pool.getAdaptor(pooled).discardFromPool(pooled);
+
// Set the next pointer of the previous node to null.
// If the very first node inspected was too old,
***************
*** 162,182 ****
if (prev == null)
! first = null;
else
prev.next = null;
-
- break;
}
prev = e;
e = e.next;
- count++;
}
! return count;
}
public String toString()
{
! return "PoolList[" + count + "]";
}
! }
\ No newline at end of file
--- 184,231 ----
if (prev == null)
! _first = null;
else
prev.next = null;
}
+ else
+ _count++;
prev = e;
e = e.next;
}
! return _count;
}
+
public String toString()
{
! return "PoolList[" + _count + "]";
}
!
! /**
! * Much like {@link #cleanup(int)}, but discards all
! * pooled objects.
! *
! * @since 2.4
! *
! **/
!
! void discardAll()
! {
! Entry e = _first;
!
! while (e != null)
! {
! Object pooled = e.pooled;
!
! _pool.getAdaptor(pooled).discardFromPool(pooled);
!
! e = e.next;
! }
!
! _first = null;
! _spare = null;
! _count = 0;
!
! }
! }
Index: Pool.java
===================================================================
RCS file: /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/util/pool/Pool.java,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.2
diff -C2 -d -r1.7.2.1 -r1.7.2.2
*** Pool.java 12 Dec 2002 12:42:39 -0000 1.7.2.1
--- Pool.java 3 Jan 2003 20:54:18 -0000 1.7.2.2
***************
*** 9,14 ****
--- 9,17 ----
import org.apache.commons.logging.LogFactory;
+ import net.sf.tapestry.ApplicationRuntimeException;
import net.sf.tapestry.IMarkupWriter;
import net.sf.tapestry.IRenderDescription;
+ import net.sf.tapestry.Tapestry;
+ import net.sf.tapestry.util.AdaptorRegistry;
import net.sf.tapestry.util.ICleanable;
import net.sf.tapestry.util.JanitorThread;
***************
*** 28,31 ****
--- 31,50 ----
* culls objects whose generation count is too old (outside of a
* {@link #getWindow() window}).
+ *
+ * <p>
+ * Objects in the pool can receive two notifications: one notification
+ * when they are {@link #store(Object, Object) stored} into the pool,
+ * and one when they are discarded form the pool.
+ *
+ * <p>
+ * Classes that implement {@link net.sf.tapestry.util.pool.IPoolable}
+ * receive notifications directly, as per the two methods
+ * of that interface.
+ *
+ * <p>
+ * Alternately, an adaptor for the other classes can be
+ * registerered (using {@link #registerAdaptor(Class, IPoolableAdaptor)}.
+ * The adaptor will be invoked to perform the desred cleanup
+ * of the object instead.
*
* @author Howard Lewis Ship
***************
*** 38,41 ****
--- 57,62 ----
private static final Log LOG = LogFactory.getLog(Pool.class);
+ private AdaptorRegistry _adaptors = new AdaptorRegistry();
+
/**
* The generation, used to cull unused pooled items.
***************
*** 102,105 ****
--- 123,128 ----
if (useSharedJanitor)
JanitorThread.getSharedJanitorThread().add(this);
+
+ registerAdaptors();
}
***************
*** 182,213 ****
/**
! * Stores an object in the pool for later retrieval. Invokes
! * {@link IPoolable#resetForPool()}, if the object
! * implements the {@link IPoolable} interface.
! *
**/
! public synchronized void store(Object key, Object object)
{
! PoolList list;
! int count;
! if (object instanceof IPoolable)
{
! ((IPoolable) object).resetForPool();
}
if (_map == null)
_map = new HashMap();
! list = (PoolList) _map.get(key);
if (list == null)
{
! list = new PoolList();
_map.put(key, list);
}
! count = list.store(_generation, object);
_pooledCount++;
--- 205,273 ----
/**
! * Retrieves an instance of the named class. If no pooled
! * instance is available, a new instance is created
! * (using the no arguments constructor). Objects are
! * pooled using their actual class as a key.
! *
**/
! public Object retrieve(Class objectClass)
{
! Object result = retrieve((Object) objectClass);
! if (result == null)
{
! if (LOG.isDebugEnabled())
! LOG.debug("No instance of " + objectClass.getName() + " is available, instantiating one.");
!
! try
! {
! result = objectClass.newInstance();
! }
! catch (Exception ex)
! {
! throw new ApplicationRuntimeException(
! Tapestry.getString("Pool.unable-to-instantiate-instance", objectClass.getName()),
! ex);
! }
}
+ return result;
+ }
+
+ /**
+ * Stores an object using its class as a key.
+ *
+ * @see #retrieve(Class)
+ *
+ **/
+
+ public void store(Object object)
+ {
+ store(object.getClass(), object);
+ }
+
+ /**
+ * Stores an object in the pool for later retrieval, resetting
+ * the object for storage within the pool.
+ *
+ **/
+
+ public synchronized void store(Object key, Object object)
+ {
+ getAdaptor(object).resetForPool(object);
+
if (_map == null)
_map = new HashMap();
! PoolList list = (PoolList) _map.get(key);
if (list == null)
{
! list = new PoolList(this);
_map.put(key, list);
}
! int count = list.store(_generation, object);
_pooledCount++;
***************
*** 225,229 ****
--- 285,300 ----
{
if (_map != null)
+ {
+ Iterator i = _map.values().iterator();
+
+ while (i.hasNext())
+ {
+ PoolList list = (PoolList) i.next();
+
+ list.discardAll();
+ }
+
_map.clear();
+ }
_pooledCount = 0;
***************
*** 364,367 ****
--- 435,484 ----
}
}
+ }
+
+ /**
+ * Invoked from the constructor to register the default set of
+ * {@link net.sf.tapestry.util.pool.IPoolableAdaptor}. Subclasses
+ * may override this to register a different set.
+ *
+ * <p>
+ * Registers:
+ * <ul>
+ * <li>{@link NullPoolableAdaptor} for class Object
+ * <li>{@link DefaultPoolableAdaptor} for interface {@link IPoolable}
+ * <li>{@link StringBufferAdaptor} for {@link StringBuffer}
+ * </ul>
+ *
+ * @since 2.4
+ *
+ **/
+
+ protected void registerAdaptors()
+ {
+ registerAdaptor(Object.class, new NullPoolableAdaptor());
+ registerAdaptor(IPoolable.class, new DefaultPoolableAdaptor());
+ registerAdaptor(StringBuffer.class, new StringBufferAdaptor());
+ }
+
+ /**
+ * Registers an adaptor for a particular class (or interface).
+ *
+ * @since 2.4
+ *
+ **/
+
+ public void registerAdaptor(Class registrationClass, IPoolableAdaptor adaptor)
+ {
+ _adaptors.register(registrationClass, adaptor);
+ }
+
+ /**
+ * Returns an adaptor appropriate to the object.
+ *
+ **/
+
+ public IPoolableAdaptor getAdaptor(Object object)
+ {
+ return (IPoolableAdaptor) _adaptors.getAdaptor(object.getClass());
}
}
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf