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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.