Author: manik.surtani(a)jboss.com
Date: 2009-02-03 16:42:43 -0500 (Tue, 03 Feb 2009)
New Revision: 7634
Modified:
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithmConfigBase.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseEvictionAlgorithm.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/BaseAlgorithmTest.java
Log:
Eviction overhaul, phase 2
Modified:
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithmConfigBase.java
===================================================================
---
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithmConfigBase.java 2009-02-03
21:28:24 UTC (rev 7633)
+++
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithmConfigBase.java 2009-02-03
21:42:43 UTC (rev 7634)
@@ -44,12 +44,7 @@
protected int minEntries = -1;
@Dynamic
protected long minTimeToLive = -1;
- @Dynamic
- private long timeToLive = -1;
- @Dynamic
- private long maxAge = -1;
-
/**
* Can only be instantiated by a subclass.
*/
@@ -112,43 +107,6 @@
minTimeToLive = timeUnit.toMillis(time);
}
- public long getTimeToLive() {
- return timeToLive;
- }
-
- /**
- * -1 means time to live is unused, 0 means the time to live is 0 (considered for
immediate eviction)
- *
- * @param timeToLive the time to live, since last modification, of any entry in the
cache. Defaults to -1, meaning
- * that this is unused.
- */
- public void setTimeToLive(long timeToLive) {
- testImmutability("timeToLive");
- this.timeToLive = timeToLive;
- }
-
- public void setTimeToLive(long timeToLive, TimeUnit unit) {
- setTimeToLive(unit.toMillis(timeToLive));
- }
-
- public long getMaxAge() {
- return maxAge;
- }
-
- /**
- * -1 means max age is not considered, 0 means entries are considered for eviction
immediately.
- *
- * @param maxAge the maximum age of entries in the cache, after which they will be
removed.
- */
- public void setMaxAge(long maxAge) {
- testImmutability("maxAge");
- this.maxAge = maxAge;
- }
-
- public void setMaxAge(long maxAge, TimeUnit unit) {
- setMaxAge(unit.toMillis(maxAge));
- }
-
public void validate() throws ConfigurationException {
if (evictionAlgorithmClassName == null)
throw new ConfigurationException("Eviction algorithm class name cannot be
null!");
@@ -161,11 +119,9 @@
EvictionAlgorithmConfigBase that = (EvictionAlgorithmConfigBase) o;
- if (maxAge != that.maxAge) return false;
if (maxEntries != that.maxEntries) return false;
if (minEntries != that.minEntries) return false;
if (minTimeToLive != that.minTimeToLive) return false;
- if (timeToLive != that.timeToLive) return false;
if (evictionAlgorithmClassName != null ?
!evictionAlgorithmClassName.equals(that.evictionAlgorithmClassName) :
that.evictionAlgorithmClassName != null)
return false;
@@ -178,8 +134,6 @@
result = 31 * result + maxEntries;
result = 31 * result + minEntries;
result = 31 * result + (int) (minTimeToLive ^ (minTimeToLive >>> 32));
- result = 31 * result + (int) (timeToLive ^ (timeToLive >>> 32));
- result = 31 * result + (int) (maxAge ^ (maxAge >>> 32));
return result;
}
@@ -190,8 +144,6 @@
", maxEntries=" + maxEntries +
", minEntries=" + minEntries +
", minTimeToLive=" + minTimeToLive +
- ", timeToLive=" + timeToLive +
- ", maxAge=" + maxAge +
'}';
}
@@ -199,8 +151,6 @@
maxEntries = -1;
minEntries = -1;
minTimeToLive = -1;
- timeToLive = -1;
- maxAge = -1;
}
public EvictionAlgorithmConfigBase clone() {
Modified:
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseEvictionAlgorithm.java
===================================================================
---
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseEvictionAlgorithm.java 2009-02-03
21:28:24 UTC (rev 7633)
+++
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseEvictionAlgorithm.java 2009-02-03
21:42:43 UTC (rev 7634)
@@ -85,17 +85,6 @@
return true;
}
- // else, let's check if the entry has expired due to TTL or maxAge
- if (evictionAlgorithmConfig.getTimeToLive() > -1) {
- if (System.currentTimeMillis() > evictionAlgorithmConfig.getTimeToLive() +
entry.getModifiedTimeStamp())
- return true;
- }
-
- if (evictionAlgorithmConfig.getMaxAge() > -1) {
- if (System.currentTimeMillis() > evictionAlgorithmConfig.getMaxAge() +
entry.getCreationTimeStamp())
- return true;
- }
-
return false;
}
@@ -188,6 +177,9 @@
case VISIT_ENTRY_EVENT:
processVisitedEntries(event);
break;
+ case CLEAR_CACHE_EVENT:
+ processClearCacheEvent();
+ break;
case MARK_IN_USE_EVENT:
processMarkInUseNodes(event.getKey(), event.getInUseTimeout());
break;
@@ -198,7 +190,7 @@
throw new RuntimeException("Illegal Eviction Event type " +
event.getEventType());
}
}
- if (trace) log.trace("processed {0} eviction events", count);
+ log.trace("processed {0} eviction events", count);
}
protected boolean evict(EntryEvictionData data) {
@@ -225,7 +217,7 @@
}
protected void processMarkInUseNodes(Object key, long inUseTimeout) throws
EvictionException {
- if (trace) log.trace("Marking {0} as in use with a usage timeout of {1}",
key, inUseTimeout);
+ log.trace("Marking {0} as in use with a usage timeout of {1}", key,
inUseTimeout);
EntryEvictionData ne = evictionQueue.get(key);
if (ne != null) {
@@ -234,7 +226,7 @@
}
protected void processUnmarkInUseNodes(Object key) throws EvictionException {
- if (trace) log.trace("Unmarking node {0} as in use", key);
+ log.trace("Unmarking node {0} as in use", key);
EntryEvictionData ne = evictionQueue.get(key);
if (ne != null) {
@@ -244,39 +236,44 @@
protected void processAddedEntries(EvictionEvent evictedEventNode) throws
EvictionException {
Object key = evictedEventNode.getKey();
- if (trace) log.trace("Adding entry {0} to eviction queue", key);
+ log.trace("Adding entry {0} to eviction queue", key);
EntryEvictionData data = evictionQueue.get(key);
if (data != null) {
data.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
data.incrementNumberOfVisits();
- if (trace) log.trace("Queue already contains key. Processing it as
visited.");
+ log.trace("Queue already contains key. Processing it as visited.");
processVisitedEntries(evictedEventNode);
} else {
data = new EntryEvictionData(1, evictedEventNode.getCreationTimestamp(), key);
data.setCreationTimeStamp(evictedEventNode.getCreationTimestamp());
evictionQueue.add(data);
- if (trace) log.trace("Added successfully to eviction queue");
+ log.trace("Added successfully to eviction queue");
}
}
protected void processRemovedEntries(EvictionEvent evictedEventNode) throws
EvictionException {
Object key = evictedEventNode.getKey();
- if (trace) log.trace("Removing key {0} from eviction queue and attempting
eviction", key);
+ log.trace("Removing key {0} from eviction queue and attempting eviction",
key);
EntryEvictionData data = evictionQueue.get(key);
if (data != null) {
- evictionQueue.remove(data);
+ evictionQueue.remove(key);
} else {
- if (trace)
- log.trace("Can't find entry eviction data associated with key {0}.
Could have been evicted earlier.",
- key);
+ log.trace("Can't find entry eviction data associated with key {0}.
Could have been evicted earlier.", key);
return;
}
- if (trace) log.trace("Removed from eviction queue");
+ log.trace("Removed from eviction queue");
}
+ protected void processClearCacheEvent() throws EvictionException {
+ log.trace("Clearing eviction queue");
+ evictionQueue.clear();
+ log.trace("Cleared eviction queue");
+ }
+
+
/**
* Visit a node in cache.
* <p/>
Modified:
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/BaseAlgorithmTest.java
===================================================================
---
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/BaseAlgorithmTest.java 2009-02-03
21:28:24 UTC (rev 7633)
+++
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/BaseAlgorithmTest.java 2009-02-03
21:42:43 UTC (rev 7634)
@@ -8,12 +8,13 @@
import org.horizon.eviction.EvictionAlgorithm;
import org.horizon.eviction.EvictionAlgorithmConfigBase;
import org.horizon.eviction.EvictionEvent;
-import static org.horizon.eviction.EvictionEvent.Type.ADD_ENTRY_EVENT;
+import static org.horizon.eviction.EvictionEvent.Type.*;
import org.horizon.util.Util;
import org.testng.annotations.Test;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
@Test(groups = "unit")
public abstract class BaseAlgorithmTest {
@@ -176,85 +177,53 @@
EasyMock.verify(mockAction);
}
- public void testTimeToLive1() throws Exception {
+ public void testRemoveEvent() throws Exception {
EvictionAlgorithmConfigBase config = getNewEvictionAlgorithmConfig();
- config.setTimeToLive(-1);
+ config.setMinTimeToLive(24 * 60 * 60, TimeUnit.SECONDS); // huge - so evictions
wont happen
BlockingQueue<EvictionEvent> eventQueue = new
LinkedBlockingQueue<EvictionEvent>();
- eventQueue.put(new EvictionEvent("one", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("two", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("three", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("four", ADD_ENTRY_EVENT, 1));
+ eventQueue.put(new EvictionEvent("one", ADD_ENTRY_EVENT));
+ eventQueue.put(new EvictionEvent("two", ADD_ENTRY_EVENT));
+ eventQueue.put(new EvictionEvent("three", ADD_ENTRY_EVENT));
+ eventQueue.put(new EvictionEvent("four", ADD_ENTRY_EVENT));
EvictionAlgorithm algo = createAndInit(config);
- EvictionAction mockAction = EasyMock.createMock(EvictionAction.class);
+ EvictionAction mockAction = EasyMock.createNiceMock(EvictionAction.class);
algo.setEvictionAction(mockAction);
- // Should not select any
- EasyMock.replay(mockAction);
- algo.process(eventQueue);
- EasyMock.verify(mockAction);
-
- }
-
- public void testTimeToLive2() throws Exception {
- EvictionAlgorithmConfigBase config = getNewEvictionAlgorithmConfig();
- config.setTimeToLive(0);
- BlockingQueue<EvictionEvent> eventQueue = new
LinkedBlockingQueue<EvictionEvent>();
- eventQueue.put(new EvictionEvent("one", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("two", ADD_ENTRY_EVENT,
System.currentTimeMillis() * 2));
- eventQueue.put(new EvictionEvent("three", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("four", ADD_ENTRY_EVENT,
System.currentTimeMillis() * 2));
- EvictionAlgorithm algo = createAndInit(config);
- EvictionAction mockAction = EasyMock.createMock(EvictionAction.class);
- algo.setEvictionAction(mockAction);
-
- // only the first one is selected since the others are not considered since max
entries has not been hit.
+ // should prune down to equal to maxEntries
EasyMock.expect(mockAction.evict(eq("one"))).andReturn(true).once();
EasyMock.replay(mockAction);
algo.process(eventQueue);
- EasyMock.verify(mockAction);
- }
- public void testMaxAge1() throws Exception {
- EvictionAlgorithmConfigBase config = getNewEvictionAlgorithmConfig();
- config.setMaxAge(-1);
- BlockingQueue<EvictionEvent> eventQueue = new
LinkedBlockingQueue<EvictionEvent>();
- eventQueue.put(new EvictionEvent("one", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("two", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("three", ADD_ENTRY_EVENT, 1));
- eventQueue.put(new EvictionEvent("four", ADD_ENTRY_EVENT, 1));
- EvictionAlgorithm algo = createAndInit(config);
- EvictionAction mockAction = EasyMock.createMock(EvictionAction.class);
- algo.setEvictionAction(mockAction);
+ assert algo.getEvictionQueue().size() == 4;
- // Should not select any
- EasyMock.replay(mockAction);
+ eventQueue.put(new EvictionEvent("three", REMOVE_ENTRY_EVENT));
algo.process(eventQueue);
- EasyMock.verify(mockAction);
-
+ assert algo.getEvictionQueue().size() == 3;
+ assert algo.getEvictionQueue().get("three") == null;
}
- public void testMaxAge2() throws Exception {
+ public void testClearEvent() throws Exception {
EvictionAlgorithmConfigBase config = getNewEvictionAlgorithmConfig();
- config.setMaxAge(10);
+ config.setMinTimeToLive(24 * 60 * 60, TimeUnit.SECONDS); // huge - so evictions
wont happen
BlockingQueue<EvictionEvent> eventQueue = new
LinkedBlockingQueue<EvictionEvent>();
eventQueue.put(new EvictionEvent("one", ADD_ENTRY_EVENT));
eventQueue.put(new EvictionEvent("two", ADD_ENTRY_EVENT));
eventQueue.put(new EvictionEvent("three", ADD_ENTRY_EVENT));
eventQueue.put(new EvictionEvent("four", ADD_ENTRY_EVENT));
- Thread.sleep(10);
EvictionAlgorithm algo = createAndInit(config);
- EvictionAction mockAction = EasyMock.createMock(EvictionAction.class);
+ EvictionAction mockAction = EasyMock.createNiceMock(EvictionAction.class);
algo.setEvictionAction(mockAction);
- // all of them should have crossed max age by now
+ // should prune down to equal to maxEntries
EasyMock.expect(mockAction.evict(eq("one"))).andReturn(true).once();
- EasyMock.expect(mockAction.evict(eq("two"))).andReturn(true).once();
- EasyMock.expect(mockAction.evict(eq("three"))).andReturn(true).once();
- EasyMock.expect(mockAction.evict(eq("four"))).andReturn(true).once();
EasyMock.replay(mockAction);
algo.process(eventQueue);
- EasyMock.verify(mockAction);
- }
+ assert algo.getEvictionQueue().size() == 4;
+ eventQueue.put(new EvictionEvent("three", CLEAR_CACHE_EVENT));
+ algo.process(eventQueue);
+ assert algo.getEvictionQueue().size() == 0;
+ assert algo.getEvictionQueue().get("three") == null;
+ }
}