[jboss-cvs] JBossCache/src/org/jboss/cache/eviction ...
Elias Ross
genman at noderunner.net
Sun Nov 26 23:51:24 EST 2006
User: genman
Date: 06/11/26 23:51:24
Added: src/org/jboss/cache/eviction ExpirationAlgorithm.java
ExpirationConfiguration.java ExpirationPolicy.java
Log:
JBCACHE-880 add per node expiration policy
Revision Changes Path
1.1 date: 2006/11/27 04:51:24; author: genman; state: Exp;JBossCache/src/org/jboss/cache/eviction/ExpirationAlgorithm.java
Index: ExpirationAlgorithm.java
===================================================================
package org.jboss.cache.eviction;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Region;
import org.jboss.cache.lock.TimeoutException;
import org.jboss.cache.optimistic.FqnComparator;
import org.jgroups.ExitEvent;
/**
* Eviction algorithm that uses a key in the Node data that indicates the time the node should
* be evicted.
* This algorithm also considers {@link ExpirationConfiguration#getMaxNodes()}, and
* will remove the most soon to expire entires first.
* <p/>
* Note that if the expiration key is absent, the node will not be evicted.
*/
public class ExpirationAlgorithm extends BaseEvictionAlgorithm
{
private static final Log log = LogFactory.getLog(ExpirationAlgorithm.class);
private ExpirationConfiguration config;
private ExpirationPolicy policy;
private SortedSet<ExpirationEntry> set;
/**
* Constructs a new algorithm with a policy.
*/
public ExpirationAlgorithm(ExpirationPolicy policy)
{
this.policy = policy;
this.set = new TreeSet<ExpirationEntry>();
}
private void addEvictionEntry(EvictedEventNode node)
{
Fqn fqn = node.getFqn();
addEvictionEntry(fqn);
}
private void addEvictionEntry(Fqn fqn)
{
Long l = getExpiration(fqn);
if (l == null) {
if (config.getWarnNoExpirationKey())
log.warn("No expiration key '" + config.getExpirationKeyName() +
"' for Node: " + fqn);
else if (log.isDebugEnabled())
log.debug("No expiration key for Node: " + fqn);
return;
}
ExpirationEntry ee = new ExpirationEntry(fqn, l.longValue());
set.add(ee);
}
private Long getExpiration(Fqn fqn)
{
Long l = (Long) policy.getCacheData(fqn, config.getExpirationKeyName());
if (l == null)
return null;
return l;
}
@Override
protected void processQueues(Region region) throws EvictionException
{
EvictedEventNode node;
int count = 0;
while ((node = region.takeLastEventNode()) != null)
{
if (log.isTraceEnabled())
{
log.trace("process " + node);
}
count++;
switch (node.getEventType())
{
case ADD_NODE_EVENT :
case ADD_ELEMENT_EVENT :
addEvictionEntry(node);
break;
case REMOVE_ELEMENT_EVENT :
case REMOVE_NODE_EVENT :
removeEvictionEntry(node);
break;
case VISIT_NODE_EVENT :
case MARK_IN_USE_EVENT :
case UNMARK_USE_EVENT :
// TODO
break;
default :
throw new RuntimeException("Illegal Eviction Event type " + node.getEventType());
}
}
if (log.isTraceEnabled())
{
log.trace("processed " + count + " node events in region: " + region.getFqn());
}
}
@Override
protected void prune() throws EvictionException
{
if (set.isEmpty())
return;
long now = System.currentTimeMillis();
int max = config.getMaxNodes();
for (Iterator<ExpirationEntry> i = set.iterator(); i.hasNext();)
{
ExpirationEntry ee = i.next();
if (ee.getExpiration() < now || (max != 0 && set.size() > max))
{
i.remove();
evictCacheNode(ee.getFqn());
}
else
{
break;
}
}
}
private void removeEvictionEntry(EvictedEventNode node)
{
Fqn fqn = node.getFqn();
if (getExpiration(fqn) == null)
set.remove(new ExpirationEntry(fqn));
}
@Override
public void resetEvictionQueue(Region region)
{
for (ExpirationEntry ee: set)
{
addEvictionEntry(ee.getFqn());
}
}
@Override
protected EvictionQueue setupEvictionQueue(Region region) throws EvictionException
{
this.region = region;
this.config = (ExpirationConfiguration) region.getEvictionPolicyConfig();
return new DummyEvictionQueue();
}
@Override
protected boolean shouldEvictNode(NodeEntry ne)
{
throw new UnsupportedOperationException();
}
/**
* Ordered list of FQN, with the expiration taken from the Map at the time
* of processing.
*/
static class ExpirationEntry implements Comparable<ExpirationEntry>
{
private long expiration;
private Fqn fqn;
public ExpirationEntry(Fqn fqn)
{
this.fqn = fqn;
}
public ExpirationEntry(Fqn fqn, long expiration)
{
this.fqn = fqn;
this.expiration = expiration;
}
/**
* Returns true if the FQN are the same, else compares expiration, then FQN order.
*/
public int compareTo(ExpirationEntry ee)
{
if (fqn.equals(ee.fqn))
return 0;
long n = expiration - ee.expiration;
if (n < 0)
return -1;
if (n > 0)
return 1;
return FqnComparator.INSTANCE.compare(fqn, ee.fqn);
}
/**
* @return the expiration
*/
public long getExpiration()
{
return expiration;
}
/**
* @return the fqn
*/
public Fqn getFqn()
{
return fqn;
}
public boolean equals(ExpirationEntry ee)
{
return fqn.equals(ee.fqn);
}
public int hashCode()
{
return fqn.hashCode();
}
public String toString()
{
return "EE fqn=" + fqn;
}
}
class DummyEvictionQueue implements EvictionQueue {
public void addNodeEntry(NodeEntry entry)
{
throw new UnsupportedOperationException();
}
public void clear()
{
set.clear();
}
public boolean containsNodeEntry(NodeEntry entry)
{
return false;
}
public NodeEntry getFirstNodeEntry()
{
return null;
}
public NodeEntry getNodeEntry(Fqn fqn)
{
return null;
}
public NodeEntry getNodeEntry(String fqn)
{
return null;
}
public int getNumberOfElements()
{
return set.size();
}
public int getNumberOfNodes()
{
return set.size();
}
public Iterator iterate()
{
return null;
}
public void modifyElementCount(int difference)
{
}
public void removeNodeEntry(NodeEntry entry)
{
throw new UnsupportedOperationException();
}
}
}
1.1 date: 2006/11/27 04:51:24; author: genman; state: Exp;JBossCache/src/org/jboss/cache/eviction/ExpirationConfiguration.java
Index: ExpirationConfiguration.java
===================================================================
package org.jboss.cache.eviction;
import org.jboss.cache.config.Dynamic;
/**
* Configuration for indicating the Node key for setting a specific eviction time.
*/
public class ExpirationConfiguration extends EvictionPolicyConfigBase
{
/**
* Default key name for indicating expiration time.
*/
public static final String DEFAULT_EXPIRATION_KEY = "expiration";
/**
* Node key name used to indicate the expiration of a node.
*/
@Dynamic
private String expirationKeyName = DEFAULT_EXPIRATION_KEY;
@Dynamic
private boolean warnNoExpirationKey = true;
public ExpirationConfiguration()
{
setEvictionPolicyClassName();
}
@Override
protected void setEvictionPolicyClassName()
{
setEvictionPolicyClass(ExpirationPolicy.class.getName());
}
/**
* Returns the expirationKeyName.
* This key should point to a java.lang.Long value in the Node data.
*/
public String getExpirationKeyName()
{
return expirationKeyName;
}
/**
* Sets the expirationKeyName.
*/
public void setExpirationKeyName(String expirationKeyName)
{
this.expirationKeyName = expirationKeyName;
}
/**
* Returns true if the algorithm should warn if a expiration key is missing for a node.
*/
public boolean getWarnNoExpirationKey()
{
return warnNoExpirationKey;
}
/**
* Sets if the algorithm should warn if a expiration key is missing for a node.
*/
public void setWarnNoExpirationKey(boolean warnNoExpirationKey)
{
this.warnNoExpirationKey = warnNoExpirationKey;
}
}
1.1 date: 2006/11/27 04:51:24; author: genman; state: Exp;JBossCache/src/org/jboss/cache/eviction/ExpirationPolicy.java
Index: ExpirationPolicy.java
===================================================================
package org.jboss.cache.eviction;
/**
* Returns the {@link ExpirationAlgorithm} as the policy's algorithm.
* @author rosse
*/
public class ExpirationPolicy extends BaseEvictionPolicy
{
private EvictionAlgorithm algorithm;
public ExpirationPolicy() {
algorithm = new ExpirationAlgorithm(this);
}
public EvictionAlgorithm getEvictionAlgorithm()
{
return algorithm;
}
public Class getEvictionConfigurationClass()
{
return ExpirationConfiguration.class;
}
}
More information about the jboss-cvs-commits
mailing list