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>