You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by co...@apache.org on 2002/01/10 16:57:18 UTC
cvs commit: jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/cache FlipSpacesCacheStore.java
colus 02/01/10 07:57:18
Added: src/scratchpad/org/apache/avalon/excalibur/cache
FlipSpacesCacheStore.java
Log:
Added FlipSpacesCacheStore.
Submitted by: Larry Mccacy (lawrence_mccay-iii@hp.com)
Revision Changes Path
1.1 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/cache/FlipSpacesCacheStore.java
Index: FlipSpacesCacheStore.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.avalon.excalibur.cache;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author <a href="mailto:lawrence_mccay-iii@hp.com">Larry McCay</a>
*/
public class FlipSpacesCacheStore
extends AbstractCacheStore
{
/**
* the data space which stores the most recently accessed objects
*/
private Map m_newCache = null;
/**
* the data space which stores accessed items which have not been accessed since the last space swap. At the time
* <code>copySpaces</code> is called, objects still stored within this space are removed from the cache.
*/
private Map m_oldCache = null;
/**
* the size at which the cache is deemed to be full
*/
private int m_capacity;
/**
* Sets up the data spaces and sets the capacity of the cache
*
* @param capacity - the size at which the cache is deemed full
*/
public FlipSpacesCacheStore( final int capacity )
{
if ( capacity < 1 ) throw new IllegalArgumentException( "Specified capacity must be at least 1" );
m_capacity = capacity;
m_newCache = new HashMap( m_capacity );
m_oldCache = new HashMap( m_capacity );
}
/**
* Puts a given name value pair into the newCache.
* By invoking a get for the Object associated with the name before doing the actual put - we insure that the
* name value pair lives in the newCache data space. After executing the put - we determine if the cache is full
* - if so swap the data spaces - effectively clearing the newCache.
*
* @param key - name or key of the Object to be cached
* @param value - the actual cached Object
* @return the Object previously associated with the given name or key
*/
public Object put( final Object key, final Object value )
{
Object old = null;
get( key );
old = m_newCache.put( key, value );
if ( isFull() ) // cache full?
{
copySpaces();
}
return old;
}
/**
* Removes the Object associated with the given name from the both spaces of this cache store.
* By doing a get before removing the object we insure that the object if in the cache has been moved to the newCache
*
* @param key - name or key associated with the Object to be removed
* @return the removed Object
*/
public Object remove( final Object key )
{
Object cr = get( key );
return m_newCache.remove( key );
}
/**
* Gets the cached object associated with the given name.
* If the object does not exist within the newCache the old is checked. If the cache is determined to be full
* the spaces are swapped - effectively clearing the newCache. The object is then put into the newCache.
*
* @param key - the name or key of the requested object
* @return the requested Object
*/
public Object get( final Object key )
{
Object value = null;
if ( m_newCache.containsKey( key ) )
{
value = m_newCache.get( key ); // try new space
}
else
{
if ( m_oldCache.containsKey( key ) )
{
value = m_oldCache.get( key ); // try old space
if ( isFull() ) // cache full?
{
copySpaces();
}
m_oldCache.remove( key ); // remove from old space
m_newCache.put( key, value ); // move to new space
}
}
return value;
}
/**
* Erase the oldCache - releasing those objects that are still considered old by the time the newCache has been
* determined to be full. Move the newCache to old and the previously oldCache to newCache effectively clearing
* it. Over time accessing objects will move them from the oldCache to the newCache leaving those objects behind
* that shall be cleared as the newCache is determined to be full again.
*/
private void copySpaces()
{
m_oldCache.clear(); // erase old space
final Map temp = m_oldCache; // flip spaces
m_oldCache = m_newCache;
m_newCache = temp;
}
/**
* Gets the current size of the newCache.
* @return newCacheSize
*/
public int size()
{
return m_newCache.size();
}
/**
* Gets the capacity for the cache. Once the cache size has reached the capacity it is considered full.
* @return cache capacity
*/
public int capacity()
{
return m_capacity;
}
/**
* Checks if a given key exists within either of the spaces - old and new Caches.
* @return true if the key exists within this cache
*/
public boolean containsKey( final Object key )
{
boolean rc = m_newCache.containsKey( key );
if ( !rc )
{
rc = m_oldCache.containsKey( key );
}
return rc;
}
/**
* Gets array of keys from both caches or spaces.
* @return array of all the keys within this cache
*/
public Object[] keys()
{
final Set newKeys = m_newCache.keySet();
final Set oldKeys = m_oldCache.keySet();
final ArrayList keys = new ArrayList( newKeys );
keys.addAll( oldKeys );
return keys.toArray();
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>