svn commit: r783765 - in /jakarta/jcs/trunk/src: java/org/apache/jcs/access/exception/ java/org/apache/jcs/access/monitor/ java/org/apache/jcs/auxiliary/disk/ java/org/apache/jcs/auxiliary/disk/indexed/ java/org/apache/jcs/engine/ java/org/apache/jcs/e...
[email protected] Thu, 11 Jun 2009 13:46:35 -0000
| Newsgroups | gmane.comp.jakarta.turbine.jcs.devel |
|---|---|
| Message-ID | <[email protected]> |
Author: asmuts
Date: Thu Jun 11 13:46:34 2009
New Revision: 783765
URL: http://svn.apache.org/viewvc?rev=783765&view=rev
Log:
Cleaning up: Removing unused code. Adding unit tests.
Added:
jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCache.java
jakarta/jcs/trunk/src/test-conf/TestLHMLRUCache.ccf
jakarta/jcs/trunk/src/test/org/apache/jcs/TestLogConfigurationUtil.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/AbstractDiskCacheUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/LRUMapJCSUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/PurgatoryElementUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheConcurrentUnitTest.java
jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheUnitTest.java
Removed:
jakarta/jcs/trunk/src/java/org/apache/jcs/access/exception/NotARetrievableObjectException.java
jakarta/jcs/trunk/src/java/org/apache/jcs/access/exception/NullObjectException.java
jakarta/jcs/trunk/src/java/org/apache/jcs/access/monitor/MonitorAccess.java
jakarta/jcs/trunk/src/java/org/apache/jcs/access/monitor/MonitorXMLRPCServer.java
Modified:
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java
jakarta/jcs/trunk/src/java/org/apache/jcs/engine/CacheEventQueueFactory.java
jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCacheManager.java
jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java
jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java
jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LRUMemoryCacheConcurrentUnitTest.java
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCache.java Thu Jun 11 13:46:34 2009
@@ -71,7 +71,7 @@
private static final Log log = LogFactory.getLog( AbstractDiskCache.class );
/** Generic disk cache attributes */
- private IDiskCacheAttributes dcattr = null;
+ private IDiskCacheAttributes diskCacheAttributes = null;
/**
* Map where elements are stored between being added to this cache and actually spooled to disk.
@@ -89,7 +89,10 @@
*/
protected ICacheEventQueue cacheEventQueue;
- /** Indicates whether the cache is 'alive': initialized, but not yet disposed. */
+ /**
+ * Indicates whether the cache is 'alive': initialized, but not yet disposed. Child classes must
+ * set this to true.
+ */
protected boolean alive = false;
/** Every cache will have a name, subclasses must set this when they are initialized. */
@@ -107,20 +110,22 @@
// ----------------------------------------------------------- constructors
/**
- * Construct the abstract disk cache, create event queues and purgatory.
+ * Construct the abstract disk cache, create event queues and purgatory. Child classes should
+ * set the alive flag to true after they are initialized.
* <p>
* @param attr
*/
public AbstractDiskCache( IDiskCacheAttributes attr )
{
- this.dcattr = attr;
+ this.diskCacheAttributes = attr;
this.cacheName = attr.getCacheName();
// create queue
CacheEventQueueFactory fact = new CacheEventQueueFactory();
this.cacheEventQueue = fact.createCacheEventQueue( new MyCacheListener(), CacheInfo.listenerId, cacheName,
- dcattr.getEventQueuePoolName(), dcattr.getEventQueueType() );
+ diskCacheAttributes.getEventQueuePoolName(),
+ diskCacheAttributes.getEventQueueType() );
// create purgatory
initPurgatory();
@@ -146,9 +151,9 @@
{
synchronized ( purgatory )
{
- if ( dcattr.getMaxPurgatorySize() >= 0 )
+ if ( diskCacheAttributes.getMaxPurgatorySize() >= 0 )
{
- purgatory = new LRUMapJCS( dcattr.getMaxPurgatorySize() );
+ purgatory = new LRUMapJCS( diskCacheAttributes.getMaxPurgatorySize() );
}
else
{
@@ -158,9 +163,9 @@
}
else
{
- if ( dcattr.getMaxPurgatorySize() >= 0 )
+ if ( diskCacheAttributes.getMaxPurgatorySize() >= 0 )
{
- purgatory = new LRUMapJCS( dcattr.getMaxPurgatorySize() );
+ purgatory = new LRUMapJCS( diskCacheAttributes.getMaxPurgatorySize() );
}
else
{
@@ -240,6 +245,10 @@
if ( !alive )
{
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "get was called, but the disk cache is not alive." );
+ }
return null;
}
@@ -430,7 +439,7 @@
public final void removeAll()
throws IOException
{
- if ( this.dcattr.isAllowRemoveAll() )
+ if ( this.diskCacheAttributes.isAllowRemoveAll() )
{
// Replace purgatory with a new empty hashtable
initPurgatory();
@@ -492,7 +501,7 @@
// wait up to 60 seconds for dispose and then quit if not done.
try
{
- t.join( this.dcattr.getShutdownSpoolTimeLimit() * 1000 );
+ t.join( this.diskCacheAttributes.getShutdownSpoolTimeLimit() * 1000 );
}
catch ( InterruptedException ex )
{
@@ -763,10 +772,10 @@
/**
* Before the event logging layer, the subclasses implemented the do* methods. Now the do*
- * methods call the *WithEventLogging method on the super. The *WithEventLogging methods call the
- * abstract process* methods. The children implement the process methods.
+ * methods call the *WithEventLogging method on the super. The *WithEventLogging methods call
+ * the abstract process* methods. The children implement the process methods.
* <p>
- * ex. doGet calls getWithEventLogging, which calls processGet
+ * ex. doGet calls getWithEventLogging, which calls processGet
*/
/**
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java Thu Jun 11 13:46:34 2009
@@ -160,9 +160,10 @@
{
StringBuffer str = new StringBuffer();
str.append( "AbstractDiskCacheAttributes " );
- str.append( "\n diskPath = " + diskPath );
- str.append( "\n maxPurgatorySize = " + maxPurgatorySize );
- str.append( "\n allowRemoveAll = " + allowRemoveAll );
+ str.append( "\n diskPath = " + getDiskPath() );
+ str.append( "\n maxPurgatorySize = " + getMaxPurgatorySize() );
+ str.append( "\n allowRemoveAll = " + isAllowRemoveAll() );
+ str.append( "\n ShutdownSpoolTimeLimit = " + getShutdownSpoolTimeLimit() );
return str.toString();
}
}
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/PurgatoryElement.java Thu Jun 11 13:46:34 2009
@@ -128,4 +128,21 @@
{
cacheElement.setElementAttributes( attr );
}
+
+ /**
+ * @return debug string
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "[PurgatoryElement: " );
+ buf.append( " isSpoolable = " + isSpoolable() );
+ buf.append( " CacheElement = " + getCacheElement() );
+ buf.append( " CacheName = " + getCacheName() );
+ buf.append( " Key = " + getKey() );
+ buf.append( " Value = " + getVal() );
+ buf.append( " ElementAttributes = " + getElementAttributes() );
+ buf.append( "]" );
+ return buf.toString();
+ }
}
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/indexed/IndexedDiskElementDescriptor.java Thu Jun 11 13:46:34 2009
@@ -38,24 +38,6 @@
public int len;
/**
- * Set the offset (i.e. position, and the size of the element)
- * <p>
- * @param pos
- * @param data
- */
- public void init( long pos, byte[] data )
- {
- this.pos = pos;
- this.len = data.length;
- }
-
- /** Constructor for the DiskElementDescriptor object */
- public IndexedDiskElementDescriptor()
- {
- super();
- }
-
- /**
* Constructs a usable disk element descriptor.
* <p>
* @param pos
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/CacheEventQueueFactory.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/CacheEventQueueFactory.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/CacheEventQueueFactory.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/CacheEventQueueFactory.java Thu Jun 11 13:46:34 2009
@@ -74,7 +74,7 @@
}
ICacheEventQueue eventQueue = null;
- if ( ICacheEventQueue.SINGLE_QUEUE_TYPE.equalsIgnoreCase( poolType ) )
+ if ( poolType == null || ICacheEventQueue.SINGLE_QUEUE_TYPE.equalsIgnoreCase( poolType ) )
{
eventQueue = new CacheEventQueue( listener, listenerId, cacheName, maxFailure, waitBeforeRetry );
}
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCacheManager.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCacheManager.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCacheManager.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/control/CompositeCacheManager.java Thu Jun 11 13:46:34 2009
@@ -114,6 +114,7 @@
* Gets the CacheHub instance. For backward compatibility, if this creates the instance it will
* attempt to configure it with the default configuration. If you want to configure from your
* own source, use {@link #getUnconfiguredInstance}and then call {@link #configure}
+ * <p>
* @return CompositeCacheManager
*/
public static synchronized CompositeCacheManager getInstance()
@@ -134,6 +135,7 @@
/**
* Initializes the cache manager using the props file for the given name.
+ * <p>
* @param propsFilename
* @return CompositeCacheManager configured from the give propsFileName
*/
@@ -182,6 +184,7 @@
/**
* Simple factory method, must override in subclasses so getInstance creates / returns the
* correct object.
+ * <p>
* @return CompositeCacheManager
*/
protected static CompositeCacheManager createInstance()
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/AbstractMemoryCache.java Thu Jun 11 13:46:34 2009
@@ -107,7 +107,6 @@
}
shrinkerDaemon.executePeriodically( cattr.getShrinkerIntervalSeconds() * 1000, new ShrinkerThread( this ),
false );
-
}
}
Added: jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCache.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCache.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCache.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCache.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,390 @@
+package org.apache.jcs.engine.memory.lru;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.ArrayList;
+import java.util.Collections;
+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.control.group.GroupAttrName;
+import org.apache.jcs.engine.control.group.GroupId;
+import org.apache.jcs.engine.memory.AbstractMemoryCache;
+import org.apache.jcs.engine.memory.util.MemoryElementDescriptor;
+import org.apache.jcs.engine.stats.StatElement;
+import org.apache.jcs.engine.stats.Stats;
+import org.apache.jcs.engine.stats.behavior.IStatElement;
+import org.apache.jcs.engine.stats.behavior.IStats;
+
+/**
+ * This is a test memory manager using the jdk1.4 LinkedHashMap. There may be some thread safety
+ * issues.
+ */
+public class LHMLRUMemoryCache
+ extends AbstractMemoryCache
+{
+ /** Don't change */
+ private static final long serialVersionUID = 6403738094136424101L;
+
+ /** The Logger. */
+ private final static Log log = LogFactory.getLog( LRUMemoryCache.class );
+
+ /** number of hits */
+ protected int hitCnt = 0;
+
+ /** number of misses */
+ protected int missCnt = 0;
+
+ /** number of puts */
+ protected int putCnt = 0;
+
+ /**
+ * For post reflection creation initialization
+ * <p>
+ * @param hub
+ */
+ public synchronized void initialize( CompositeCache hub )
+ {
+ super.initialize( hub );
+ log.info( "initialized LHMLRUMemoryCache for " + cacheName );
+ }
+
+ /**
+ * Returns a synchronized LHMSpooler
+ * <p>
+ * @return Collections.synchronizedMap( new LHMSpooler() )
+ */
+ public Map createMap()
+ {
+ return Collections.synchronizedMap( new LHMSpooler() );
+ }
+
+ /**
+ * Puts an item to the cache.
+ * <p>
+ * @param ce Description of the Parameter
+ * @exception IOException
+ */
+ public void update( ICacheElement ce )
+ throws IOException
+ {
+ putCnt++;
+ ce.getElementAttributes().setLastAccessTimeNow();
+ map.put( ce.getKey(), ce );
+ }
+
+ /**
+ * Get an item from the cache without affecting its last access time or position. There is no
+ * way to do this with the LinkedHashMap!
+ * <p>
+ * @param key Identifies item to find
+ * @return Element matching key if found, or null
+ * @exception IOException
+ */
+ public ICacheElement getQuiet( Serializable key )
+ throws IOException
+ {
+ return (ICacheElement) map.get( key );
+ }
+
+ /**
+ * Get an item from the cache
+ * <p>
+ * @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 )
+ {
+ hitCnt++;
+ ce.getElementAttributes().setLastAccessTimeNow();
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( cacheName + ": LRUMemoryCache hit for " + key );
+ }
+ }
+ else
+ {
+ missCnt++;
+ 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.
+ * <p>
+ * @param key
+ * @return true if removed
+ * @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 );
+ if ( ce != null )
+ {
+ removed = true;
+ }
+ }
+
+ return removed;
+ }
+
+ /**
+ * Get an Array of the keys for all elements in the memory cache
+ * <p>
+ * @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();
+ }
+ }
+
+ /**
+ * This returns semi-structured information on the memory cache, such as the size, put count,
+ * hit count, and miss count.
+ * <p>
+ * @return IStats
+ */
+ public synchronized IStats getStatistics()
+ {
+ IStats stats = new Stats();
+ stats.setTypeName( "LHMLRU Memory Cache" );
+
+ ArrayList elems = new ArrayList();
+
+ IStatElement se = null;
+
+ se = new StatElement();
+ se.setName( "Map Size" );
+ se.setData( "" + map.size() );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Put Count" );
+ se.setData( "" + putCnt );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Hit Count" );
+ se.setData( "" + hitCnt );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Miss Count" );
+ se.setData( "" + missCnt );
+ elems.add( se );
+
+ // get an array and put them in the Stats object
+ IStatElement[] ses = (IStatElement[]) elems.toArray( new StatElement[0] );
+ stats.setStatElements( ses );
+
+ // int rate = ((hitCnt + missCnt) * 100) / (hitCnt * 100) * 100;
+ // buf.append("\n Hit Rate = " + rate + " %" );
+
+ return stats;
+ }
+
+ // ---------------------------------------------------------- debug methods
+
+ /**
+ * Dump the cache map for debugging.
+ */
+ public void dumpMap()
+ {
+ if ( log.isDebugEnabled() )
+ {
+ 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 last for debugging.
+ */
+ public void dumpCacheEntries()
+ {
+ dumpMap();
+ }
+
+ /**
+ * This can't be implemented.
+ * <p>
+ * @param numberToFree
+ * @return 0
+ * @throws IOException
+ */
+ public int freeElements( int numberToFree )
+ throws IOException
+ {
+ // can't be implemented using the LHM
+ return 0;
+ }
+
+ // ---------------------------------------------------------- extended map
+
+ /**
+ * Implementation of removeEldestEntry in LinkedHashMap
+ */
+ public class LHMSpooler
+ extends java.util.LinkedHashMap
+ {
+ /** Don't change. */
+ private static final long serialVersionUID = -1255907868906762484L;
+
+ /**
+ * Initialize to a small size--for now, 1/2 of max 3rd variable "true" indicates that it
+ * should be access and not time governed. This could be configurable.
+ */
+ public LHMSpooler()
+ {
+ super( (int) ( cache.getCacheAttributes().getMaxObjects() * .5 ), .75F, true );
+ }
+
+ /**
+ * Remove eldest. Automatically called by LinkedHashMap.
+ * <p>
+ * @param eldest
+ * @return true if removed
+ */
+ 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
+ * <p>
+ * @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() );
+ }
+ }
+ }
+}
Modified: jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java (original)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/utils/struct/LRUMap.java Thu Jun 11 13:46:34 2009
@@ -661,4 +661,12 @@
// TODO fix this, it needs to return the keys inside the wrappers.
return map.keySet();
}
+
+ /**
+ * @return the max objects size.
+ */
+ public int getMaxObjects()
+ {
+ return maxObjects;
+ }
}
Added: jakarta/jcs/trunk/src/test-conf/TestLHMLRUCache.ccf
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test-conf/TestLHMLRUCache.ccf?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test-conf/TestLHMLRUCache.ccf (added)
+++ jakarta/jcs/trunk/src/test-conf/TestLHMLRUCache.ccf Thu Jun 11 13:46:34 2009
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+# Cache configuration for the 'TestDiskCache' test. The memory cache has a
+# a maximum of 100 objects, so objects should get pushed into the disk cache
+
+jcs.default=
+jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
+jcs.default.cacheattributes.MaxObjects=100
+jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LHMLRUMemoryCache
\ No newline at end of file
Added: jakarta/jcs/trunk/src/test/org/apache/jcs/TestLogConfigurationUtil.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/TestLogConfigurationUtil.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/TestLogConfigurationUtil.java (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/TestLogConfigurationUtil.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,27 @@
+package org.apache.jcs;
+
+import java.io.StringWriter;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.WriterAppender;
+
+/** Utility for testing log messages. */
+public class TestLogConfigurationUtil
+{
+ /**
+ * Configures a logger for the given name. This allows us to check the log output.
+ * <p>
+ * @param stringWriter string writer
+ * @param loggerName logger name
+ */
+ public static void configureLogger( StringWriter stringWriter, String loggerName )
+ {
+ Logger logger = Logger.getLogger( loggerName );
+ WriterAppender appender = new WriterAppender( new PatternLayout(), stringWriter );
+
+ logger.addAppender( appender );
+ logger.setLevel( Level.DEBUG );
+ }
+}
Added: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/AbstractDiskCacheUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/AbstractDiskCacheUnitTest.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/AbstractDiskCacheUnitTest.java (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/AbstractDiskCacheUnitTest.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,274 @@
+package org.apache.jcs.auxiliary.disk;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.TestLogConfigurationUtil;
+import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
+import org.apache.jcs.auxiliary.disk.behavior.IDiskCacheAttributes;
+import org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes;
+import org.apache.jcs.engine.CacheConstants;
+import org.apache.jcs.engine.CacheElement;
+import org.apache.jcs.engine.ElementAttributes;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.behavior.IElementAttributes;
+
+/** Tests for the abstract disk cache. It's largely tested by actual instances. */
+public class AbstractDiskCacheUnitTest
+ extends TestCase
+{
+ /**
+ * Verify that update and get work.
+ * <p>
+ * @throws IOException
+ */
+ public void testUpdateGet_allowed()
+ throws IOException
+ {
+ // SETUP
+ String cacheName = "testUpdateGet_allowed";
+ IDiskCacheAttributes diskCacheAttributes = new IndexedDiskCacheAttributes();
+ diskCacheAttributes.setCacheName( cacheName );
+
+ AbstractDiskCacheTestInstance diskCache = new AbstractDiskCacheTestInstance( diskCacheAttributes );
+
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value, elementAttributes );
+
+ diskCache.update( cacheElement );
+
+ // DO WORK
+ ICacheElement result = diskCache.get( key );
+
+ // VERIFY
+ //System.out.println( diskCache.getStats() );
+ assertNotNull( "Item should be in the map.", result );
+ }
+
+ /**
+ * Verify that alive is set to false..
+ * <p>
+ * @throws IOException
+ */
+ public void testDispose()
+ throws IOException
+ {
+ // SETUP
+ String cacheName = "testDispose";
+ IDiskCacheAttributes diskCacheAttributes = new IndexedDiskCacheAttributes();
+ diskCacheAttributes.setCacheName( cacheName );
+
+ AbstractDiskCacheTestInstance diskCache = new AbstractDiskCacheTestInstance( diskCacheAttributes );
+
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value, elementAttributes );
+
+ diskCache.update( cacheElement );
+
+ // DO WORK
+ diskCache.dispose();
+
+ // VERIFY
+ assertFalse( "disk cache should not be alive.", diskCache.alive );
+ assertEquals( "Status should be disposed", CacheConstants.STATUS_DISPOSED, diskCache.getStatus() );
+ }
+
+ /**
+ * Verify that removeAll is prohibited.
+ * <p>
+ * @throws IOException
+ */
+ public void testRemoveAll_notAllowed()
+ throws IOException
+ {
+ // SETUP
+ StringWriter stringWriter = new StringWriter();
+ TestLogConfigurationUtil.configureLogger( stringWriter, AbstractDiskCache.class.getName() );
+
+ IDiskCacheAttributes diskCacheAttributes = new IndexedDiskCacheAttributes();
+ diskCacheAttributes.setAllowRemoveAll( false );
+
+ AbstractDiskCacheTestInstance diskCache = new AbstractDiskCacheTestInstance( diskCacheAttributes );
+
+ String cacheName = "testRemoveAll_notAllowed";
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value, elementAttributes );
+
+ diskCache.update( cacheElement );
+
+ // DO WORK
+ diskCache.removeAll();
+ String result = stringWriter.toString();
+
+ // VERIFY
+ assertTrue( "Should say not allowed.", result.indexOf( "set to false" ) != -1 );
+ assertNotNull( "Item should be in the map.", diskCache.get( key ) );
+ }
+
+ /**
+ * Verify that removeAll is allowed.
+ * <p>
+ * @throws IOException
+ */
+ public void testRemoveAll_allowed()
+ throws IOException
+ {
+ // SETUP
+ IDiskCacheAttributes diskCacheAttributes = new IndexedDiskCacheAttributes();
+ diskCacheAttributes.setAllowRemoveAll( true );
+
+ AbstractDiskCacheTestInstance diskCache = new AbstractDiskCacheTestInstance( diskCacheAttributes );
+
+ String cacheName = "testRemoveAll_allowed";
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value, elementAttributes );
+
+ diskCache.update( cacheElement );
+
+ // DO WORK
+ diskCache.removeAll();
+
+ // VERIFY
+ assertNull( "Item should not be in the map.", diskCache.get( key ) );
+ }
+
+ /** Concrete, testable instance. */
+ class AbstractDiskCacheTestInstance
+ extends AbstractDiskCache
+ {
+ /** Internal map */
+ protected Map map = new HashMap();
+
+ /** used by the abstract aux class */
+ protected IDiskCacheAttributes diskCacheAttributes;
+
+ /**
+ * Creates the disk cache.
+ * <p>
+ * @param attr
+ */
+ public AbstractDiskCacheTestInstance( IDiskCacheAttributes attr )
+ {
+ super( attr );
+ diskCacheAttributes = attr;
+ super.alive = true;
+ }
+
+ /** Nothing. */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The location on disk
+ * <p>
+ * @return "memory"
+ */
+ protected String getDiskLocation()
+ {
+ return "memory";
+ }
+
+ /**
+ * @param groupName
+ * @return Collections.EMPTY_SET
+ */
+ public Set getGroupKeys( String groupName )
+ {
+ return Collections.EMPTY_SET;
+ }
+
+ /**
+ * @return map.size()
+ */
+ public int getSize()
+ {
+ return map.size();
+ }
+
+ /**
+ * @throws IOException
+ */
+ protected void processDispose()
+ throws IOException
+ {
+ //System.out.println( "processDispose" );
+ }
+
+ /**
+ * @param key
+ * @return ICacheElement
+ * @throws IOException
+ */
+ protected ICacheElement processGet( Serializable key )
+ throws IOException
+ {
+ //System.out.println( "processGet: " + key );
+ return (ICacheElement) map.get( key );
+ }
+
+ /**
+ * @param pattern
+ * @return Collections.EMPTY_MAP
+ * @throws IOException
+ */
+ protected Map processGetMatching( String pattern )
+ throws IOException
+ {
+ return Collections.EMPTY_MAP;
+ }
+
+ /**
+ * @param key
+ * @return false
+ * @throws IOException
+ */
+ protected boolean processRemove( Serializable key )
+ throws IOException
+ {
+ return map.remove( key ) != null;
+ }
+
+ /**
+ * @throws IOException
+ */
+ protected void processRemoveAll()
+ throws IOException
+ {
+ //System.out.println( "processRemoveAll" );
+ map.clear();
+ }
+
+ /**
+ * @param cacheElement
+ * @throws IOException
+ */
+ protected void processUpdate( ICacheElement cacheElement )
+ throws IOException
+ {
+ //System.out.println( "processUpdate: " + cacheElement );
+ map.put( cacheElement.getKey(), cacheElement );
+ }
+
+ /**
+ * @return null
+ */
+ public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
+ {
+ return diskCacheAttributes;
+ }
+ }
+}
Added: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/LRUMapJCSUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/LRUMapJCSUnitTest.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/LRUMapJCSUnitTest.java (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/LRUMapJCSUnitTest.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,58 @@
+package org.apache.jcs.auxiliary.disk;
+
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.TestLogConfigurationUtil;
+
+/** Unit tests for the LRUMapJCS implementation. */
+public class LRUMapJCSUnitTest
+ extends TestCase
+{
+ /** Verify that we default to unlimited */
+ public void testDefault()
+ {
+ // SETUP
+
+ // DO WORK
+ LRUMapJCS map = new LRUMapJCS();
+
+ // VERIFY
+ assertEquals( "Should be unlimted", -1, map.getMaxObjects() );
+ }
+
+ /** Verify that we default to unlimited */
+ public void testLimited()
+ {
+ // SETUP
+ int expected = 100;
+
+ // DO WORK
+ LRUMapJCS map = new LRUMapJCS( expected );
+
+ // VERIFY
+ assertEquals( "Should be expected", expected, map.getMaxObjects() );
+ }
+
+ /** Verify that the log message. */
+ public void testProcessRemovedLRU()
+ {
+ // SETUP
+ StringWriter stringWriter = new StringWriter();
+ TestLogConfigurationUtil.configureLogger( stringWriter, LRUMapJCS.class.getName() );
+
+ LRUMapJCS map = new LRUMapJCS();
+
+ String key = "myKey";
+ String value = "myValue";
+
+ // DO WORK
+ map.processRemovedLRU( key, value );
+ String result = stringWriter.toString();
+
+ // VERIFY
+ assertTrue( "Debug log should contain the key,", result.indexOf( key ) != -1 );
+ assertTrue( "Debug log should contain the value,", result.indexOf( value ) != -1 );
+ }
+}
Added: jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/PurgatoryElementUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/PurgatoryElementUnitTest.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/PurgatoryElementUnitTest.java (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/auxiliary/disk/PurgatoryElementUnitTest.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,72 @@
+package org.apache.jcs.auxiliary.disk;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.engine.CacheElement;
+import org.apache.jcs.engine.ElementAttributes;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.behavior.IElementAttributes;
+
+/** Simple unit tests for the Purgatory Element. */
+public class PurgatoryElementUnitTest
+ extends TestCase
+{
+ /** Verify basic data */
+ public void testSpoolable_normal()
+ {
+ // SETUP
+ String cacheName = "myCacheName";
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value, elementAttributes );
+ PurgatoryElement purgatoryElement = new PurgatoryElement( cacheElement );
+ purgatoryElement.setSpoolable( false );
+
+ // DO WORK
+ boolean result = purgatoryElement.isSpoolable();
+
+ // VERIFY
+ assertFalse( "Should not be spoolable.", result );
+ }
+
+ /** Verify basic data */
+ public void testElementAttributes_normal()
+ {
+ // SETUP
+ String cacheName = "myCacheName";
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value );
+ PurgatoryElement purgatoryElement = new PurgatoryElement( cacheElement );
+ purgatoryElement.setElementAttributes( elementAttributes );
+
+ // DO WORK
+ IElementAttributes result = cacheElement.getElementAttributes();
+
+ // VERIFY
+ assertEquals( "Should have set the attributes on the element", elementAttributes, result );
+ }
+
+ /** Verify basic data */
+ public void testToString_normal()
+ {
+ // SETUP
+ String cacheName = "myCacheName";
+ String key = "myKey";
+ String value = "myValue";
+ IElementAttributes elementAttributes = new ElementAttributes();
+ ICacheElement cacheElement = new CacheElement( cacheName, key, value, elementAttributes );
+ PurgatoryElement purgatoryElement = new PurgatoryElement( cacheElement );
+
+ // DO WORK
+ String result = purgatoryElement.toString();
+
+ // VERIFY
+ assertTrue( "Should have the cacheName.", result.indexOf( cacheName ) != -1 );
+ assertTrue( "Should have the key.", result.indexOf( key ) != -1 );
+ assertTrue( "Should have the value.", result.indexOf( value ) != -1 );
+ }
+}
Added: jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheConcurrentUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheConcurrentUnitTest.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheConcurrentUnitTest.java (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheConcurrentUnitTest.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,174 @@
+package org.apache.jcs.engine.memory.lru;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import junit.extensions.ActiveTestSuite;
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+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.control.CompositeCacheManager;
+
+/**
+ * Test which exercises the LRUMemory cache. This one uses three different
+ * regions for three threads.
+ */
+public class LHMLRUMemoryCacheConcurrentUnitTest
+ extends TestCase
+{
+ /**
+ * Number of items to cache, twice the configured maxObjects for the memory
+ * cache regions.
+ */
+ private static int items = 200;
+
+ /**
+ * Constructor for the TestDiskCache object.
+ *
+ * @param testName
+ */
+ public LHMLRUMemoryCacheConcurrentUnitTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * Main method passes this test to the text test runner.
+ *
+ * @param args
+ */
+ public static void main( String args[] )
+ {
+ String[] testCaseName = { LHMLRUMemoryCacheConcurrentUnitTest.class.getName() };
+ junit.textui.TestRunner.main( testCaseName );
+ }
+
+ /**
+ * A unit test suite for JUnit
+ * <p>
+ * @return The test suite
+ */
+ public static Test suite()
+ {
+ ActiveTestSuite suite = new ActiveTestSuite();
+
+ suite.addTest( new LHMLRUMemoryCacheConcurrentUnitTest( "testLHMLRUMemoryCache" )
+ {
+ public void runTest()
+ throws Exception
+ {
+ this.runTestForRegion( "indexedRegion1" );
+ }
+ } );
+
+ return suite;
+ }
+
+ /**
+ * Test setup
+ */
+ public void setUp()
+ {
+ //JCS.setConfigFilename( "/TestLHMLRUCache.ccf" );
+ }
+
+ /**
+ * Adds items to cache, gets them, and removes them. The item count is more
+ * than the size of the memory cache, so items should be dumped.
+ * <p>
+ * @param region
+ * Name of the region to access
+ *
+ * @exception Exception
+ * If an error occurs
+ */
+ public void runTestForRegion( String region )
+ throws Exception
+ {
+ CompositeCacheManager cacheMgr = CompositeCacheManager.getUnconfiguredInstance();
+ cacheMgr.configure( "/TestLHMLRUCache.ccf" );
+ CompositeCache cache = cacheMgr.getCache( region );
+
+ LRUMemoryCache lru = new LRUMemoryCache();
+ lru.initialize( cache );
+
+ // Add items to cache
+
+ for ( int i = 0; i < items; i++ )
+ {
+ ICacheElement ice = new CacheElement( cache.getCacheName(), i + ":key", region + " data " + i );
+ ice.setElementAttributes( cache.getElementAttributes() );
+ lru.update( ice );
+ }
+
+ // Test that initial items have been purged
+ for ( int i = 0; i < 100; i++ )
+ {
+ assertNull( "Should not have " + i + ":key", lru.get( i + ":key" ) );
+ }
+
+ // Test that last items are in cache
+ for ( int i = 100; i < items; i++ )
+ {
+ String value = (String) lru.get( i + ":key" ).getVal();
+ assertEquals( region + " data " + i, value );
+ }
+
+ // Test that getMultiple returns all the items remaining in cache and none of the missing ones
+ Set keys = new HashSet();
+ for ( int i = 0; i < items; i++ )
+ {
+ keys.add( i + ":key" );
+ }
+
+ Map elements = lru.getMultiple( keys );
+ for ( int i = 0; i < 100; i++ )
+ {
+ assertNull( "Should not have " + i + ":key", elements.get( i + ":key" ) );
+ }
+ for ( int i = 100; i < items; i++ )
+ {
+ ICacheElement element = (ICacheElement) elements.get( i + ":key" );
+ assertNotNull( "element " + i + ":key is missing", element );
+ assertEquals( "value " + i + ":key", region + " data " + i, element.getVal() );
+ }
+
+ // Remove all the items
+
+ for ( int i = 0; i < items; i++ )
+ {
+ lru.remove( i + ":key" );
+ }
+
+ // Verify removal
+
+ for ( int i = 0; i < items; i++ )
+ {
+ assertNull( "Removed key should be null: " + i + ":key", lru.get( i + ":key" ) );
+ }
+ }
+
+}
Added: jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheUnitTest.java?rev=783765&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheUnitTest.java (added)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LHMLRUMemoryCacheUnitTest.java Thu Jun 11 13:46:34 2009
@@ -0,0 +1,311 @@
+package org.apache.jcs.engine.memory.lru;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.jcs.JCS;
+import org.apache.jcs.access.exception.CacheException;
+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.control.CompositeCacheManager;
+
+/**
+ * Tests for the test LHMLRU implementation.
+ * <p>
+ * @author Aaron Smuts
+ */
+public class LHMLRUMemoryCacheUnitTest
+ extends TestCase
+{
+ /** Test setup */
+ public void setUp()
+ {
+ JCS.setConfigFilename( "/TestLHMLRUCache.ccf" );
+ }
+
+ /**
+ * Verify that the mru gets used by a non-defined region when it is set as the default in the
+ * default region.
+ * <p>
+ * @throws CacheException
+ */
+ public void testLoadFromCCF()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testPutGet" );
+ String memoryCacheName = cache.getCacheAttributes().getMemoryCacheName();
+ assertTrue( "Cache name should have LHMLRU in it.", memoryCacheName.indexOf( "LHMLRUMemoryCache" ) != -1 );
+ }
+
+ /**
+ * put twice as many as the max. verify that the second half is in the cache.
+ * <p>
+ * @throws CacheException
+ */
+ public void testPutGetThroughHub()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testPutGetThroughHub" );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max * 2;
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( i + ":key", "myregion" + " data " + i );
+ }
+
+ // Test that first items are not in the cache
+ for ( int i = max -1; i >= 0; i-- )
+ {
+ String value = (String) cache.get( i + ":key" );
+ assertNull( "Should not have value for key [" + i + ":key" + "] in the cache." + cache.getStats(), value );
+ }
+
+ // Test that last items are in cache
+ // skip 2 for the buffer.
+ for ( int i = max + 2; i < items; i++ )
+ {
+ String value = (String) cache.get( i + ":key" );
+ assertEquals( "myregion" + " data " + i, value );
+ }
+
+ // Test that getMultiple returns all the items remaining in cache and none of the missing ones
+ Set keys = new HashSet();
+ for ( int i = 0; i < items; i++ )
+ {
+ keys.add( i + ":key" );
+ }
+
+ Map elements = cache.getCacheElements( keys );
+ for ( int i = max-1; i >= 0; i-- )
+ {
+ assertNull( "Should not have value for key [" + i + ":key" + "] in the cache." + cache.getStats(), elements.get( i + ":key" ) );
+ }
+ for ( int i = max + 2; i < items; i++ )
+ {
+ ICacheElement element = (ICacheElement) elements.get( i + ":key" );
+ assertNotNull( "element " + i + ":key is missing", element );
+ assertEquals( "value " + i + ":key", "myregion" + " data " + i, element.getVal() );
+ }
+ }
+
+ /**
+ * Put twice as many as the max, twice. verify that the second half is in the cache.
+ * <p>
+ * @throws CacheException
+ */
+ public void testPutGetThroughHubTwice()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testPutGetThroughHub" );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max * 2;
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( i + ":key", "myregion" + " data " + i );
+ }
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( i + ":key", "myregion" + " data " + i );
+ }
+
+ // Test that first items are not in the cache
+ for ( int i = max -1; i >= 0; i-- )
+ {
+ String value = (String) cache.get( i + ":key" );
+ assertNull( "Should not have value for key [" + i + ":key" + "] in the cache.", value );
+ }
+
+ // Test that last items are in cache
+ // skip 2 for the buffer.
+ for ( int i = max + 2; i < items; i++ )
+ {
+ String value = (String) cache.get( i + ":key" );
+ assertEquals( "myregion" + " data " + i, value );
+ }
+
+ }
+
+ /**
+ * put the max and remove each. verify that they are all null.
+ * <p>
+ * @throws CacheException
+ */
+ public void testPutRemoveThroughHub()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testPutGetThroughHub" );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max * 2;
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( i + ":key", "myregion" + " data " + i );
+ }
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.remove( i + ":key" );
+ }
+
+ // Test that first items are not in the cache
+ for ( int i = max; i >= 0; i-- )
+ {
+ String value = (String) cache.get( i + ":key" );
+ assertNull( "Should not have value for key [" + i + ":key" + "] in the cache.", value );
+ }
+ }
+
+ /**
+ * put the max and clear. verify that no elements remain.
+ * <p>
+ * @throws CacheException
+ */
+ public void testClearThroughHub()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testPutGetThroughHub" );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max * 2;
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( i + ":key", "myregion" + " data " + i );
+ }
+
+ cache.clear();
+
+ // Test that first items are not in the cache
+ for ( int i = max; i >= 0; i-- )
+ {
+ String value = (String) cache.get( i + ":key" );
+ assertNull( "Should not have value for key [" + i + ":key" + "] in the cache.", value );
+ }
+ }
+
+ /**
+ * Get stats.
+ * <p>
+ * @throws CacheException
+ */
+ public void testGetStatsThroughHub()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testGetStatsThroughHub" );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max * 2;
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( i + ":key", "myregion" + " data " + i );
+ }
+
+ String stats = cache.getStats();
+
+ //System.out.println( stats );
+
+ // TODO improve stats check
+ assertTrue( "Should have 200 puts" + stats, stats.indexOf( "200" ) != -1 );
+ }
+
+ /**
+ * Put half the max and clear. get the key array and verify that it has the correct number of
+ * items.
+ * <p>
+ * @throws Exception
+ */
+ public void testGetKeyArray()
+ throws Exception
+ {
+ CompositeCacheManager cacheMgr = CompositeCacheManager.getUnconfiguredInstance();
+ cacheMgr.configure( "/TestLHMLRUCache.ccf" );
+ CompositeCache cache = cacheMgr.getCache( "testGetKeyArray" );
+
+ LHMLRUMemoryCache mru = new LHMLRUMemoryCache();
+ mru.initialize( cache );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max / 2;
+
+ for ( int i = 0; i < items; i++ )
+ {
+ ICacheElement ice = new CacheElement( cache.getCacheName(), i + ":key", cache.getCacheName() + " data " + i );
+ ice.setElementAttributes( cache.getElementAttributes() );
+ mru.update( ice );
+ }
+
+ Object[] keys = mru.getKeyArray();
+
+ assertEquals( "Wrong number of keys.", items, keys.length );
+ }
+
+ /**
+ * Add a few keys with the delimeter. Remove them.
+ * <p>
+ * @throws CacheException
+ */
+ public void testRemovePartialThroughHub()
+ throws CacheException
+ {
+ JCS cache = JCS.getInstance( "testGetStatsThroughHub" );
+
+ int max = cache.getCacheAttributes().getMaxObjects();
+ int items = max / 2;
+
+ cache.put( "test", "data" );
+
+ String root = "myroot";
+
+ for ( int i = 0; i < items; i++ )
+ {
+ cache.put( root + ":" + i + ":key", "myregion" + " data " + i );
+ }
+
+ // Test that last items are in cache
+ for ( int i = 0; i < items; i++ )
+ {
+ String value = (String) cache.get( root + ":" + i + ":key" );
+ assertEquals( "myregion" + " data " + i, value );
+ }
+
+ // remove partial
+ cache.remove( root + ":" );
+
+ for ( int i = 0; i < items; i++ )
+ {
+ assertNull( "Should have been removed by partial loop.", cache.get( root + ":" + i + ":key" ) );
+ }
+
+ assertNotNull( "Other item should be in the cache.", cache.get( "test" ) );
+ }
+}
Modified: jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LRUMemoryCacheConcurrentUnitTest.java
URL: http://svn.apache.org/viewvc/jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LRUMemoryCacheConcurrentUnitTest.java?rev=783765&r1=783764&r2=783765&view=diff
==============================================================================
--- jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LRUMemoryCacheConcurrentUnitTest.java (original)
+++ jakarta/jcs/trunk/src/test/org/apache/jcs/engine/memory/lru/LRUMemoryCacheConcurrentUnitTest.java Thu Jun 11 13:46:34 2009
@@ -47,7 +47,7 @@
/**
* Constructor for the TestDiskCache object.
- *
+ * <p>
* @param testName
*/
public LRUMemoryCacheConcurrentUnitTest( String testName )
@@ -57,7 +57,7 @@
/**
* Main method passes this test to the text test runner.
- *
+ * <p>
* @param args
*/
public static void main( String args[] )
@@ -80,7 +80,7 @@
public void runTest()
throws Exception
{
- this.runTestForRegion( "indexedRegion1" );
+ this.runTestForRegion( "testRegion1" );
}
} );
@@ -101,7 +101,6 @@
* <p>
* @param region
* Name of the region to access
- *
* @exception Exception
* If an error occurs
*/
@@ -157,18 +156,15 @@
}
// Remove all the items
-
for ( int i = 0; i < items; i++ )
{
lru.remove( i + ":key" );
}
// Verify removal
-
for ( int i = 0; i < items; i++ )
{
assertNull( "Removed key should be null: " + i + ":key", lru.get( i + ":key" ) );
}
}
-
}