You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by as...@apache.org on 2004/07/16 05:16:23 UTC
cvs commit: jakarta-turbine-jcs/auxiliary-builds/jdk14/src/java/org/apache/jcs/engine/memory/lru LHMLRUMemoryCache.java
asmuts 2004/07/15 20:16:23
Added: auxiliary-builds/jdk14/src/java/org/apache/jcs/engine/memory/lru
LHMLRUMemoryCache.java
Log:
new jdk1.4 build dir
Revision Changes Path
1.1 jakarta-turbine-jcs/auxiliary-builds/jdk14/src/java/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCache.java
Index: LHMLRUMemoryCache.java
===================================================================
package org.apache.jcs.engine.memory.lru;
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jcs.engine.CacheConstants;
import org.apache.jcs.engine.CacheElement;
import org.apache.jcs.engine.behavior.ICacheElement;
import org.apache.jcs.engine.control.CompositeCache;
import org.apache.jcs.engine.memory.AbstractMemoryCache;
import org.apache.jcs.engine.control.group.GroupId;
import org.apache.jcs.engine.control.group.GroupAttrName;
import org.apache.jcs.engine.memory.util.MemoryElementDescriptor;
/**
* This is a test memory manager using the jdk1.4 LinkedHashMap.
* There may be some thread safety issues.
* So far i cannot notice any performance difference between this and the
* standard LRU implementation. It needs more testing.
*
*@version $Id: LHMLRUMemoryCache.java,v 1.1 2004/07/16 03:16:23 asmuts Exp $
*/
public class LHMLRUMemoryCache
extends AbstractMemoryCache
{
private final static Log log = LogFactory.getLog(LRUMemoryCache.class);
// the extended LinkedHashMap
private Map map;
/**
* For post reflection creation initialization
*
*@param hub
*/
public synchronized void initialize(CompositeCache hub)
{
super.initialize(hub);
map = new LHMSpooler();
log.info("initialized LHMLRUMemoryCache for " + cacheName);
}
/**
* Puts an item to the cache.
*
*@param ce Description of the Parameter
*@exception IOException
*/
public void update(ICacheElement ce) throws IOException
{
// Asynchronisly create a MemoryElement
ce.getElementAttributes().setLastAccessTimeNow();
map.put(ce.getKey(), ce);
}
/**
* Remove all of the elements from both the Map and the linked
* list implementation. Overrides base class.
*/
public synchronized void removeAll() throws IOException
{
map.clear();
}
/**
* Get an item from the cache without affecting its last access time or
* position. There is no way to do this with the LinkedHashMap!
*
*@param key Identifies item to find
*@return Element mathinh key if found, or null
*@exception IOException
*/
public ICacheElement getQuiet(Serializable key) throws IOException
{
ICacheElement ce = null;
ce = (ICacheElement) map.get(key);
if (ce != null)
{
if (log.isDebugEnabled())
{
log.debug(cacheName + ": LRUMemoryCache quiet hit for " + key);
}
}
else if (log.isDebugEnabled())
{
log.debug(cacheName + ": LRUMemoryCache quiet miss for " + key);
}
return ce;
}
/**
* Get an item from the cache
*
*@param key Identifies item to find
*@return ICacheElement if found, else null
*@exception IOException
*/
public synchronized ICacheElement get(Serializable key) throws IOException
{
ICacheElement ce = null;
if (log.isDebugEnabled())
{
log.debug("getting item from cache " + cacheName + " for key " +
key);
}
ce = (ICacheElement) map.get(key);
if (ce != null)
{
if (log.isDebugEnabled())
{
log.debug(cacheName + ": LRUMemoryCache hit for " + key);
}
}
else
{
log.debug(cacheName + ": LRUMemoryCache miss for " + key);
}
return ce;
}
/**
* Removes an item from the cache. This method handles hierarchical
* removal. If the key is a String and ends with the
* CacheConstants.NAME_COMPONENT_DELIMITER, then all items with keys
* starting with the argument String will be removed.
*
*@param key
*@return
*@exception IOException
*/
public synchronized boolean remove(Serializable key) throws IOException
{
if (log.isDebugEnabled())
{
log.debug("removing item for key: " + key);
}
boolean removed = false;
// handle partial removal
if (key instanceof String && ( (String) key)
.endsWith(CacheConstants.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
&& ( (String) k).startsWith(key.toString()))
{
itr.remove();
removed = true;
}
}
}
}
else if (key instanceof GroupId)
{
// 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 GroupAttrName
&& ( (GroupAttrName) k).groupId.equals(key))
{
itr.remove();
removed = true;
}
}
}
}
else
{
// remove single item.
ICacheElement ce = (ICacheElement) map.remove(key);
removed = true;
}
return removed;
}
/**
* Get an Array of the keys for all elements in the memory cache
*
*@return An Object[]
*/
public Object[] getKeyArray()
{
// need a better locking strategy here.
synchronized (this)
{
// may need to lock to map here?
return map.keySet().toArray();
}
}
// ---------------------------------------------------------- debug methods
/**
* Dump the cache map for debugging.
*/
public void dumpMap()
{
log.debug("dumpingMap");
for (Iterator itr = map.entrySet().iterator(); itr.hasNext(); )
{
Map.Entry e = (Map.Entry) itr.next();
MemoryElementDescriptor me = (MemoryElementDescriptor) e.getValue();
log.debug("dumpMap> key=" + e.getKey() + ", val=" + me.ce.getVal());
}
}
/**
* Dump the cache entries from first to list for debugging.
*/
public void dumpCacheEntries()
{
log.debug("dumpingCacheEntries");
//Map.Entry e = map.
//for ( )
//{
// log.debug( "dumpCacheEntries> key="
// + me.ce.getKey() + ", val=" + me.ce.getVal() );
//}
}
private int dumpCacheSize()
{
int size = 0;
size = map.size();
return size;
}
// ---------------------------------------------------------- extended map
/**
* Implementation of removeEldestEntry in LinkedHashMap
*/
public class LHMSpooler
extends java.util.LinkedHashMap
{
/**
* Initialize to a small size--for now, 1/2 of max
* 3rd variable "true" indicates that it should be access
* and not time goverened. This could be configurable.
*/
public LHMSpooler()
{
super( (int) (cache.getCacheAttributes().getMaxObjects() * .5), .75F, true);
}
/**
* Remove eldest. Automatically called by LinkedHashMap.
*/
protected boolean removeEldestEntry(Map.Entry eldest)
{
CacheElement element = (CacheElement) eldest.getValue();
if (size() <= cache.getCacheAttributes().getMaxObjects())
{
return false;
}
else
{
if (log.isDebugEnabled())
{
log.debug("LHMLRU max size: " +
cache.getCacheAttributes().getMaxObjects()
+ ". Spooling element, key: " + element.getKey());
}
spoolToDisk(element);
if (log.isDebugEnabled())
{
log.debug("LHMLRU size: " + map.size());
}
}
return true;
}
/**
* Puts the element in the DiskStore
* @param element The CacheElement
*/
private void spoolToDisk(CacheElement element)
{
cache.spoolToDisk(element);
if (log.isDebugEnabled())
{
log.debug(cache.getCacheName() + "Spoolled element to disk: " +
element.getKey());
}
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-jcs-dev-help@jakarta.apache.org