You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by do...@apache.org on 2001/02/26 01:38:20 UTC

cvs commit: jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool AbstractPool.java DefaultObjectFactory.java DefaultPool.java ObjectFactory.java Pool.java PoolController.java Poolable.java ThreadSafePool.java

donaldp     01/02/25 16:38:20

  Added:       proposal/4.0/src/java/org/apache/avalon/pool
                        AbstractPool.java DefaultObjectFactory.java
                        DefaultPool.java ObjectFactory.java Pool.java
                        PoolController.java Poolable.java
                        ThreadSafePool.java
  Log:
  Added poolable stuff.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/AbstractPool.java
  
  Index: AbstractPool.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  import org.apache.avalon.Initializable;
  import org.apache.avalon.Recyclable;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class AbstractPool
      implements Pool, Initializable
  {
      protected int                     m_count;
      protected Poolable[]              m_pool;
      protected ObjectFactory           m_factory;
      protected PoolController          m_controller;
      protected int                     m_maximum;
      protected int                     m_initial;
  
      public AbstractPool( final ObjectFactory factory,
                           final PoolController controller,
                           final int initial,
                           final int maximum )
      {
          m_count = 0;
          m_factory = factory;
          m_controller = controller;
          m_maximum = maximum;
          m_initial = initial;
      }
  
      public void init() 
          throws Exception
      {
          grow( m_maximum );
          fill( m_initial );
      }
  
      /**
       * Retrieve an object from pool.
       *
       * @return an object from Pool
       */
      public Poolable get() throws Exception
      {
          if( null == m_pool && null != m_controller )
          {
              final int increase = m_controller.grow();
              if( increase > 0 ) grow( increase );
          }
  
          if( 0 == m_count )
          {
              return m_factory.newInstance();
          }
  
          m_count--;
  
          final Poolable poolable = m_pool[ m_count ];
          m_pool[ m_count ] = null;
          return poolable;
      }
  
      /**
       * Place an object in pool.
       *
       * @param poolable the object to be placed in pool
       */
      public void put( final Poolable poolable )
      {
          if( poolable instanceof Recyclable )
          {
              ((Recyclable)poolable).recycle();
          }
  
          if(  m_pool.length == (m_count + 1) && null != m_controller )
          {
              final int decrease = m_controller.shrink();
              if( decrease > 0 ) shrink( decrease );
          }
  
          if ( m_pool.length > m_count + 1 )
          {
              m_pool[ m_count++ ] = poolable;
          }
      }
  
      /**
       * Return the total number of slots in Pool
       *
       * @return the total number of slots
       */
      public final int getCapacity()
      {
          return m_pool.length;
      }
  
      /**
       * Get the number of used slots in Pool
       *
       * @return the number of used slots
       */
      public final int getSize()
      {
          return m_count;
      }
  
      /**
       * This fills the pool to the size specified in parameter.
       */
      public final void fill( final int fillSize ) throws Exception
      {
          final int size = Math.min( m_pool.length, fillSize );
  
          for( int i = m_count; i < size; i++ )
          {
              m_pool[i] = m_factory.newInstance();
          }
  
          m_count = size;
      }
  
      /**
       * This fills the pool by the size specified in parameter.
       */
      public final void grow( final int increase )
      {
          if( null == m_pool )
          {
              m_pool = new Poolable[ increase ];
              return;
          }
  
          final Poolable[] poolables = new Poolable[ increase + m_pool.length ];
          System.arraycopy( m_pool, 0, poolables, 0, m_pool.length );
          m_pool = poolables;
      }
  
      /**
       * This shrinks the pool by parameter size.
       */
      public final void shrink( final int decrease )
      {
          final Poolable[] poolables = new Poolable[ m_pool.length - decrease ];
          System.arraycopy( m_pool, 0, poolables, 0, poolables.length );
          m_pool = poolables;
      }
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/DefaultObjectFactory.java
  
  Index: DefaultObjectFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  import java.lang.reflect.Constructor;
  import org.apache.avalon.Recyclable;
  
  /**
   * This is the default for factory that is used to create objects for Pool.
   *
   * It creates objects via reflection and constructor.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultObjectFactory
      implements ObjectFactory
  {
      protected Constructor            m_constructor;
      protected Object[]               m_arguements;
  
      public DefaultObjectFactory( final Constructor constructor, final Object[] arguements )
      {
          m_arguements = arguements;
          m_constructor = constructor;
      }
  
      public DefaultObjectFactory( final Class clazz, 
                                   final Class[] arguementClasses, 
                                   final Object[] arguements )
          throws NoSuchMethodException
      {
          this( clazz.getConstructor( arguementClasses ), arguements );
      }
  
      public DefaultObjectFactory( final Class clazz )
          throws NoSuchMethodException
      {
          this( clazz, null, null );
      }
  
      public Class getCreatedClass()
      {
          return m_constructor.getDeclaringClass();
      }
  
      public Poolable newInstance()
      {
          try
          {
              return (Poolable)m_constructor.newInstance( m_arguements );
          } 
          catch( final Exception e ) 
          {
              throw new Error( "Failed to instantiate the class " + 
                               m_constructor.getDeclaringClass().getName() + " due to " + e );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/DefaultPool.java
  
  Index: DefaultPool.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  import org.apache.avalon.Recyclable;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class DefaultPool
      extends AbstractPool
  {
      public final static int           DEFAULT_POOL_SIZE           = 8;
  
      public DefaultPool( final ObjectFactory factory, 
                          final PoolController controller ) 
          throws Exception
      {
          super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
      }
  
      public DefaultPool( final ObjectFactory factory ) 
          throws Exception
      {
          this( factory, null );
      }
  
      public DefaultPool( final Class clazz, final int initial, final int maximum ) 
          throws NoSuchMethodException, Exception
      {
          super( new DefaultObjectFactory( clazz ), null, initial, maximum );
      }
  
      public DefaultPool( final Class clazz, final int initial ) 
          throws NoSuchMethodException, Exception
      {
          this( clazz, initial, initial );
      }
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/ObjectFactory.java
  
  Index: ObjectFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  import org.apache.avalon.component.Component;
  
  /**
   * This is the interface for factory that is used to create objects for Pool.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface ObjectFactory 
      extends Component
  {
      Poolable newInstance() throws Exception;
      Class getCreatedClass();
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/Pool.java
  
  Index: Pool.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  import org.apache.avalon.component.Component;
  
  /**
   * This is an <code>Pool</code> that caches Poolable objects for reuse.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@mad.scientist.com">Peter Donald</a>
   */
  public interface Pool 
      extends Component
  {
      Poolable get() throws Exception;
      void put( Poolable poolable );
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/PoolController.java
  
  Index: PoolController.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  /**
   * This is the interface you implement if you want to control how Pools capacity 
   * changes overtime.
   * 
   * It gets called everytime that a Pool tries to go below or above it's minimum or maximum.
   * 
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   */
  public interface PoolController
  {
      /**
       * Called when a Pool reaches it's minimum. 
       *
       * Return the number of elements to increase minimum and maximum by.
       *
       * @return the element increase
       */
      int grow();
  
      /**
       * Called when a pool reaches it's maximum.
       *
       * Returns the number of elements to decrease mi and max by.
       *
       * @return the element decrease
       */
      int shrink();
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/Poolable.java
  
  Index: Poolable.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  /**
   * Poolable marker interface. 
   *
   * Components implement this interface if it is reasonable to 
   * Pool the object. Components that don't implement this interface 
   * will be created anew via a factory.
   *
   * NB: It was a deliberat e choice not to extend Component. This will have to 
   * be reassed once we see it in action.
   *
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public interface Poolable 
  {
  }
  
  
  
  1.1                  jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/ThreadSafePool.java
  
  Index: ThreadSafePool.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.pool;
  
  import org.apache.avalon.Recyclable;
  import org.apache.avalon.ThreadSafe;
  
  /**
   * This is a implementation of  <code>Pool</code> that is thread safe.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
   * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
   */
  public class ThreadSafePool
      extends AbstractPool
      implements ThreadSafe
  {
      public final static int           DEFAULT_POOL_SIZE           = 8;
  
      protected boolean                 m_blocking                  = false;
  
      public ThreadSafePool( final ObjectFactory factory, final PoolController controller )
          throws Exception 
      {
          super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
      }
  
      public ThreadSafePool( final ObjectFactory factory )
          throws Exception 
      {
          this( factory, null );
      }
  
      public ThreadSafePool( final ObjectFactory factory, 
                             final int initial, 
                             final int maximum  )
          throws Exception 
      {
          super( factory, null, initial, maximum );
      }
  
      public ThreadSafePool( final ObjectFactory factory, final int initial )
          throws Exception 
      {
          this( factory, initial, initial );
      }
  
      public ThreadSafePool( final Class clazz, final int initial, final int maximum ) 
          throws NoSuchMethodException, Exception
      {
          this( new DefaultObjectFactory( clazz ), initial, maximum );
      }
  
      public ThreadSafePool( final Class clazz, final int initial ) 
          throws NoSuchMethodException, Exception
      {
          this( clazz, initial, initial );
      }
  
      public final boolean isBlocking() 
      {
          return m_blocking;
      }
  
      /**
       * Set whether this pool is blocking. 
       * 
       * If this pool is blocking and empties the Pool then the thread will block until
       * an object is placed back in the pool. This has to be used with care as an errant
       * thread who never does a put will force blocked clients to wait forever.
       *
       * @param blocking a boolean indicating if it is blocking or not
       */
      public final void setBlocking( final boolean blocking ) 
      {
          m_blocking = blocking;
      }
  
      /**
       * Retrieve an object from pool.
       *
       * @return an object from Pool
       */
      public final Poolable get() throws Exception 
      {
          //Require this or else the wait later will cause 
          final Poolable[] pool = m_pool;
  
          synchronized( pool )
          {
              if( 0 == m_count )
              {
                  if( !m_blocking ) 
                  {
                      return m_factory.newInstance();
                  }
                  else
                  {
                      while( 0 == m_count )
                      {
                          try { pool.wait(); }
                          catch( final InterruptedException ie ) { }
                      }
                  }
              }
  
              m_count--;
              final Poolable poolable = m_pool[ m_count ];
              m_pool[ m_count ] = null;
              return poolable;
          }
      }
  
      /**
       * Place an object in pool.
       *
       * @param poolable the object to be placed in pool
       */
      public final void put( final Poolable poolable ) 
      {
          final Poolable[] pool = m_pool;
  
          synchronized( pool )
          {
              super.put( poolable );
  
              //if someone was waiting on the old pool then we have to notify them
              pool.notifyAll();
          }
      }
  }