asmuts 2004/06/28 18:26:22
Modified: src/java/org/apache/jcs/engine/memory/lru
LRUMemoryCache.java
Log:
reverse order of delete,
Patch by Scott Jarvi
for ibm jvm
Revision Changes Path
1.24 +599 -586
jakarta-turbine-jcs/src/java/org/apache/jcs/engine/memory/lru/LRUMemoryCache.java
Index: LRUMemoryCache.java
===================================================================
RCS file:
/home/cvs/jakarta-turbine-jcs/src/java/org/apache/jcs/engine/memory/lru/LRUMemoryCache.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- LRUMemoryCache.java 12 Jun 2004 02:33:41 -0000 1.23
+++ LRUMemoryCache.java 29 Jun 2004 01:26:22 -0000 1.24
@@ -1,6 +1,5 @@
package org.apache.jcs.engine.memory.lru;
-
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
@@ -17,7 +16,6 @@
* limitations under the License.
*/
-
import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
@@ -50,689 +48,704 @@
public class LRUMemoryCache
extends AbstractMemoryCache
{
- private final static Log log =
- LogFactory.getLog( LRUMemoryCache.class );
+ private final static Log log =
+ LogFactory.getLog( LRUMemoryCache.class );
- // LRU double linked list head/tail nodes
- private MemoryElementDescriptor first;
- private MemoryElementDescriptor last;
-
- /**
- * For post reflection creation initialization
- *
- [EMAIL PROTECTED] hub
- */
- public synchronized void initialize( CompositeCache hub )
- {
- super.initialize(hub);
- log.info( "initialized LRUMemoryCache for " + cacheName );
- }
-
- /**
- * Puts an item to the cache.
- *
- [EMAIL PROTECTED] ce Description of the Parameter
- [EMAIL PROTECTED] IOException
- */
- public void update( ICacheElement ce )
- throws IOException
- {
- // Asynchronisly create a MemoryElement
-
- ce.getElementAttributes().setLastAccessTimeNow();
- addFirst( ce );
- MemoryElementDescriptor old =
- ( MemoryElementDescriptor ) map.put( first.ce.getKey(), first );
+ // LRU double linked list head/tail nodes
+ private MemoryElementDescriptor first;
+ private MemoryElementDescriptor last;
- // If the node was the same as an existing node, remove it.
+ /**
+ * For post reflection creation initialization
+ *
+ [EMAIL PROTECTED] hub
+ */
+ public synchronized void initialize( CompositeCache hub )
+ {
+ super.initialize( hub );
+ log.info( "initialized LRUMemoryCache for " + cacheName );
+ }
- if ( old != null && first.ce.getKey().equals( old.ce.getKey() ) )
- {
- removeNode( old );
- }
+ /**
+ * Puts an item to the cache.
+ *
+ [EMAIL PROTECTED] ce Description of the Parameter
+ [EMAIL PROTECTED] IOException
+ */
+ public void update( ICacheElement ce ) throws IOException
+ {
+ // Asynchronisly create a MemoryElement
- int size = map.size();
- // If the element limit is reached, we need to spool
+ ce.getElementAttributes().setLastAccessTimeNow();
+ addFirst( ce );
+ MemoryElementDescriptor old =
+ ( MemoryElementDescriptor ) map.put( first.ce.getKey(), first );
- if ( size < this.cattr.getMaxObjects() )
- {
- return;
- }
- log.debug( "In memory limit reached, spooling" );
+ // If the node was the same as an existing node, remove it.
- // Write the last 'chunkSize' items to disk.
+ if ( old != null && first.ce.getKey().equals( old.ce.getKey() ) )
+ {
+ removeNode( old );
+ }
- int chunkSizeCorrected = Math.min( size, chunkSize );
+ int size = map.size();
+ // If the element limit is reached, we need to spool
- if ( log.isDebugEnabled() )
- {
- log.debug( "About to spool to disk cache, map size: " + size
- + ", max objects: " + this.cattr.getMaxObjects()
- + ", items to spool: " + chunkSizeCorrected );
- }
+ if ( size < this.cattr.getMaxObjects() )
+ {
+ return;
+ }
+ log.debug( "In memory limit reached, spooling" );
- // The spool will put them in a disk event queue, so there is no
- // need to pre-queue the queuing. This would be a bit wasteful
- // and wouldn't save much time in this synchronous call.
+ // Write the last 'chunkSize' items to disk.
- for ( int i = 0; i < chunkSizeCorrected; i++ )
- {
- synchronized ( this )
- {
- if ( last != null )
- {
- if ( last.ce != null )
- {
- cache.spoolToDisk( last.ce );
- if ( !map.containsKey(last.ce.getKey()) )
- {
- log.error("update: map does not contain key: " +
last.ce.getKey());
- verifyCache();
- }
- if ( map.remove(last.ce.getKey()) == null )
- {
- log.warn("update: remove failed for key: " +
last.ce.getKey() );
- verifyCache();
- }
- }
- else
- {
- throw new Error("update: last.ce is null!");
- }
- removeNode( last );
- }
- else
- {
- verifyCache();
- throw new Error("update: last is null!");
- }
- }
- }
+ int chunkSizeCorrected = Math.min( size, chunkSize );
- if ( log.isDebugEnabled() )
- {
- log.debug("update: After spool map size: " + map.size());
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "About to spool to disk cache, map size: " + size
+ + ", max objects: " + this.cattr.getMaxObjects()
+ + ", items to spool: " + chunkSizeCorrected );
+ }
+
+ // The spool will put them in a disk event queue, so there is no
+ // need to pre-queue the queuing. This would be a bit wasteful
+ // and wouldn't save much time in this synchronous call.
+
+ for ( int i = 0; i < chunkSizeCorrected; i++ )
+ {
+ synchronized ( this )
+ {
+ if ( last != null )
+ {
+ if ( last.ce != null )
+ {
+ cache.spoolToDisk( last.ce );
+ if ( !map.containsKey( last.ce.getKey() ) )
+ {
+ log.error( "update: map does not contain key: " + last.ce.getKey() );
+ verifyCache();
+ }
+ if ( map.remove( last.ce.getKey() ) == null )
+ {
+ log.warn( "update: remove failed for key: " + last.ce.getKey() );
+ verifyCache();
+ }
+ }
+ else
+ {
+ throw new Error( "update: last.ce is null!" );
+ }
+ removeNode( last );
}
- if ( map.size() != dumpCacheSize() )
+ else
{
- log.error("update: After spool, size mismatch: map.size() = "
- + map.size() + ", linked list size = " +
- dumpCacheSize());
+ verifyCache();
+ throw new Error( "update: last is null!" );
}
+ }
}
- /**
- * Remove all of the elements from both the Map and the linked
- * list implementation. Overrides base class.
- */
- public synchronized void removeAll()
- throws IOException
+ if ( log.isDebugEnabled() )
{
- map.clear();
- for ( MemoryElementDescriptor me = first; me != null; )
- {
- if ( me.prev != null )
- {
- me.prev = null;
- }
- MemoryElementDescriptor next = me.next;
- me = next;
- }
- first = last = null;
+ log.debug( "update: After spool map size: " + map.size() );
+ }
+ if ( map.size() != dumpCacheSize() )
+ {
+ log.error( "update: After spool, size mismatch: map.size() = "
+ + map.size() + ", linked list size = " +
+ dumpCacheSize() );
}
+ }
- /**
- * Get an item from the cache without affecting its last access time or
- * position.
- *
- [EMAIL PROTECTED] key Identifies item to find
- [EMAIL PROTECTED] Element mathinh key if found, or null
- [EMAIL PROTECTED] IOException
- */
- public ICacheElement getQuiet( Serializable key )
- throws IOException
+ /**
+ * 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();
+ for ( MemoryElementDescriptor me = first; me != null; )
{
- ICacheElement ce = null;
+ if ( me.prev != null )
+ {
+ me.prev = null;
+ }
+ MemoryElementDescriptor next = me.next;
+ me = next;
+ }
+ first = last = null;
+ }
- MemoryElementDescriptor me = (MemoryElementDescriptor) map.get(key);
- if ( me != null )
- {
- if ( log.isDebugEnabled() )
- {
- log.debug(cacheName + ": LRUMemoryCache quiet hit for " + key);
- }
-
- ce = me.ce;
- }
- else if ( log.isDebugEnabled() )
- {
- log.debug( cacheName + ": LRUMemoryCache quiet miss for " + key );
- }
+ /**
+ * Get an item from the cache without affecting its last access time or
+ * position.
+ *
+ [EMAIL PROTECTED] key Identifies item to find
+ [EMAIL PROTECTED] Element mathinh key if found, or null
+ [EMAIL PROTECTED] IOException
+ */
+ public ICacheElement getQuiet( Serializable key ) throws IOException
+ {
+ ICacheElement ce = null;
- return ce;
+ MemoryElementDescriptor me = ( MemoryElementDescriptor ) map.get( key );
+ if ( me != null )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( cacheName + ": LRUMemoryCache quiet hit for " + key );
+ }
+
+ ce = me.ce;
}
+ else if ( log.isDebugEnabled() )
+ {
+ log.debug( cacheName + ": LRUMemoryCache quiet miss for " + key );
+ }
+
+ return ce;
+ }
+ /**
+ * Get an item from the cache
+ *
+ [EMAIL PROTECTED] key Identifies item to find
+ [EMAIL PROTECTED] ICacheElement if found, else null
+ [EMAIL PROTECTED] IOException
+ */
+ public synchronized ICacheElement get( Serializable key ) throws IOException
+ {
+ ICacheElement ce = null;
- /**
- * Get an item from the cache
- *
- [EMAIL PROTECTED] key Identifies item to find
- [EMAIL PROTECTED] ICacheElement if found, else null
- [EMAIL PROTECTED] IOException
- */
- public synchronized ICacheElement get( Serializable key )
- throws IOException
+ if ( log.isDebugEnabled() )
{
- ICacheElement ce = null;
+ log.debug( "getting item from cache " + cacheName + " for key " +
+ key );
+ }
- if ( log.isDebugEnabled() )
- {
- log.debug( "getting item from cache " + cacheName + " for key " +
- key );
- }
+ MemoryElementDescriptor me = ( MemoryElementDescriptor ) map.get( key );
- MemoryElementDescriptor me = (MemoryElementDescriptor)map.get(key);
-
- if ( me != null )
- {
- if ( log.isDebugEnabled() )
- {
- log.debug( cacheName + ": LRUMemoryCache hit for " + key );
- }
-
- ce = me.ce;
-
- ce.getElementAttributes().setLastAccessTimeNow();
- makeFirst( me );
- }
- else
- {
- log.debug( cacheName + ": LRUMemoryCache miss for " + key );
- }
-
- verifyCache();
- 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.
- *
- [EMAIL PROTECTED] key
- [EMAIL PROTECTED]
- [EMAIL PROTECTED] IOException
- */
- public synchronized boolean remove( Serializable key )
- throws IOException
+ if ( me != null )
{
- if ( log.isDebugEnabled() )
- {
- log.debug( "removing item for key: " + key );
- }
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( cacheName + ": LRUMemoryCache hit for " + key );
+ }
- boolean removed = false;
+ ce = me.ce;
- // 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();
-
- removeNode( ( MemoryElementDescriptor )
- entry.getValue() );
-
- removed = true;
- }
- }
- }
- }
- else if ( key instanceof GroupId )
+ ce.getElementAttributes().setLastAccessTimeNow();
+ makeFirst( me );
+ }
+ else
+ {
+ log.debug( cacheName + ": LRUMemoryCache miss for " + key );
+ }
+
+ verifyCache();
+ 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.
+ *
+ [EMAIL PROTECTED] key
+ [EMAIL PROTECTED]
+ [EMAIL PROTECTED] 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(); )
{
- // 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();
-
- removeNode( ( MemoryElementDescriptor )
- entry.getValue() );
-
- removed = true;
- }
- }
- }
+ Map.Entry entry = ( Map.Entry ) itr.next();
+ Object k = entry.getKey();
+
+ if ( k instanceof String
+ && ( ( String ) k ).startsWith( key.toString() ) )
+ {
+ removeNode( ( MemoryElementDescriptor )
+ entry.getValue() );
+
+ itr.remove();
+
+ removed = true;
+ }
}
- else
+ }
+ }
+ else if ( key instanceof GroupId )
+ {
+ // remove all keys of the same name hierarchy.
+ synchronized ( map )
+ {
+ for ( Iterator itr = map.entrySet().iterator(); itr.hasNext(); )
{
- // remove single item.
- MemoryElementDescriptor me =
- ( MemoryElementDescriptor ) map.remove( key );
+ Map.Entry entry = ( Map.Entry ) itr.next();
+ Object k = entry.getKey();
- if ( me != null )
- {
- removeNode( me );
- removed = true;
- }
+ if ( k instanceof GroupAttrName
+ && ( ( GroupAttrName ) k ).groupId.equals( key ) )
+ {
+ itr.remove();
+
+ removeNode( ( MemoryElementDescriptor )
+ entry.getValue() );
+
+ removed = true;
+ }
}
+ }
+ }
+ else
+ {
+ // remove single item.
+ MemoryElementDescriptor me =
+ ( MemoryElementDescriptor ) map.remove( key );
- return removed;
+ if ( me != null )
+ {
+ removeNode( me );
+ removed = true;
+ }
}
- public class IteratorWrapper
- implements Iterator
+ return removed;
+ }
+
+ public class IteratorWrapper
+ implements Iterator
+ {
+ private final Log log = LogFactory.getLog( LRUMemoryCache.class );
+ private final Iterator i;
+
+ private IteratorWrapper( Map m )
{
- private final Log log = LogFactory.getLog( LRUMemoryCache.class );
- private final Iterator i;
+ i = m.entrySet().iterator();
+ }
- private IteratorWrapper(Map m)
- {
- i = m.entrySet().iterator();
- }
- public boolean hasNext()
- {
- return i.hasNext();
- }
- public Object next()
- {
- return new MapEntryWrapper((Map.Entry)i.next());
- }
- public void remove()
- {
- i.remove();
- }
- public boolean equals(Object o)
- {
- return i.equals(o);
- }
- public int hashCode()
- {
- return i.hashCode();
- }
+ public boolean hasNext()
+ {
+ return i.hasNext();
}
- public class MapEntryWrapper
- implements Map.Entry
+ public Object next()
{
- private final Map.Entry e;
- private MapEntryWrapper(Map.Entry e)
- {
- this.e = e;
- }
+ return new MapEntryWrapper( ( Map.Entry ) i.next() );
+ }
- public boolean equals(Object o)
- {
- return e.equals(o);
- }
- public Object getKey()
- {
- return e.getKey();
- }
- public Object getValue()
- {
- return ((MemoryElementDescriptor)e.getValue()).ce;
- }
- public int hashCode()
- {
- return e.hashCode();
- }
- public Object setValue(Object value)
- {
- throw new UnsupportedOperationException("Use normal cache methods"
- + " to alter the contents of the cache.");
- }
+ public void remove()
+ {
+ i.remove();
}
- /**
- * Gets the iterator attribute of the LRUMemoryCache object
- *
- * @return The iterator value
- */
- public Iterator getIterator()
- {
- return new IteratorWrapper(map);
- }
-
- /**
- * Get an Array of the keys for all elements in the memory cache
- *
- [EMAIL PROTECTED] An Object[]
- */
- public Object[] getKeyArray()
+ public boolean equals( Object o )
{
- // need a better locking strategy here.
- synchronized ( this )
- {
- // may need to lock to map here?
- return map.keySet().toArray();
- }
+ return i.equals( o );
}
- // --------------------------- internal mehods (linked list implementation)
+ public int hashCode()
+ {
+ return i.hashCode();
+ }
+ }
- /**
- * Removes the specified node from the link list.
- *
- [EMAIL PROTECTED] me Description of the Parameter
- */
- private synchronized void removeNode( MemoryElementDescriptor me )
+ public class MapEntryWrapper
+ implements Map.Entry
+ {
+ private final Map.Entry e;
+ private MapEntryWrapper( Map.Entry e )
{
- if ( log.isDebugEnabled() )
- {
- log.debug( "removing node " + me.ce.getKey() + " from cache " +
- cacheName );
- }
+ this.e = e;
+ }
- if ( me.next == null )
- {
- if ( me.prev == null )
- {
- // Make sure it really is the only node before setting head and
- // tail to null. It is possible that we will be passed a node
- // which has already been removed from the list, in which case
- // we should ignore it
-
- if ( me == first && me == last )
- {
- first = last = null;
- }
- }
- else
- {
- // last but not the first.
- last = me.prev;
- last.next = null;
- me.prev = null;
- }
- }
- else if ( me.prev == null )
- {
- // first but not the last.
- first = me.next;
- first.prev = null;
- me.next = null;
- }
- else
- {
- // neither the first nor the last.
- me.prev.next = me.next;
- me.next.prev = me.prev;
- me.prev = me.next = null;
- }
+ public boolean equals( Object o )
+ {
+ return e.equals( o );
}
- /**
- * Adds a new node to the end of the link list. Currently not used.
- *
- [EMAIL PROTECTED] ce The feature to be added to the Last
- */
- private void addLast( CacheElement ce )
+ public Object getKey()
{
- MemoryElementDescriptor me = new MemoryElementDescriptor( ce );
+ return e.getKey();
+ }
- if ( first == null )
- {
- // empty list.
- first = me;
- }
- else
- {
- last.next = me;
- me.prev = last;
- }
- last = me;
- verifyCache(ce.getKey());
+ public Object getValue()
+ {
+ return ( ( MemoryElementDescriptor ) e.getValue() ).ce;
+ }
+
+ public int hashCode()
+ {
+ return e.hashCode();
}
- /**
- * Adds a new node to the start of the link list.
- *
- [EMAIL PROTECTED] ce The feature to be added to the First
- */
- private synchronized void addFirst( ICacheElement ce )
+ public Object setValue( Object value )
{
+ throw new UnsupportedOperationException( "Use normal cache methods"
+ +
+ " to alter the contents of the cache." );
+ }
+ }
- MemoryElementDescriptor me = new MemoryElementDescriptor( ce );
+ /**
+ * Gets the iterator attribute of the LRUMemoryCache object
+ *
+ * @return The iterator value
+ */
+ public Iterator getIterator()
+ {
+ return new IteratorWrapper( map );
+ }
- if ( last == null )
- {
- // empty list.
- last = me;
- }
- else
- {
- first.prev = me;
- me.next = first;
- }
- first = me;
- return;
+ /**
+ * Get an Array of the keys for all elements in the memory cache
+ *
+ [EMAIL PROTECTED] An Object[]
+ */
+ public Object[] getKeyArray()
+ {
+ // need a better locking strategy here.
+ synchronized ( this )
+ {
+ // may need to lock to map here?
+ return map.keySet().toArray();
}
+ }
- /**
- * Moves an existing node to the start of the link list.
- *
- [EMAIL PROTECTED] ce Description of the Parameter
- */
- public void makeFirst( ICacheElement ce )
+ // --------------------------- internal mehods (linked list implementation)
+
+ /**
+ * Removes the specified node from the link list.
+ *
+ [EMAIL PROTECTED] me Description of the Parameter
+ */
+ private synchronized void removeNode( MemoryElementDescriptor me )
+ {
+ if ( log.isDebugEnabled() )
{
- makeFirst( new MemoryElementDescriptor( ce ) );
+ log.debug( "removing node " + me.ce.getKey() + " from cache " +
+ cacheName );
}
- /**
- * Moves an existing node to the start of the link list.
- *
- [EMAIL PROTECTED] me Description of the Parameter
- */
- public synchronized void makeFirst( MemoryElementDescriptor me )
+ if ( me.next == null )
{
- if ( me.prev == null )
- {
- // already the first node.
- return;
- }
- me.prev.next = me.next;
-
- if ( me.next == null )
- {
- // last but not the first.
- last = me.prev;
- last.next = null;
- }
- else
+ if ( me.prev == null )
+ {
+ // Make sure it really is the only node before setting head and
+ // tail to null. It is possible that we will be passed a node
+ // which has already been removed from the list, in which case
+ // we should ignore it
+
+ if ( me == first && me == last )
{
- // neither the last nor the first.
- me.next.prev = me.prev;
+ first = last = null;
}
- first.prev = me;
- me.next = first;
+ }
+ else
+ {
+ // last but not the first.
+ last = me.prev;
+ last.next = null;
me.prev = null;
- first = me;
+ }
}
+ else if ( me.prev == null )
+ {
+ // first but not the last.
+ first = me.next;
+ first.prev = null;
+ me.next = null;
+ }
+ else
+ {
+ // neither the first nor the last.
+ me.prev.next = me.next;
+ me.next.prev = me.prev;
+ me.prev = me.next = null;
+ }
+ }
- // ---------------------------------------------------------- debug methods
+ /**
+ * Adds a new node to the end of the link list. Currently not used.
+ *
+ [EMAIL PROTECTED] ce The feature to be added to the Last
+ */
+ private void addLast( CacheElement ce )
+ {
+ MemoryElementDescriptor me = new MemoryElementDescriptor( ce );
- /**
- * Dump the cache map for debugging.
- */
- public void dumpMap()
+ if ( first == null )
{
- 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() );
- }
+ // empty list.
+ first = me;
+ }
+ else
+ {
+ last.next = me;
+ me.prev = last;
}
+ last = me;
+ verifyCache( ce.getKey() );
+ }
+
+ /**
+ * Adds a new node to the start of the link list.
+ *
+ [EMAIL PROTECTED] ce The feature to be added to the First
+ */
+ private synchronized void addFirst( ICacheElement ce )
+ {
- /**
- * Dump the cache entries from first to list for debugging.
- */
- public void dumpCacheEntries()
+ MemoryElementDescriptor me = new MemoryElementDescriptor( ce );
+
+ if ( last == null )
{
- log.debug( "dumpingCacheEntries" );
- for ( MemoryElementDescriptor me = first; me != null; me = me.next )
- {
- log.debug( "dumpCacheEntries> key="
- + me.ce.getKey() + ", val=" + me.ce.getVal() );
- }
+ // empty list.
+ last = me;
+ }
+ else
+ {
+ first.prev = me;
+ me.next = first;
}
+ first = me;
+ return;
+ }
+
+ /**
+ * Moves an existing node to the start of the link list.
+ *
+ [EMAIL PROTECTED] ce Description of the Parameter
+ */
+ public void makeFirst( ICacheElement ce )
+ {
+ makeFirst( new MemoryElementDescriptor( ce ) );
+ }
- private int dumpCacheSize()
+ /**
+ * Moves an existing node to the start of the link list.
+ *
+ [EMAIL PROTECTED] me Description of the Parameter
+ */
+ public synchronized void makeFirst( MemoryElementDescriptor me )
+ {
+ if ( me.prev == null )
{
- int size = 0;
- for ( MemoryElementDescriptor me = first; me != null; me = me.next )
- {
- size++;
- }
- return size;
+ // already the first node.
+ return;
}
+ me.prev.next = me.next;
- private void verifyCache()
+ if ( me.next == null )
{
- if ( !log.isDebugEnabled() )
- return;
+ // last but not the first.
+ last = me.prev;
+ last.next = null;
+ }
+ else
+ {
+ // neither the last nor the first.
+ me.next.prev = me.prev;
+ }
+ first.prev = me;
+ me.next = first;
+ me.prev = null;
+ first = me;
+ }
- boolean found = false;
- log.debug("verifycache[" + cacheName + "]: mapContains " + map.size() + "
elements, linked list contains "
- + dumpCacheSize() + " elements" );
- log.debug("verifycache: checking linked list by key ");
- for ( MemoryElementDescriptor li = first; li != null; li = li.next )
- {
- Object key = li.ce.getKey();
- if ( !map.containsKey(key) )
- {
- log.error("verifycache[" + cacheName + "]: map does not contain key
: " + li.ce.getKey());
- log.error("li.hashcode=" + li.ce.getKey().hashCode());
- log.error("key class=" + key.getClass());
- log.error("key hashcode=" + key.hashCode());
- log.error("key toString=" + key.toString());
- if ( key instanceof GroupAttrName )
- {
- GroupAttrName name = (GroupAttrName) key;
- log.error("GroupID hashcode=" + name.groupId.hashCode());
- log.error("GroupID.class=" + name.groupId.getClass());
- log.error("AttrName hashcode=" + name.attrName.hashCode());
- log.error("AttrName.class=" + name.attrName.getClass());
- }
- dumpMap();
- }
- else if ( map.get(li.ce.getKey()) == null )
- {
- log.error("verifycache[" + cacheName +
- "]: linked list retrieval returned null for key: " +
- li.ce.getKey());
- }
- }
+ // ---------------------------------------------------------- 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" );
+ for ( MemoryElementDescriptor me = first; me != null; me = me.next )
+ {
+ log.debug( "dumpCacheEntries> key="
+ + me.ce.getKey() + ", val=" + me.ce.getVal() );
+ }
+ }
- log.debug("verifycache: checking linked list by value ");
- for ( MemoryElementDescriptor li3 = first; li3 != null; li3 = li3.next )
+ private int dumpCacheSize()
+ {
+ int size = 0;
+ for ( MemoryElementDescriptor me = first; me != null; me = me.next )
+ {
+ size++;
+ }
+ return size;
+ }
+
+ private void verifyCache()
+ {
+ if ( !log.isDebugEnabled() )
+ {
+ return;
+ }
+
+ boolean found = false;
+ log.debug( "verifycache[" + cacheName + "]: mapContains " + map.size() +
+ " elements, linked list contains "
+ + dumpCacheSize() + " elements" );
+ log.debug( "verifycache: checking linked list by key " );
+ for ( MemoryElementDescriptor li = first; li != null; li = li.next )
+ {
+ Object key = li.ce.getKey();
+ if ( !map.containsKey( key ) )
+ {
+ log.error( "verifycache[" + cacheName +
+ "]: map does not contain key : " + li.ce.getKey() );
+ log.error( "li.hashcode=" + li.ce.getKey().hashCode() );
+ log.error( "key class=" + key.getClass() );
+ log.error( "key hashcode=" + key.hashCode() );
+ log.error( "key toString=" + key.toString() );
+ if ( key instanceof GroupAttrName )
+ {
+ GroupAttrName name = ( GroupAttrName ) key;
+ log.error( "GroupID hashcode=" + name.groupId.hashCode() );
+ log.error( "GroupID.class=" + name.groupId.getClass() );
+ log.error( "AttrName hashcode=" + name.attrName.hashCode() );
+ log.error( "AttrName.class=" + name.attrName.getClass() );
+ }
+ dumpMap();
+ }
+ else if ( map.get( li.ce.getKey() ) == null )
+ {
+ log.error( "verifycache[" + cacheName +
+ "]: linked list retrieval returned null for key: " +
+ li.ce.getKey() );
+ }
+ }
+
+ log.debug( "verifycache: checking linked list by value " );
+ for ( MemoryElementDescriptor li3 = first; li3 != null; li3 = li3.next )
+ {
+ if ( map.containsValue( li3 ) == false )
+ {
+ log.error( "verifycache[" + cacheName +
+ "]: map does not contain value : " + li3 );
+ dumpMap();
+ }
+ }
+
+ log.debug( "verifycache: checking via keysets!" );
+ for ( Iterator itr2 = map.keySet().iterator(); itr2.hasNext(); )
+ {
+ found = false;
+ Serializable val = null;
+ try
+ {
+ val = ( Serializable ) itr2.next();
+ }
+ catch ( NoSuchElementException nse )
+ {
+ log.error( "verifycache: no such element exception" );
+ }
+
+ for ( MemoryElementDescriptor li2 = first; li2 != null; li2 = li2.next )
+ {
+ if ( val.equals( li2.ce.getKey() ) )
+ {
+ found = true;
+ break;
+ }
+ }
+ if ( !found )
+ {
+ log.error( "verifycache[" + cacheName + "]: key not found in list : " +
+ val );
+ dumpCacheEntries();
+ if ( map.containsKey( val ) )
{
- if ( map.containsValue(li3) == false )
- {
- log.error("verifycache[" + cacheName + "]: map does not contain
value : " + li3);
- dumpMap();
- }
+ log.error( "verifycache: map contains key" );
}
-
- log.debug("verifycache: checking via keysets!");
- for ( Iterator itr2 = map.keySet().iterator(); itr2.hasNext(); )
+ else
{
- found = false;
- Serializable val = null;
- try
- {
- val = (Serializable) itr2.next();
- }
- catch ( NoSuchElementException nse )
- {
- log.error("verifycache: no such element exception");
- }
-
- for ( MemoryElementDescriptor li2 = first; li2 != null; li2 = li2.next
)
- {
- if ( val.equals(li2.ce.getKey()) )
- {
- found = true;
- break;
- }
- }
- if ( !found )
- {
- log.error("verifycache[" + cacheName + "]: key not found in list :
" + val );
- dumpCacheEntries();
- if ( map.containsKey(val) )
- {
- log.error("verifycache: map contains key");
- }
- else
- {
- log.error("verifycache: map does NOT contain key, what the
HECK!");
- }
- }
+ log.error( "verifycache: map does NOT contain key, what the HECK!" );
}
+ }
}
+ }
- private void verifyCache(Serializable key)
+ private void verifyCache( Serializable key )
+ {
+ if ( !log.isDebugEnabled() )
{
- if ( !log.isDebugEnabled() )
- return;
+ return;
+ }
- boolean found = false;
+ boolean found = false;
- // go through the linked list looking for the key
- for ( MemoryElementDescriptor li = first; li != null; li = li.next )
- {
- if ( li.ce.getKey() == key )
- {
- found = true;
- log.debug("verifycache(key) key match: " + key );
- break;
- }
- }
- if ( !found )
- {
- log.error("verifycache(key)[" + cacheName + "], couldn't find key! : "
+ key );
- }
+ // go through the linked list looking for the key
+ for ( MemoryElementDescriptor li = first; li != null; li = li.next )
+ {
+ if ( li.ce.getKey() == key )
+ {
+ found = true;
+ log.debug( "verifycache(key) key match: " + key );
+ break;
+ }
}
+ if ( !found )
+ {
+ log.error( "verifycache(key)[" + cacheName + "], couldn't find key! : " +
+ key );
+ }
+ }
}
/**
* needed for memory cache element LRU linked lisk
*/
-class MemoryElementDescriptor implements Serializable
+class MemoryElementDescriptor
+ implements Serializable
{
- /** Description of the Field */
- public MemoryElementDescriptor prev, next;
- /** Description of the Field */
- public ICacheElement ce;
-
- /**
- * Constructor for the MemoryElementDescriptor object
- *
- * @param ce
- */
- public MemoryElementDescriptor( ICacheElement ce )
- {
- this.ce = ce;
- }
+ /** Description of the Field */
+ public MemoryElementDescriptor prev, next;
+
+ /** Description of the Field */
+ public ICacheElement ce;
+
+ /**
+ * Constructor for the MemoryElementDescriptor object
+ *
+ * @param ce
+ */
+ public MemoryElementDescriptor( ICacheElement ce )
+ {
+ this.ce = ce;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]