PR: MRM-39

Added javadoc annotations and improved Cache class

git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@356516 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Edwin L. Punzalan 2005-12-13 08:37:00 +00:00
parent 70bbe70782
commit 911feec6f7
3 changed files with 112 additions and 11 deletions

View File

@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.Map;
/**
* Class to implement caching
*
*/
public class Cache
@ -34,11 +35,26 @@ public class Cache
private long cacheHits = 0;
private long cacheMiss = 0;
/**
* Caches all data and expires only the oldest data when the specified cache hit rate is reached.
*/
public Cache( double cacheHitRatio )
{
this( cacheHitRatio, 0 );
}
/**
* Caches all data and expires only the oldest data when the maximum cache size is reached
*/
public Cache( long cacheMaxSize )
{
this( (double) 1, cacheMaxSize );
}
/**
* Caches all data and expires only the oldest data when either the specified cache hit rate is reached
* or the maximum cache size is reached.
*/
public Cache( double cacheHitRatio, long cacheMaxSize )
{
this.cacheHitRatio = cacheHitRatio;
@ -47,6 +63,36 @@ public class Cache
cache = new HashMap();
}
/**
* Check if the specified key is already mapped to an object.
*
* @param key the key used to map the cached object
*
* @returns true if the cache contains an object associated with the given key
*/
public boolean containsKey( Object key )
{
boolean contains = cache.containsKey( key );
if ( contains )
{
cacheHits++;
}
else
{
cacheMiss++;
}
return contains;
}
/**
* Check for a cached object and return it if it exists. Returns null when the keyed object is not found
*
* @param key the key used to map the cached object
*
* @returns the object mapped to the given key, or null if no cache object is mapped to the given key
*/
public Object get( Object key )
{
Object retValue = null;
@ -69,6 +115,12 @@ public class Cache
return retValue;
}
/**
* Cache the given value and map it using the given key
*
* @param key the object to map the valued object
* @param value the object to cache
*/
public void put( Object key, Object value )
{
DblLinkedList entry;
@ -86,16 +138,27 @@ public class Cache
makeMostRecent( entry );
}
/**
* Compute for the efficiency of this cache.
*
* @returns the ratio of cache hits to the cache misses to queries for cache objects
*/
public double getHitRate()
{
return ( cacheHits == 0 && cacheMiss == 0 ) ? 0 : ( (double) cacheHits ) / (double) ( cacheHits + cacheMiss );
}
/**
* Get the total number of cache objects currently cached.
*/
public long size()
{
return cache.size();
}
/**
* Empty the cache and reset the cache hit rate
*/
public void flush()
{
while ( cache.size() > 0 )
@ -135,7 +198,7 @@ public class Cache
{
if ( cacheMaxSize == 0 )
{
//if desired HitRatio is reached, we can trim the cache to conserve memory
//desired HitRatio is reached, we can trim the cache to conserve memory
if ( cacheHitRatio <= getHitRate() )
{
trimCache();
@ -143,12 +206,21 @@ public class Cache
}
else if ( cache.size() > cacheMaxSize )
{
//trim cache regardless of cacheHitRatio
// maximum cache size is reached
while( cache.size() > cacheMaxSize )
{
trimCache();
}
}
else
{
//even though the max has not been reached, the desired HitRatio is already reached,
// so we can trim the cache to conserve memory
if ( cacheHitRatio <= getHitRate() )
{
trimCache();
}
}
}
private void trimCache()

View File

@ -103,10 +103,4 @@ public class CachedRepositoryQueryLayer
return metadata;
}
private class DblLinkedList {
DblLinkedList prev;
Object cacheObject;
DblLinkedList next;
}
}

View File

@ -49,7 +49,7 @@ public class CacheTest
public void testCacheManagementBasedOnCacheSize()
{
cache = new Cache( 0.5, 9 );
cache = new Cache( 9 );
newCacheObjectTests();
String key = "key";
@ -64,6 +64,41 @@ public class CacheTest
assertEquals( "check cache size to be max size", 9, cache.size() );
}
public void testCacheManagementBasedOnCacheSizeAndHitRate()
{
cache = new Cache( 0.5, 9 );
newCacheObjectTests();
String key = "key";
String value = "value";
for( int ctr=1; ctr<5; ctr++ )
{
cache.put( key + ctr, value + ctr );
}
while ( cache.getHitRate() < 0.5 )
{
cache.get( "key3" );
}
cache.put( "key10", "value10");
assertNull( "first key must be expired", cache.get( "key1" ) );
while ( cache.getHitRate() >= 0.5 )
{
cache.get( "key11" );
}
for( int ctr=5; ctr<10; ctr++ )
{
cache.put( key + ctr, value + ctr );
}
cache.put( "key11", "value11");
assertNull( "second key must be expired", cache.get( "key2" ) );
assertEquals( "check cache size to be max size", 9, cache.size() );
}
public void testCacheOnRedundantData()
{
cache = new Cache( 0.5, 9 );