all get documented properly soon, need to update this for the new server... also changed all the E-mail addresses in the old java source to match present reality
281 lines
8.4 KiB
Java
281 lines
8.4 KiB
Java
/*
|
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
|
* (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.mozilla.org/MPL/>.
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
|
|
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
|
|
* language governing rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Venice Web Communities System.
|
|
*
|
|
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@users.sf.net>,
|
|
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
|
|
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
package com.silverwrist.util.cache;
|
|
|
|
import java.lang.ref.*;
|
|
import java.util.*;
|
|
|
|
/**
|
|
* An entry from the <CODE>CacheMap</CODE> class. This object holds the key, a <CODE>SoftReference</CODE>
|
|
* to the value, the timestamp of its last access, and the number of times this element has been accessed.
|
|
* The latter two values are frequently used by an object implementing the <CODE>CacheMapStrategy</CODE>
|
|
* interface to compute a "figure of merit" for the entry that decides whether or not it gets discarded.
|
|
*
|
|
* @author Eric J. Bowersox <erbo@users.sf.net>
|
|
* @version X
|
|
* @see CacheMap
|
|
* @see CacheMapStrategy
|
|
* @see java.lang.ref.SoftReference
|
|
*/
|
|
public final class CacheMapEntry implements Map.Entry
|
|
{
|
|
/*--------------------------------------------------------------------------------
|
|
* Attributes
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
private Object key; // the key for this entry
|
|
private SoftReference value; // reference to (discardable) value
|
|
private int hits = 0; // number of hits on this entry
|
|
private long timestamp; // timestamp of this entry
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Constructors
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* Creates a new <CODE>CacheMapEntry</CODE>.
|
|
*
|
|
* @param key The key for this entry.
|
|
* @param value The value to be held in this entry.
|
|
*/
|
|
CacheMapEntry(Object key, Object value)
|
|
{
|
|
this.key = key;
|
|
this.value = new SoftReference(value);
|
|
this.timestamp = System.currentTimeMillis();
|
|
|
|
} // end constructor
|
|
|
|
/**
|
|
* Creates a new <CODE>CacheMapEntry</CODE>.
|
|
*
|
|
* @param key The key for this entry.
|
|
* @param value The value to be held in this entry.
|
|
* @param q The <CODE>ReferenceQueue</CODE> to add the new reference generated by this constructor to.
|
|
*/
|
|
CacheMapEntry(Object key, Object value, ReferenceQueue q)
|
|
{
|
|
this.key = key;
|
|
this.value = new SoftReference(value,q);
|
|
this.timestamp = System.currentTimeMillis();
|
|
|
|
} // end constructor
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* finalize() function
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* Called by the garbage collector on an object when garbage collection determines that there are no
|
|
* more references to the object.
|
|
*/
|
|
protected void finalize()
|
|
{
|
|
key = null;
|
|
value.clear();
|
|
value = null;
|
|
|
|
} // end finalize
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* Implementations from interface Map.Entry
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* Returns the key corresponding to this entry.
|
|
*
|
|
* @return The key corresponding to this entry.
|
|
*/
|
|
public final Object getKey()
|
|
{
|
|
return key;
|
|
|
|
} // end getKey
|
|
|
|
/**
|
|
* Returns the value corresponding to this entry. If the value has already been reclaimed by the
|
|
* garbage collector, the return value is <CODE>null</CODE>.
|
|
*
|
|
* @return The value corresponding to this entry.
|
|
*/
|
|
public final Object getValue()
|
|
{
|
|
return value.get();
|
|
|
|
} // end getValue
|
|
|
|
/**
|
|
* Replaces the value corresponding to this entry with the specified value.
|
|
*
|
|
* @param o The new value to be stored in this entry.
|
|
* @return The former value stored in this entry. If the value has already been reclaimed by the
|
|
* garbage collector, the return value is <CODE>null</CODE>.
|
|
*/
|
|
public final Object setValue(Object o)
|
|
{
|
|
Object rc = value.get();
|
|
value.clear();
|
|
value = new SoftReference(o);
|
|
return rc;
|
|
|
|
} // end setValue
|
|
|
|
/**
|
|
* Compares the specified object with this object for equality. The <CODE>CacheMap</CODE> considers
|
|
* two entries to be equivalent if they have the same key. (The value is not considered because it
|
|
* might already have been garbage-collected.)
|
|
*
|
|
* @param o The other object to compare to.
|
|
* @return <CODE>true</CODE> if the specified object is equal to this entry.
|
|
*/
|
|
public final boolean equals(Object o)
|
|
{
|
|
// make sure the other element is a Map.Entry
|
|
if ((o==null) || !(o instanceof Map.Entry))
|
|
return false;
|
|
Map.Entry other = (Map.Entry)o;
|
|
|
|
// compare the keys only (the values may change)
|
|
if (key==null)
|
|
return (other.getKey()==null);
|
|
else
|
|
return ((other.getKey()!=null) && key.equals(other.getKey()));
|
|
|
|
} // end equals
|
|
|
|
/**
|
|
* Returns the hash code value for this map entry, defined to be the hash code value of the key.
|
|
*
|
|
* @return The hash code value for this map entry.
|
|
*/
|
|
public final int hashCode()
|
|
{
|
|
return ((key==null) ? 0 : key.hashCode());
|
|
|
|
} // end hashCode
|
|
|
|
/*--------------------------------------------------------------------------------
|
|
* External operations
|
|
*--------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* Replaces the value corresponding to this entry with the specified value.
|
|
*
|
|
* @param o The new value to be stored in this entry.
|
|
* @param q The <CODE>ReferenceQueue</CODE> to add the freshly-generated reference to.
|
|
* @return The former value stored in this entry. If the value has already been reclaimed by the
|
|
* garbage collector, the return value is <CODE>null</CODE>.
|
|
*/
|
|
final Object setValue(Object o, ReferenceQueue q)
|
|
{
|
|
Object rc = value.get();
|
|
value.clear();
|
|
value = new SoftReference(o,q);
|
|
return rc;
|
|
|
|
} // end setValue
|
|
|
|
/**
|
|
* Returns <CODE>true</CODE> if the value in this map entry has been cleared by the garbage collector.
|
|
*
|
|
* @return <CODE>true</CODE> if the value has been cleared, <CODE>false</CODE> if not.
|
|
*/
|
|
public final boolean isCleared()
|
|
{
|
|
return (value.get()==null);
|
|
|
|
} // end isCleared
|
|
|
|
/**
|
|
* Returns <CODE> true if the specified reference is the one contained in this map entry.
|
|
*
|
|
* @param r The reference we're trying to match.
|
|
* @return <CODE>true/CODE> if this reference is the same as the one contained in the map entry,
|
|
* <CODE>false</CODE> if not.
|
|
*/
|
|
final boolean matchReference(Reference r)
|
|
{
|
|
if (r instanceof SoftReference)
|
|
return (value==(SoftReference)r);
|
|
else
|
|
return false;
|
|
|
|
} // end matchReference
|
|
|
|
/**
|
|
* Clears out all references held by this map entry.
|
|
*/
|
|
final void discard()
|
|
{
|
|
key = null;
|
|
value.clear();
|
|
value = null;
|
|
|
|
} // end discard
|
|
|
|
/**
|
|
* Returns the number of times this map entry has been referenced.
|
|
*
|
|
* @return The number of times this map entry has been referenced.
|
|
*/
|
|
public final int getHits()
|
|
{
|
|
return hits;
|
|
|
|
} // end getHits
|
|
|
|
/**
|
|
* Returns the timestamp of the most recent reference to this map entry.
|
|
*
|
|
* @return The timestamp of the most recent reference to this map entry.
|
|
*/
|
|
public final long getTimestamp()
|
|
{
|
|
return timestamp;
|
|
|
|
} // end getTimestamp
|
|
|
|
/**
|
|
* Returns the number of milliseconds since this map entry was last referenced.
|
|
*
|
|
* @param tick The current time tick of the system in milliseconds.
|
|
* @return The number of milliseconds since this map entry was last referenced.
|
|
*/
|
|
public final long getAge(long tick)
|
|
{
|
|
return (tick - timestamp);
|
|
|
|
} // end getAge
|
|
|
|
/**
|
|
* References this entry, which increments its "hit" counter and updates its current time stamp.
|
|
*/
|
|
final void touch()
|
|
{
|
|
hits++;
|
|
timestamp = System.currentTimeMillis();
|
|
|
|
} // end touch
|
|
|
|
} // end class CacheMapEntry
|