You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by as...@apache.org on 2002/02/18 19:16:50 UTC

cvs commit: jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/memory/shrinking ShrinkingMemoryCache.java ShrinkerThread.java

asmuts      02/02/18 10:16:50

  Added:       src/java/org/apache/stratum/jcs/engine/memory/shrinking
                        ShrinkingMemoryCache.java ShrinkerThread.java
  Log:
  these are very rough and i'm just looking for problems witht he concept
  
  Revision  Changes    Path
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/memory/shrinking/ShrinkingMemoryCache.java
  
  Index: ShrinkingMemoryCache.java
  ===================================================================
  package org.apache.stratum.jcs.engine.memory.shrinking;
  
  import java.io.IOException;
  import java.io.Serializable;
  
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  import java.util.Map.Entry;
  
  import org.apache.stratum.jcs.engine.behavior.IElementAttributes;
  import org.apache.stratum.jcs.engine.CacheElement;
  
  import org.apache.stratum.jcs.engine.behavior.ICache;
  import org.apache.stratum.jcs.engine.behavior.ICacheElement;
  import org.apache.stratum.jcs.engine.behavior.ICacheHub;
  import org.apache.stratum.jcs.engine.behavior.ICacheType;
  import org.apache.stratum.jcs.engine.behavior.ICompositeCacheAttributes;
  
  import org.apache.stratum.jcs.engine.memory.MemoryElementDescriptor;
  import org.apache.stratum.jcs.engine.memory.behavior.IMemoryCache;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  /**
   * This is mainly intended as a tester for the ShrinkerThread
   *
   * @author asmuts
   * @created February 18, 2002
   */
  public class ShrinkingMemoryCache implements IMemoryCache, ICache, Serializable
  {
      private final static Log log =
          LogSource.getInstance( ShrinkingMemoryCache.class );
  
      // MOVE TO MEMORYMANAGER
      String cacheName;
  
      /**
       * The item store
       */
      protected Map map = new HashMap();
  
      /**
       * Region Elemental Attributes
       */
      public IElementAttributes attr;
  
      /**
       * Cache Attributes
       */
      public ICompositeCacheAttributes cattr;
  
      private String source_id = "org.apache.stratum.jcs.engine.memory.shrinking.ShrinkingMemoryCache";
  
      // The HUB
      ICacheHub hub;
  
      // status
      private int status = this.STATUS_ERROR;
  
      private ShrinkerThread shrinker;
  
      // for reflection
      /**
       * Constructor for the ShrinkingMemoryCache object
       */
      public ShrinkingMemoryCache()
      {
          // might want to consider this an error state
          status = this.STATUS_ERROR;
      }
  
      // should use this method
  
      /**
       * Constructor for the ShrinkingMemoryCache object
       *
       * @param cacheName
       * @param cattr
       * @param hub
       */
      public ShrinkingMemoryCache( String cacheName, ICompositeCacheAttributes cattr, ICacheHub hub )
      {
          initialize( cacheName, cattr, hub );
      }
  
  
      // for post reflection creation initialization
      /**
       * Description of the Method
       *
       * @param cacheName
       * @param cattr
       * @param hub
       */
      public void initialize( String cacheName, ICompositeCacheAttributes cattr, ICacheHub hub )
      {
          this.cacheName = cacheName;
          this.cattr = cattr;
          this.hub = hub;
          status = this.STATUS_ALIVE;
  
          if ( cattr.getUseMemoryShrinker() )
          {
              shrinker = new ShrinkerThread( this );
              shrinker.setPriority( shrinker.MIN_PRIORITY );
              shrinker.start();
          }
  
          log.info( "initialized ShrinkingMemoryCache for " + cacheName );
      }
  
  
      /**
       * Gets the sourceId attribute of the ShrinkingMemoryCache object
       *
       * @return The sourceId value
       */
      public Serializable getSourceId()
      {
          return this.source_id;
      }
  
  
      /**
       * Gets the cacheType attribute of the ShrinkingMemoryCache object
       *
       * @return The cacheType value
       */
      public int getCacheType()
      {
          return ICacheType.MEMORY_CACHE;
      }
  
  
      /**
       * Puts an item to the cache.
       *
       * @param ce
       * @exception IOException
       */
      public void update( ICacheElement ce )
          throws IOException
      {
  
          try
          {
  
              MemoryElementDescriptor me = new MemoryElementDescriptor( ce );
              map.put( ce.getKey(), me );
  
          }
          catch ( Exception ex )
          {
              // impossible case.
              ex.printStackTrace();
              throw new IllegalStateException( ex.getMessage() );
          }
  
      }
      // end update
  
      // TODO: Implement or modify interface, just implement
      // may need insert if we want to distinguish b/wn put and replace
      /**
       * Description of the Method
       *
       * @param key
       * @param val
       * @exception IOException
       */
      public void put( Serializable key, Serializable val )
          throws IOException
      {
          // not used
      }
  
  
      /**
       * Description of the Method
       *
       * @param key
       * @param val
       * @param attr
       * @exception IOException
       */
      public void put( Serializable key, Serializable val, IElementAttributes attr )
          throws IOException
      {
          // not used
      }
  
  
      /**
       * Gets an item from the cache.
       *
       * @return
       * @param key
       * @exception IOException
       */
      public Serializable get( Serializable key )
          throws IOException
      {
          return get( key, true );
      }
  
  
      /**
       * Description of the Method
       *
       * @return
       * @param key
       * @param container
       * @exception IOException
       */
      public Serializable get( Serializable key, boolean container )
          throws IOException
      {
          MemoryElementDescriptor me = null;
          ICacheElement ce = null;
          boolean found = false;
  
          try
          {
              if ( log.isDebugEnabled() )
              {
                  log.debug( "get: key = " + key );
              }
  
              me = ( MemoryElementDescriptor ) map.get( key );
              if ( log.isDebugEnabled() )
              {
                  log.debug( "me =" + me );
              }
  
              if ( me == null )
              {
  
              }
              else
              {
                  found = true;
                  ce = me.ce;
                  //ramHit++;
                  if ( log.isDebugEnabled() )
                  {
                      log.debug( cacheName + " -- RAM-HIT for " + key );
                  }
              }
  
          }
          catch ( Exception e )
          {
              log.error( e );
          }
  
          try
          {
  
              if ( !found )
              {
                  // Item not found in all caches.
                  //miss++;
                  if ( log.isDebugEnabled() )
                  {
                      log.debug( cacheName + " -- MISS for " + key );
                  }
                  return null;
                  //throw new ObjectNotFoundException( key + " not found in cache" );
              }
          }
          catch ( Exception e )
          {
              log.error( "Error handling miss", e );
              return null;
          }
  
          try
          {
              //me.ce.setLastAccessTimeNow();
          }
          catch ( Exception e )
          {
              log.error( "Error making first", e );
              return null;
          }
  
          if ( container )
          {
              return ce;
          }
          else
          {
              return ce.getVal();
          }
  
      }
      // end get
  
      /**
       * Removes an item from the cache.
       *
       * @return
       * @param key
       * @exception IOException
       */
      public boolean remove( Serializable key )
          throws IOException
      {
  
          if ( log.isDebugEnabled() )
          {
              log.debug( "remove> key=" + key );
              //+, nonLocal="+nonLocal);
          }
  
          //p("remove> key="+key+", nonLocal="+nonLocal);
          boolean removed = false;
  
          // handle partial removal
          if ( key instanceof String && key.toString().endsWith( NAME_COMPONENT_DELIMITER ) )
          {
              // remove all keys of the same name hierarchy.
              synchronized ( map )
              {
                  for ( Iterator itr = map.entrySet().iterator(); itr.hasNext();  )
                  {
                      Map.Entry entry = ( Map.Entry ) itr.next();
                      Object k = entry.getKey();
                      if ( k instanceof String && k.toString().startsWith( key.toString() ) )
                      {
                          itr.remove();
                          removed = true;
                      }
                  }
              }
          }
          else
          {
              // remove single item.
              MemoryElementDescriptor ce = ( MemoryElementDescriptor ) map.remove( key );
              if ( ce != null )
              {
                  removed = true;
              }
          }
          // end else not hierarchical removal
          return removed;
      }
  
  
      /**
       * Removes all cached items from the cache.
       *
       * @exception IOException
       */
      public void removeAll()
          throws IOException
      {
          map = new HashMap();
      }
  
      /**
       * Description of the Method
       *
       * @param me
       */
      protected void waterfal( MemoryElementDescriptor me )
      {
          hub.spoolToDisk( me.ce );
      }
  
  
      /**
       * Prepares for shutdown.
       *
       * @exception IOException
       */
      public void dispose()
          throws IOException
      {
          shrinker.kill();
      }
  
  
      /**
       * Returns the cache statistics.
       *
       * @return The stats value
       */
      public String getStats()
      {
          return "";
      }
  
  
      /**
       * Returns the current cache size.
       *
       * @return The size value
       */
      public int getSize()
      {
          return this.map.size();
      }
  
  
      /**
       * Returns the cache status.
       *
       * @return The status value
       */
      public int getStatus()
      {
          return this.status;
          //return this.STATUS_ALIVE;
      }
  
  
      /**
       * Returns the cache name.
       *
       * @return The cacheName value
       */
      public String getCacheName()
      {
          return this.cattr.getCacheName();
      }
  
  
      /**
       * Gets the iterator attribute of the ShrinkingMemoryCache object
       *
       * @return The iterator value
       */
      public Iterator getIterator()
      {
          //return Collections.enumeration(map.entrySet());
          return map.entrySet().iterator();
      }
  
  
      /**
       * Dump the cache map for debugging.
       */
      public void dumpMap()
      {
          log.debug( "dumpingMap" );
          for ( Iterator itr = map.entrySet().iterator(); itr.hasNext();  )
          {
              //for ( Iterator itr = memCache.getIterator(); itr.hasNext();) {
              Map.Entry e = ( Map.Entry ) itr.next();
              MemoryElementDescriptor me = ( MemoryElementDescriptor ) e.getValue();
              log.debug( "dumpMap> key=" + e.getKey() + ", val=" + me.ce.getVal() );
          }
      }
  
  }
  
  
  
  1.1                  jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/memory/shrinking/ShrinkerThread.java
  
  Index: ShrinkerThread.java
  ===================================================================
  package org.apache.stratum.jcs.engine.memory.shrinking;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   * notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   * notice, this list of conditions and the following disclaimer in
   * the documentation and/or other materials provided with the
   * distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   * any, must include the following acknowlegement:
   * "This product includes software developed by the
   * Apache Software Foundation (http://www.apache.org/)."
   * Alternately, this acknowlegement may appear in the software itself,
   * if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Velocity", and "Apache Software
   * Foundation" must not be used to endorse or promote products derived
   * from this software without prior written permission. For written
   * permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   * nor may "Apache" appear in their names without prior written
   * permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogSource;
  
  import org.apache.stratum.jcs.engine.memory.MemoryElementDescriptor;
  
  /**
   * A background memory shrinker. Just started. Don't use.
   *
   * @author <a href="mailto:asmuts@yahoo.com">Aaron Smuts</a>
   * @created February 18, 2002
   * @version $Id:
   */
  public class ShrinkerThread extends Thread
  {
  
      private ShrinkingMemoryCache cache;
      boolean alive = true;
  
      /**
       * Constructor for the ShrinkerThread object. Should take an IMemoryCache
       *
       * @param cache
       */
      public ShrinkerThread( ShrinkingMemoryCache cache )
      {
          super();
          this.cache = cache;
      }
  
      /**
       * Description of the Method
       */
      public void kill()
      {
          alive = false;
      }
  
      /**
       * Main processing method for the ShrinkerThread object
       */
      public void run()
      {
  
          while ( alive )
          {
  
              shrink();
  
              // should be in the CacheAttributes
              try
              {
                  this.sleep( cache.cattr.getShrinkerIntervalSeconds() * 1000 );
              }
              catch ( InterruptedException ie )
              {
                  return;
              }
          }
          return;
      }
  
      /**
       * Constructor for the shrink object
       */
      protected void shrink()
      {
  
          // not thread safe.  Copuld cause problems.  Only call remove directly
          // to the map.
          try
          {
              java.util.Set keySet = cache.map.keySet();
  
              java.util.Iterator keys = keySet.iterator();
  
              while ( keys.hasNext() )
              {
                  Object key = keys.next();
                  long now = System.currentTimeMillis();
  
                  MemoryElementDescriptor me = ( MemoryElementDescriptor ) cache.map.get( key );
  
                  // Memory idle, to disk shrinkage
                  if ( cache.cattr.getMaxMemoryIdleTimeSeconds() != -1 )
                  {
                      long deadAt = me.ce.getElementAttributes().getLastAccessTime() + ( cache.cattr.getMaxMemoryIdleTimeSeconds() * 1000 );
                      if ( ( deadAt - now ) < 0 )
                      {
                          cache.map.remove( key );
                          cache.waterfal( me );
                      }
                  }
  
                  if ( !me.ce.getElementAttributes().getIsEternal() )
                  {
                      // Exceeded maxLifeSeconds
                      if ( ( me.ce.getElementAttributes().getMaxLifeSeconds() != -1 ) && ( now - me.ce.getElementAttributes().getCreateTime() ) > ( me.ce.getElementAttributes().getMaxLifeSeconds() * 1000 ) )
                      {
                          cache.map.remove( key );
                      }
  
                      // Exceeded maxIdleTime, removal
                      if ( ( me.ce.getElementAttributes().getIdleTime() * 1000 != -1 ) && ( now - me.ce.getElementAttributes().getLastAccessTime() ) > ( me.ce.getElementAttributes().getIdleTime() * 1000 ) )
                      {
                          cache.map.remove( key );
                      }
                  }
  
              }
          }
          catch ( Throwable t )
          {
              // keep going?
              // concurrent modifications will be a serious problem here
              // there is no good way yo interate througha  map without locking it
  
              //stop for now
              return;
          }
  
      }
  
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>