JBoss Cache SVN: r7628 - in core/branches/flat/src/main/java/org/horizon/eviction/algorithms: nullalgo and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-02 21:16:01 -0500 (Mon, 02 Feb 2009)
New Revision: 7628
Added:
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/
Removed:
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null/
Modified:
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionQueue.java
Log:
Eviction overhaul, phase 1
Copied: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo (from rev 7627, core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null)
Property changes on: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null/NullEvictionAlgorithm.java 2009-02-03 02:12:24 UTC (rev 7627)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionAlgorithm.java 2009-02-03 02:16:01 UTC (rev 7628)
@@ -19,7 +19,7 @@
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.horizon.eviction.algorithms.NULL;
+package org.horizon.eviction.algorithms.nullalgo;
import org.horizon.Cache;
import org.horizon.config.EvictionAlgorithmConfig;
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null/NullEvictionAlgorithmConfig.java 2009-02-03 02:12:24 UTC (rev 7627)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionAlgorithmConfig.java 2009-02-03 02:16:01 UTC (rev 7628)
@@ -19,7 +19,7 @@
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.horizon.eviction.algorithms.NULL;
+package org.horizon.eviction.algorithms.nullalgo;
import org.horizon.config.AbstractNamedCacheConfigurationBean;
import org.horizon.config.ConfigurationException;
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null/NullEvictionQueue.java 2009-02-03 02:12:24 UTC (rev 7627)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/nullalgo/NullEvictionQueue.java 2009-02-03 02:16:01 UTC (rev 7628)
@@ -19,7 +19,7 @@
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.horizon.eviction.algorithms.NULL;
+package org.horizon.eviction.algorithms.nullalgo;
import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionQueue;
15 years, 11 months
JBoss Cache SVN: r7627 - core/branches/flat/src/main/java/org/horizon/eviction/algorithms.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-02 21:12:24 -0500 (Mon, 02 Feb 2009)
New Revision: 7627
Added:
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null/
Removed:
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/
Log:
changed case
Copied: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/null (from rev 7626, core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL)
15 years, 11 months
JBoss Cache SVN: r7626 - core/branches/flat/src/test/java/org/horizon/eviction.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-02 21:11:34 -0500 (Mon, 02 Feb 2009)
New Revision: 7626
Modified:
core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java
Log:
Eviction overhaul, phase 1
Modified: core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java 2009-02-03 02:11:20 UTC (rev 7625)
+++ core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java 2009-02-03 02:11:34 UTC (rev 7626)
@@ -16,7 +16,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-@Test(groups = "functional", sequential = true)
+@Test(groups = "functional", sequential = true, enabled = false)
public class EvictionFunctionalTest {
Cache cache;
EvictionListener el;
15 years, 11 months
JBoss Cache SVN: r7625 - in core/branches/flat/src: main/java/org/horizon/config and 23 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-02 21:11:20 -0500 (Mon, 02 Feb 2009)
New Revision: 7625
Added:
core/branches/flat/src/main/java/org/horizon/eviction/EntryEvictionData.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionManager.java
core/branches/flat/src/test/java/org/horizon/eviction/
core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java
core/branches/flat/src/test/java/org/horizon/eviction/EvictionManagerTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoAlgorithmTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoQueueTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuAlgorithmTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuQueueTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruAlgorithmTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruQueueTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruAlgorithmTest.java
core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruQueueTest.java
Removed:
core/branches/flat/src/main/java/org/horizon/EvictionManager.java
core/branches/flat/src/main/java/org/horizon/config/EvictionCacheConfig.java
core/branches/flat/src/main/java/org/horizon/config/MissingPolicyException.java
core/branches/flat/src/main/java/org/horizon/config/parsing/element/EvictionElementParser.java
core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManager.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManagerImpl.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionTimerTask.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionWatcher.java
core/branches/flat/src/main/java/org/horizon/eviction/ExpirationAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/KeyEntry.java
core/branches/flat/src/main/java/org/horizon/eviction/RegionNameConflictException.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ElementSizeAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ExpirationAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionListEntry.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionQueueList.java
Modified:
core/branches/flat/src/main/java/org/horizon/CacheDelegate.java
core/branches/flat/src/main/java/org/horizon/CacheSPI.java
core/branches/flat/src/main/java/org/horizon/config/Configuration.java
core/branches/flat/src/main/java/org/horizon/config/EvictionAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/config/EvictionConfig.java
core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
core/branches/flat/src/main/java/org/horizon/eviction/DefaultEvictionAction.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAction.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithmConfigBase.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionEvent.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionManagerImpl.java
core/branches/flat/src/main/java/org/horizon/eviction/EvictionQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/RemoveOnEvictActionPolicy.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseEvictionAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseSortedEvictionAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/SortedEvictionQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUQueue.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithm.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithmConfig.java
core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUQueue.java
core/branches/flat/src/main/java/org/horizon/factories/AbstractComponentRegistry.java
core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java
core/branches/flat/src/main/java/org/horizon/factories/EvictionManagerFactory.java
core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java
core/branches/flat/src/main/java/org/horizon/factories/KnownComponentNames.java
core/branches/flat/src/main/java/org/horizon/factories/NamedExecutorsFactory.java
core/branches/flat/src/main/java/org/horizon/factories/TransactionManagerFactory.java
core/branches/flat/src/main/java/org/horizon/interceptors/EvictionInterceptor.java
core/branches/flat/src/main/resources/config-samples/all.xml
core/branches/flat/src/test/java/org/horizon/api/batch/BatchWithTMTest.java
core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java
core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java
Log:
Eviction overhaul, phase 1
Modified: core/branches/flat/src/main/java/org/horizon/CacheDelegate.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/CacheDelegate.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/CacheDelegate.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -38,6 +38,7 @@
import org.horizon.config.ConfigurationException;
import org.horizon.container.DataContainer;
import org.horizon.context.InvocationContext;
+import org.horizon.eviction.EvictionManager;
import org.horizon.factories.ComponentRegistry;
import org.horizon.factories.annotations.Inject;
import org.horizon.factories.annotations.NonVolatile;
@@ -263,9 +264,6 @@
public void stop() {
componentRegistry.stop();
- if (config.isUsingEviction()) {
- evictionManager.cacheStopped(getName());
- }
}
private InvocationContext buildCtx() {
Modified: core/branches/flat/src/main/java/org/horizon/CacheSPI.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/CacheSPI.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/CacheSPI.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -23,6 +23,7 @@
import net.jcip.annotations.ThreadSafe;
import org.horizon.batch.BatchContainer;
+import org.horizon.eviction.EvictionManager;
import org.horizon.factories.ComponentRegistry;
import org.horizon.interceptors.base.CommandInterceptor;
import org.horizon.loader.CacheLoader;
Deleted: core/branches/flat/src/main/java/org/horizon/EvictionManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/EvictionManager.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/EvictionManager.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,38 +0,0 @@
-package org.horizon;
-
-import net.jcip.annotations.ThreadSafe;
-import org.horizon.eviction.EvictionCacheManager;
-import org.horizon.factories.annotations.NonVolatile;
-import org.horizon.factories.scopes.Scope;
-import org.horizon.factories.scopes.Scopes;
-
-/**
- * @author Mircea.Markus(a)jboss.com
- * @since 1.0
- */
-@ThreadSafe
-@NonVolatile
-(a)Scope(Scopes.NAMED_CACHE)
-public interface EvictionManager {
- /**
- * Whenever a new cache is created this method should be called. If this cache does not have eviction enabled then
- * this is a no-op. If the cache has eviction enabled then it is reistered for receivinge eviction information. If
- * this is the first cache that requires eviction, the eviction theread will be started.
- *
- * @param cacheName
- * @param cacheManager newly create cache.
- */
- public void cacheCreated(String cacheName, EvictionCacheManager cacheManager);
-
-
- /**
- * Whenever a cache will be stoped this method should be called. If the given cache doesn't have eviction enabled
- * this is an no-op. If this is the only cache that has eviction enabled, then the eviction thread will be stopped.
- * After calling this method the given cache will be unregistered from eviction events.
- *
- * @param cacheName
- */
- public void cacheStopped(String cacheName);
-
- public void runEviction();
-}
Modified: core/branches/flat/src/main/java/org/horizon/config/Configuration.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/Configuration.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/Configuration.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -28,9 +28,8 @@
import org.horizon.util.ReflectionUtil;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
+import java.util.concurrent.TimeUnit;
/**
* Encapsulates the configuration of a Cache.
@@ -41,20 +40,11 @@
@NonVolatile
public class Configuration extends AbstractNamedCacheConfigurationBean {
private static final long serialVersionUID = 5553791890144997466L;
- private boolean invocationBatchingEnabled;
- private Map<String, EvictionCacheConfig> evictionCacheConfigs = new HashMap<String, EvictionCacheConfig>(4);
+ // reference to a global configuration
private GlobalConfiguration globalConfiguration;
- private boolean useAsyncSerialization = true;
- public EvictionCacheConfig getEvictionCacheConfig(String cacheName) {
- return evictionCacheConfigs.values().iterator().next();
- }
- public void addEvictionCacheConfig(String cacheName, EvictionCacheConfig ecc) {
- evictionCacheConfigs.put(cacheName, ecc);
- }
-
public GlobalConfiguration getGlobalConfiguration() {
return globalConfiguration;
}
@@ -114,11 +104,8 @@
// CONFIGURATION OPTIONS
// ------------------------------------------------------------------------------------------------------------
-
private boolean useReplQueue = false;
- @Dynamic
private int replQueueMaxElements = 1000;
- @Dynamic
private long replQueueInterval = 5000;
private boolean exposeManagementStatistics = true;
@Dynamic
@@ -128,11 +115,9 @@
@Dynamic
private long syncReplTimeout = 15000;
private CacheMode cacheMode = CacheMode.LOCAL;
- private boolean inactiveOnStartup = false;
@Dynamic
private long stateRetrievalTimeout = 10000;
private IsolationLevel isolationLevel = IsolationLevel.READ_COMMITTED;
- @Dynamic
private EvictionConfig evictionConfig = null;
private String transactionManagerLookupClass = null;
private CacheLoaderConfig cacheLoaderConfig = null;
@@ -140,12 +125,12 @@
private boolean syncCommitPhase = false;
@Dynamic
private boolean syncRollbackPhase = false;
-
- private transient RuntimeConfig runtimeConfig;
private boolean useLazyDeserialization = false;
private List<CustomInterceptorConfig> customInterceptors = Collections.emptyList();
private boolean writeSkewCheck = false;
private int concurrencyLevel = 500;
+ private boolean invocationBatchingEnabled;
+ private boolean useAsyncSerialization = true;
@Start(priority = 1)
private void correctIsolationLevels() {
@@ -193,6 +178,11 @@
this.replQueueInterval = replQueueInterval;
}
+ public void setReplQueueInterval(long replQueueInterval, TimeUnit timeUnit) {
+ setReplQueueInterval(timeUnit.toMillis(replQueueInterval));
+ }
+
+
public void setExposeManagementStatistics(boolean useMbean) {
testImmutability("exposeManagementStatistics");
this.exposeManagementStatistics = useMbean;
@@ -220,11 +210,19 @@
this.lockAcquisitionTimeout = lockAcquisitionTimeout;
}
+ public void setLockAcquisitionTimeout(long lockAcquisitionTimeout, TimeUnit timeUnit) {
+ setLockAcquisitionTimeout(timeUnit.toMillis(lockAcquisitionTimeout));
+ }
+
public void setSyncReplTimeout(long syncReplTimeout) {
testImmutability("syncReplTimeout");
this.syncReplTimeout = syncReplTimeout;
}
+ public void setSyncReplTimeout(long syncReplTimeout, TimeUnit timeUnit) {
+ setSyncReplTimeout(timeUnit.toMillis(syncReplTimeout));
+ }
+
public void setCacheMode(CacheMode cacheModeInt) {
testImmutability("cacheMode");
this.cacheMode = cacheModeInt;
@@ -248,11 +246,6 @@
setCacheMode(cacheMode);
}
- public void setInactiveOnStartup(boolean inactiveOnStartup) {
- testImmutability("inactiveOnStartup");
- this.inactiveOnStartup = inactiveOnStartup;
- }
-
public EvictionConfig getEvictionConfig() {
return evictionConfig;
}
@@ -297,6 +290,10 @@
this.stateRetrievalTimeout = stateRetrievalTimeout;
}
+ public void setStateRetrievalTimeout(long stateRetrievalTimeout, TimeUnit timeUnit) {
+ setStateRetrievalTimeout(timeUnit.toMillis(stateRetrievalTimeout));
+ }
+
public void setIsolationLevel(String isolationLevel) {
testImmutability("isolationLevel");
if (isolationLevel == null) throw new ConfigurationException("Isolation level cannot be null", "IsolationLevel");
@@ -362,10 +359,6 @@
return cacheMode;
}
- public boolean isInactiveOnStartup() {
- return inactiveOnStartup;
- }
-
public IsolationLevel getIsolationLevel() {
return isolationLevel;
}
@@ -394,24 +387,6 @@
return useLazyDeserialization;
}
- public synchronized RuntimeConfig getRuntimeConfig() {
- if (runtimeConfig == null) {
- setRuntimeConfig(new RuntimeConfig(), false);
- }
- return runtimeConfig;
- }
-
- public void setRuntimeConfig(RuntimeConfig runtimeConfig) {
- setRuntimeConfig(runtimeConfig, true);
- }
-
- private void setRuntimeConfig(RuntimeConfig runtimeConfig, boolean testImmutability) {
- if (testImmutability) {
- testImmutability("runtimeConfig");
- }
- this.runtimeConfig = runtimeConfig;
- }
-
// ------------------------------------------------------------------------------------------------------------
// HELPERS
// ------------------------------------------------------------------------------------------------------------
@@ -429,7 +404,6 @@
if (exposeManagementStatistics != that.exposeManagementStatistics) return false;
if (fetchInMemoryState != that.fetchInMemoryState) return false;
- if (inactiveOnStartup != that.inactiveOnStartup) return false;
if (lockAcquisitionTimeout != that.lockAcquisitionTimeout) return false;
if (replQueueInterval != that.replQueueInterval) return false;
if (replQueueMaxElements != that.replQueueMaxElements) return false;
@@ -445,7 +419,6 @@
if (evictionConfig != null ? !evictionConfig.equals(that.evictionConfig) : that.evictionConfig != null)
return false;
if (isolationLevel != that.isolationLevel) return false;
- if (runtimeConfig != null ? !runtimeConfig.equals(that.runtimeConfig) : that.runtimeConfig != null) return false;
if (transactionManagerLookupClass != null ? !transactionManagerLookupClass.equals(that.transactionManagerLookupClass) : that.transactionManagerLookupClass != null)
return false;
@@ -463,7 +436,6 @@
result = 31 * result + (int) (lockAcquisitionTimeout ^ (lockAcquisitionTimeout >>> 32));
result = 31 * result + (int) (syncReplTimeout ^ (syncReplTimeout >>> 32));
result = 31 * result + (cacheMode != null ? cacheMode.hashCode() : 0);
- result = 31 * result + (inactiveOnStartup ? 1 : 0);
result = 31 * result + (int) (stateRetrievalTimeout ^ (stateRetrievalTimeout >>> 32));
result = 31 * result + (isolationLevel != null ? isolationLevel.hashCode() : 0);
result = 31 * result + (evictionConfig != null ? evictionConfig.hashCode() : 0);
@@ -471,7 +443,6 @@
result = 31 * result + (cacheLoaderConfig != null ? cacheLoaderConfig.hashCode() : 0);
result = 31 * result + (syncCommitPhase ? 1 : 0);
result = 31 * result + (syncRollbackPhase ? 1 : 0);
- result = 31 * result + (runtimeConfig != null ? runtimeConfig.hashCode() : 0);
result = 31 * result + (useLazyDeserialization ? 1 : 0);
return result;
@@ -487,11 +458,6 @@
if (cacheLoaderConfig != null) {
c.setCacheLoaderConfig(cacheLoaderConfig.clone());
}
- if (runtimeConfig != null) {
- c.setRuntimeConfig(runtimeConfig.clone());
- // always make sure we reset the runtime when cloning.
- c.getRuntimeConfig().reset();
- }
return c;
}
catch (CloneNotSupportedException e) {
Modified: core/branches/flat/src/main/java/org/horizon/config/EvictionAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/EvictionAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/EvictionAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -55,7 +55,7 @@
/**
* @return a clone of the EvictionAlgorithmConfig.
*/
- EvictionAlgorithmConfig clone() throws CloneNotSupportedException;
+ EvictionAlgorithmConfig clone();
- public long getMinTimeToLive();
+
}
Deleted: core/branches/flat/src/main/java/org/horizon/config/EvictionCacheConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/EvictionCacheConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/EvictionCacheConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,115 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.config;
-
-import org.horizon.logging.LogFactory;
-
-public class EvictionCacheConfig extends AbstractNamedCacheConfigurationBean {
- /**
- * The serialVersionUID
- */
- private static final long serialVersionUID = -5482474634995601400L;
-
- public static final String NAME = "name";
- public static final String REGION = "region";
-
- @Dynamic
- private Integer eventQueueSize;
- private EvictionAlgorithmConfig evictionAlgorithmConfig;
- private String evictionActionClassName;
-
- public EvictionCacheConfig(EvictionAlgorithmConfig evictionAlgorithmConfig) {
- eventQueueSize = EvictionConfig.EVENT_QUEUE_SIZE_DEFAULT;
- evictionActionClassName = EvictionConfig.EVICTION_ACTION_CLASS_DEFAULT;
- this.evictionAlgorithmConfig = evictionAlgorithmConfig;
- }
-
- public EvictionCacheConfig(Integer eventQueueSize, EvictionAlgorithmConfig evictionAlgorithmConfig, String evictionActionClassName) {
- this.eventQueueSize = eventQueueSize;
- this.evictionAlgorithmConfig = evictionAlgorithmConfig;
- this.evictionActionClassName = evictionActionClassName;
- }
-
- public void setEventQueueSize(int queueSize) {
- testImmutability("eventQueueSize");
- if (queueSize <= 0) {
- LogFactory.getLog(EvictionCacheConfig.class).warn("Ignoring invalid queue capacity " +
- queueSize + " -- using " +
- EvictionConfig.EVENT_QUEUE_SIZE_DEFAULT);
- queueSize = EvictionConfig.EVENT_QUEUE_SIZE_DEFAULT;
- }
- this.eventQueueSize = queueSize;
- }
-
- /**
- * Ensure this is a valid eviction region configuration.
- */
- public void validate() {
- if (eventQueueSize < 1)
- throw new ConfigurationException("Eviction event queue size cannot be less than 1!");
-
- if (evictionAlgorithmConfig == null)
- throw new MissingPolicyException("Eviction algorithm configuration cannot be null!");
-
- evictionAlgorithmConfig.validate();
- }
-
-
- public Integer getEventQueueSize() {
- return eventQueueSize;
- }
-
- public EvictionAlgorithmConfig getEvictionAlgorithmConfig() {
- return evictionAlgorithmConfig;
- }
-
- public String getEvictionActionClassName() {
- return evictionActionClassName;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- EvictionCacheConfig that = (EvictionCacheConfig) o;
-
- if (eventQueueSize != null ? !eventQueueSize.equals(that.eventQueueSize) : that.eventQueueSize != null)
- return false;
- if (evictionActionClassName != null ? !evictionActionClassName.equals(that.evictionActionClassName) : that.evictionActionClassName != null)
- return false;
- if (evictionAlgorithmConfig != null ? !evictionAlgorithmConfig.equals(that.evictionAlgorithmConfig) : that.evictionAlgorithmConfig != null)
- return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result;
- result = (eventQueueSize != null ? eventQueueSize.hashCode() : 0);
- result = 31 * result + (evictionAlgorithmConfig != null ? evictionAlgorithmConfig.hashCode() : 0);
- result = 31 * result + (evictionActionClassName != null ? evictionActionClassName.hashCode() : 0);
- return result;
- }
-
-}
\ No newline at end of file
Modified: core/branches/flat/src/main/java/org/horizon/config/EvictionConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/EvictionConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/EvictionConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -23,8 +23,6 @@
import org.horizon.eviction.DefaultEvictionAction;
-import java.util.LinkedList;
-import java.util.List;
import java.util.concurrent.TimeUnit;
public class EvictionConfig extends AbstractNamedCacheConfigurationBean {
@@ -33,180 +31,102 @@
*/
private static final long serialVersionUID = -7979639000026975201L;
- public static final int WAKEUP_DEFAULT = 5000;
- public static final int EVENT_QUEUE_SIZE_DEFAULT = 200000;
- public static final String EVICTION_ACTION_CLASS_DEFAULT = DefaultEvictionAction.class.getName();
-
/**
- * value expressed in millis
+ * Wake up interval, in milliseconds
*/
- @Dynamic
- private long wakeupInterval = WAKEUP_DEFAULT;
+ private long wakeUpInterval = 5000; // 5 second default
+ private EvictionAlgorithmConfig algorithmConfig;
+ private int eventQueueSize = 200000; // 200,000 default
+ private String actionPolicyClass = DefaultEvictionAction.class.getName();
- private int defaultEventQueueSize = EVENT_QUEUE_SIZE_DEFAULT;
-
- // Dynamic to support runtime adds/removes of regions
- @Dynamic
- private List<EvictionCacheConfig> evictionCacheConfigs;
- private EvictionCacheConfig defaultEvictionCacheConfig;
-
public EvictionConfig() {
-// evictionCacheConfigs = new LinkedList<EvictionCacheConfig>();
-// defaultEvictionCacheConfig = new EvictionCacheConfig(ROOT);
-// defaultEvictionCacheConfig.setEventQueueSize(EVENT_QUEUE_SIZE_DEFAULT);
-// defaultEvictionCacheConfig.setEvictionActionClassName(DefaultEvictionAction.class.getName());
}
- public EvictionConfig(EvictionCacheConfig defaultEvictionCacheConfig) {
- evictionCacheConfigs = new LinkedList<EvictionCacheConfig>();
-// try
-// {
-// this.defaultEvictionCacheConfig = defaultEvictionCacheConfig.clone();
-// }
-// catch (CloneNotSupportedException e)
-// {
-// throw new ConfigurationException(e);
-// }
- this.defaultEvictionCacheConfig.setEventQueueSize(EVENT_QUEUE_SIZE_DEFAULT);
-// if (this.defaultEvictionCacheConfig.getEvictionActionClassName() == null)
-// this.defaultEvictionCacheConfig.setEvictionActionClassName(DefaultEvictionAction.class.getName());
+ public long getWakeUpInterval() {
+ return wakeUpInterval;
}
- public EvictionConfig(EvictionCacheConfig defaultEvictionCacheConfig, int wakeupInterval) {
- this(defaultEvictionCacheConfig);
- this.wakeupInterval = wakeupInterval;
+ public void setWakeUpInterval(long wakeUpInterval) {
+ testImmutability("wakeUpInterval");
+ this.wakeUpInterval = wakeUpInterval;
}
- public boolean isValidConfig() {
- return (defaultEvictionCacheConfig != null && defaultEvictionCacheConfig.getEvictionActionClassName() != null && defaultEvictionCacheConfig.getEvictionAlgorithmConfig() != null)
- || (evictionCacheConfigs != null && evictionCacheConfigs.size() > 0);
+ public void setWakeupInterval(long time, TimeUnit timeUnit) {
+ setWakeUpInterval(timeUnit.toMillis(time));
}
- public EvictionCacheConfig getDefaultEvictionRegionConfig() {
- return defaultEvictionCacheConfig;
+ public EvictionAlgorithmConfig getAlgorithmConfig() {
+ return algorithmConfig;
}
- public void setDefaultEvictionRegionConfig(EvictionCacheConfig defaultEvictionCacheConfig) {
- this.defaultEvictionCacheConfig = defaultEvictionCacheConfig;
-// this.defaultEvictionCacheConfig.setEventQueueSizeIfUnset(EVENT_QUEUE_SIZE_DEFAULT);
+ public void setAlgorithmConfig(EvictionAlgorithmConfig algorithmConfig) {
+ this.algorithmConfig = algorithmConfig;
}
- public List<EvictionCacheConfig> getEvictionCacheConfigs() {
- return evictionCacheConfigs;
+ public int getEventQueueSize() {
+ return eventQueueSize;
}
- public void setEvictionRegionConfigs(List<EvictionCacheConfig> evictionCacheConfigs) {
- testImmutability("evictionCacheConfigs");
- EvictionCacheConfig toRemove = null;
- for (EvictionCacheConfig erc : evictionCacheConfigs) {
-// if (erc.getCacheName().isRoot() || erc.getCacheName().equals(RegionManagerImpl.DEFAULT_REGION))
-// {
-// mergeWithDefault(erc);
-// toRemove = erc;
-// break;
-// }
- }
-
- if (toRemove != null) evictionCacheConfigs.remove(toRemove);
-
- this.evictionCacheConfigs = evictionCacheConfigs;
+ public void setEventQueueSize(int eventQueueSize) {
+ testImmutability("eventQueueSize");
+ this.eventQueueSize = eventQueueSize;
}
- private void mergeWithDefault(EvictionCacheConfig erc) {
-// erc.setEventQueueSizeIfUnset(defaultEvictionCacheConfig.getEventQueueSize());
-// if (erc.getEvictionAlgorithmConfig() == null)
-// erc.setEvictionAlgorithmConfig(defaultEvictionCacheConfig.getEvictionAlgorithmConfig());
-// defaultEvictionCacheConfig = erc;
+ public String getActionPolicyClass() {
+ return actionPolicyClass;
}
- public void addEvictionRegionConfig(EvictionCacheConfig evictionCacheConfig) {
- testImmutability("evictionCacheConfigs");
-// if (evictionCacheConfig.getCacheName().isRoot() || evictionCacheConfig.getCacheName().equals(RegionManagerImpl.DEFAULT_REGION))
-// {
-// mergeWithDefault(evictionCacheConfig);
-// }
-// else
-// {
-// evictionCacheConfigs.add(evictionCacheConfig);
-// }
+ public void setActionPolicyClass(String actionPolicyClass) {
+ testImmutability("actionPolicyClass");
+ this.actionPolicyClass = actionPolicyClass;
}
- /**
- * @return the wake up interval of the eviction thread, in milliseconds.
- */
- public long getWakeupInterval() {
- return wakeupInterval;
- }
-
- /**
- * Set the wake up interval for the eviction thread. 0 or a negative number disables the eviction thread.
- *
- * @param wakeupInterval interval, in milliseconds.
- */
- public void setWakeupInterval(long wakeupInterval) {
- testImmutability("wakeupInterval");
- this.wakeupInterval = wakeupInterval;
- }
-
- /**
- * Set the wake up interval for the eviction thread. 0 or a negative number disables the eviction thread.
- *
- * @param wakeupInterval interval
- * @param timeUnit for the interval provided
- */
- public void setWakeupInterval(long wakeupInterval, TimeUnit timeUnit) {
- testImmutability("wakeupInterval");
- this.wakeupInterval = timeUnit.toMillis(wakeupInterval);
- }
-
+ @Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof EvictionConfig)) return false;
+ if (o == null || getClass() != o.getClass()) return false;
EvictionConfig that = (EvictionConfig) o;
- if (defaultEventQueueSize != that.defaultEventQueueSize) return false;
- if (wakeupInterval != that.wakeupInterval) return false;
- if (defaultEvictionCacheConfig != null ? !defaultEvictionCacheConfig.equals(that.defaultEvictionCacheConfig) : that.defaultEvictionCacheConfig != null)
+ if (eventQueueSize != that.eventQueueSize) return false;
+ if (wakeUpInterval != that.wakeUpInterval) return false;
+ if (actionPolicyClass != null ? !actionPolicyClass.equals(that.actionPolicyClass) : that.actionPolicyClass != null)
return false;
- if (evictionCacheConfigs != null ? !evictionCacheConfigs.equals(that.evictionCacheConfigs) : that.evictionCacheConfigs != null)
+ if (algorithmConfig != null ? !algorithmConfig.equals(that.algorithmConfig) : that.algorithmConfig != null)
return false;
return true;
}
+ @Override
public int hashCode() {
- int result;
- result = 31 + (int) (wakeupInterval ^ (wakeupInterval >>> 32));
- result = 31 * result + defaultEventQueueSize;
- result = 31 * result + (evictionCacheConfigs != null ? evictionCacheConfigs.hashCode() : 0);
+ int result = (int) (wakeUpInterval ^ (wakeUpInterval >>> 32));
+ result = 31 * result + (algorithmConfig != null ? algorithmConfig.hashCode() : 0);
+ result = 31 * result + eventQueueSize;
+ result = 31 * result + (actionPolicyClass != null ? actionPolicyClass.hashCode() : 0);
return result;
}
@Override
- public EvictionConfig clone() throws CloneNotSupportedException {
- EvictionConfig clone = (EvictionConfig) super.clone();
- if (evictionCacheConfigs != null) {
- // needs to be a deep copy
- clone.evictionCacheConfigs = new LinkedList<EvictionCacheConfig>();
-// for (EvictionCacheConfig erc : evictionCacheConfigs)
-// clone.addEvictionRegionConfig(erc.clone());
- }
- return clone;
+ public String toString() {
+ return "EvictionConfig{" +
+ "wakeUpInterval=" + wakeUpInterval +
+ ", algorithmConfig=" + algorithmConfig +
+ ", eventQueueSize=" + eventQueueSize +
+ ", actionPolicyClass='" + actionPolicyClass + '\'' +
+ '}';
}
-
- public EvictionCacheConfig getEvictionRegionConfig(String region) {
- return null;
+ public EvictionConfig clone() {
+ try {
+ EvictionConfig clone = (EvictionConfig) super.clone();
+ clone.actionPolicyClass = actionPolicyClass;
+ if (algorithmConfig != null) clone.algorithmConfig = algorithmConfig.clone();
+ clone.eventQueueSize = eventQueueSize;
+ clone.wakeUpInterval = wakeUpInterval;
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Should never happen", e);
+ }
}
-
- /**
- * Applies defaults to a config passed in
- *
- * @param config config to apply defaults to
- */
- public void applyDefaults(EvictionCacheConfig config) {
-// if (config == null) return; // no op
-// config.setDefaults(defaultEvictionCacheConfig);
- }
}
Deleted: core/branches/flat/src/main/java/org/horizon/config/MissingPolicyException.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/MissingPolicyException.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/MissingPolicyException.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,34 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.config;
-
-public class MissingPolicyException extends ConfigurationException {
-
- /**
- * The serialVersionUID
- */
- private static final long serialVersionUID = 6107098975617303157L;
-
- public MissingPolicyException(String message) {
- super(message);
- }
-}
\ No newline at end of file
Modified: core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -5,13 +5,16 @@
import org.horizon.config.ConfigurationException;
import org.horizon.config.CustomInterceptorConfig;
import org.horizon.config.DuplicateCacheNameException;
+import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.config.EvictionConfig;
import org.horizon.config.GlobalConfiguration;
import org.horizon.config.parsing.element.CustomInterceptorsElementParser;
-import org.horizon.config.parsing.element.EvictionElementParser;
import org.horizon.config.parsing.element.LoadersElementParser;
+import org.horizon.eviction.EvictionAlgorithm;
import org.horizon.lock.IsolationLevel;
import org.horizon.transaction.GenericTransactionManagerLookup;
import org.horizon.util.FileLookup;
+import org.horizon.util.Util;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@@ -242,10 +245,40 @@
config.setCacheLoaderConfig(cacheLoaderConfig);
}
- void configureEviction(Element element, Configuration config) {
- if (element == null) return; //no eviction might be configured
- EvictionElementParser evictionElementParser = new EvictionElementParser();
- //config.setEvictionConfig(evictionElementParser.parseEvictionElement(element));
+ void configureEviction(Element evictionElement, Configuration config) {
+ if (evictionElement == null) return; //no eviction might be configured
+ EvictionConfig evictionConfig = new EvictionConfig();
+ String tmp = getAttributeValue(evictionElement, "wakeUpInterval");
+ if (existsAttribute(tmp)) {
+ evictionConfig.setWakeUpInterval(getInt(tmp));
+ }
+
+ tmp = getAttributeValue(evictionElement, "actionPolicyClass");
+ if (existsAttribute(tmp)) evictionConfig.setActionPolicyClass(tmp);
+
+ tmp = getAttributeValue(evictionElement, "eventQueueSize");
+ if (existsAttribute(tmp)) evictionConfig.setEventQueueSize(getInt(tmp));
+
+ tmp = getAttributeValue(evictionElement, "algorithmClass");
+ if (!existsAttribute(tmp))
+ throw new ConfigurationException("Required attribute 'algorithmClass' is missing on the 'eviction' element!");
+
+ Properties p = XmlConfigHelper.extractProperties(evictionElement);
+
+ EvictionAlgorithmConfig cfg;
+
+ try {
+ EvictionAlgorithm algo = (EvictionAlgorithm) Util.getInstance(tmp);
+ Class<? extends EvictionAlgorithmConfig> cfgClass = algo.getConfigurationClass();
+ cfg = Util.getInstance(cfgClass);
+ } catch (Exception e) {
+ throw new ConfigurationException("Unable to configure eviction", e);
+ }
+
+ if (p != null && !p.isEmpty()) XmlConfigHelper.setValues(cfg, p, false, true);
+
+ evictionConfig.setAlgorithmConfig(cfg);
+ config.setEvictionConfig(evictionConfig);
}
void configureJmxStatistics(Element element, Configuration config) {
Deleted: core/branches/flat/src/main/java/org/horizon/config/parsing/element/EvictionElementParser.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/parsing/element/EvictionElementParser.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/config/parsing/element/EvictionElementParser.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,181 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.config.parsing.element;
-
-import org.horizon.config.ConfigurationException;
-import org.horizon.config.EvictionAlgorithmConfig;
-import org.horizon.config.EvictionCacheConfig;
-import org.horizon.config.EvictionConfig;
-import org.horizon.config.MissingPolicyException;
-import org.horizon.config.parsing.XmlConfigHelper;
-import org.horizon.config.parsing.XmlParserBase;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Knows how to parse the <b>eviction</b> xml element.
- * <pre>
- * Note: class does not rely on element position in the configuration file.
- * It does not rely on element's name either.
- * </pre>
- *
- * @author Mircea.Markus(a)jboss.com
- * @since 1.0
- */
-public class EvictionElementParser extends XmlParserBase {
- public EvictionConfig parseEvictionElement(Element evictionElement) {
- EvictionConfig evictionConfig = new EvictionConfig();
- String wakeUpInterval = getAttributeValue(evictionElement, "wakeUpInterval");
- if (existsAttribute(wakeUpInterval)) {
- evictionConfig.setWakeupInterval(getInt(wakeUpInterval));
- } else {
- throw new ConfigurationException("Missing mandatory attribute wakeUpInterval");
- }
-
- List<EvictionCacheConfig> evictionCacheConfigs = new LinkedList<EvictionCacheConfig>();
- Element defaultRegion = getSingleElementInCoreNS("default", evictionElement);
-
- if (defaultRegion != null) {
- EvictionCacheConfig defaultCacheConfig = getEvictionRegionConfig(defaultRegion, null, true);
- if (defaultCacheConfig.getEvictionAlgorithmConfig() == null)
- throw new MissingPolicyException("Default eviction region should have an evictionAlgorithmClass defined.");
- evictionConfig.setDefaultEvictionRegionConfig(defaultCacheConfig);
- }
-
- NodeList regions = evictionElement.getElementsByTagName("region");
- for (int i = 0; i < regions.getLength(); i++) {
- Element regionConfig = (Element) regions.item(i);
- EvictionCacheConfig erc = getEvictionRegionConfig(regionConfig, evictionConfig.getDefaultEvictionRegionConfig(), false);
- evictionConfig.applyDefaults(erc);
- evictionCacheConfigs.add(erc);
- }
- evictionConfig.setEvictionRegionConfigs(evictionCacheConfigs);
- return evictionConfig;
- }
-
- @SuppressWarnings("unchecked")
- private EvictionCacheConfig getEvictionRegionConfig(Element element, EvictionCacheConfig defaultCache, boolean isDefault) {
-// EvictionCacheConfig erc = new EvictionCacheConfig();
-// erc.setRegionName(getAttributeValue(element, "name"));
-// String queueSize = getAttributeValue(element, "eventQueueSize");
-// if (existsAttribute(queueSize))
-// {
-// erc.setEventQueueSize(getInt(queueSize));
-// }
-// else if (defaultCache == null)
-// {
-// erc.setEventQueueSize(EvictionConfig.EVENT_QUEUE_SIZE_DEFAULT);
-// }
-//
-// String algorithmClassName = getAttributeValue(element, "algorithmClass");
-// EvictionAlgorithmConfig algorithmConfig = null; // every eviction region config needs an algorithm config.
-//
-// if (existsAttribute(algorithmClassName))
-// {
-// EvictionAlgorithm algorithm;
-// Class<? extends EvictionAlgorithm> algorithmClass;
-// // try using a 'getInstance()' factory.
-//
-// try
-// {
-// algorithmClass = Util.loadClass(algorithmClassName);
-// }
-// catch (Exception e)
-// {
-// throw new RuntimeException("Unable to load eviction algorithm class [" + algorithmClassName + "]", e);
-// }
-//
-//
-// try
-// {
-// algorithm = Util.getInstance(algorithmClass);
-// }
-// catch (Exception e)
-// {
-// throw new ConfigurationException("Unable to construct eviction algorithm class [" + algorithmClassName + "]", e);
-// }
-//
-// try
-// {
-// algorithmConfig = (EvictionAlgorithmConfig) Util.getInstance(algorithm.getConfigurationClass());
-// }
-// catch (Exception e)
-// {
-// throw new RuntimeException("Failed to instantiate eviction algorithm configuration class [" +
-// algorithm.getConfigurationClass() + "]", e);
-// }
-// }
-// else
-// {
-// if (!isDefault)
-// {
-// if (defaultCache == null || defaultCache.getEvictionAlgorithmConfig() == null)
-// {
-// throw new MissingPolicyException("There is no Eviction Algorithm Class specified on the region or for the entire cache!");
-// }
-// else
-// {
-// try
-// {
-// algorithmConfig = defaultCache.getEvictionAlgorithmConfig().clone();
-// }
-// catch (CloneNotSupportedException e)
-// {
-// throw new ConfigurationException("Unable to clone eviction algorithm configuration from default", e);
-// }
-// }
-// }
-// }
-//
-// if (algorithmConfig != null)
-// {
-// parseEvictionPolicyConfig(element, algorithmConfig);
-//
-// erc.setEvictionAlgorithmConfig(algorithmConfig);
-// }
-//
-// String actionPolicyClass = getAttributeValue(element, "actionPolicyClass");
-// if (existsAttribute(actionPolicyClass))
-// {
-// erc.setEvictionActionClassName(actionPolicyClass);
-// }
-// else if (defaultCache == null)
-// {
-// // this is the default region. Make sure we set the default EvictionActionPolicyClass.
-// erc.setEvictionActionClassName(EvictionConfig.EVICTION_ACTION_CLASS_DEFAULT);
-// }
-//
-//
-// return erc;
- return null;
- }
-
- public static void parseEvictionPolicyConfig(Element element, EvictionAlgorithmConfig target) {
-// target.reset();
- Properties p = XmlConfigHelper.extractProperties(element);
- XmlConfigHelper.setValues(target, p, false, true);
- }
-}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/DefaultEvictionAction.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/DefaultEvictionAction.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/DefaultEvictionAction.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -31,16 +31,17 @@
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
* @since 1.0
*/
-public class DefaultEvictionAction<K> implements EvictionAction<K> {
+public class DefaultEvictionAction implements EvictionAction {
private static final Log log = LogFactory.getLog(DefaultEvictionAction.class);
private static boolean trace = log.isTraceEnabled();
- private Cache<K, ?> cache;
+ private Cache cache;
- public void setCache(Cache<K, ?> cache) {
+ public void setCache(Cache<?, ?> cache) {
this.cache = cache;
}
- public boolean evict(K key) {
+ @SuppressWarnings("unchecked")
+ public boolean evict(Object key) {
if (trace) log.trace("Attempting to evict cache node with key of {0}", key);
try {
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,114 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction;
-
-import org.horizon.config.ConfigurationException;
-import org.horizon.config.Dynamic;
-import org.horizon.eviction.algorithms.ElementSizeAlgorithm;
-
-/**
- * Configuration for {@link org.horizon.eviction.algorithms.ElementSizeAlgorithm}.
- * <p/>
- * Requires a positive "maxElementsPerNode" value otherwise a ConfigurationException is thrown.
- *
- * @author Manik Surtani
- * @since 1.0
- */
-public class ElementSizeAlgorithmConfig extends EvictionAlgorithmConfigBase {
- /**
- * The serialVersionUID
- */
- private static final long serialVersionUID = 2510593544656833758L;
-
- @Dynamic
- private int maxElementsPerNode;
-
- public ElementSizeAlgorithmConfig() {
- evictionAlgorithmClassName = ElementSizeAlgorithm.class.getName();
- // Force configuration of maxElementsPerNode
- setMaxElementsPerNode(-1);
- }
-
- public ElementSizeAlgorithmConfig(int maxNodes, int maxElementsPerNode) {
- this();
- setMaxNodes(maxNodes);
- setMaxElementsPerNode(maxElementsPerNode);
- }
-
- public int getMaxElementsPerNode() {
- return maxElementsPerNode;
- }
-
- public void setMaxElementsPerNode(int maxElementsPerNode) {
- testImmutability("maxElementsPerNode");
- this.maxElementsPerNode = maxElementsPerNode;
- }
-
- /**
- * Requires a positive maxElementsPerNode value or ConfigurationException is thrown.
- */
- @Override
- public void validate() throws ConfigurationException {
- super.validate();
- if (maxElementsPerNode < 0) {
- throw new ConfigurationException("maxElementsPerNode must be must be " +
- "configured to a value greater than or equal to 0");
- }
- }
-
- @Override
- public String toString() {
- StringBuilder str = new StringBuilder();
- str.append("ElementSizeConfiguration: maxElementsPerNode =");
- str.append(getMaxElementsPerNode()).append(" maxNodes =").append(getMaxNodes());
- return str.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj instanceof ElementSizeAlgorithmConfig && super.equals(obj)) {
- return this.maxElementsPerNode == ((ElementSizeAlgorithmConfig) obj).maxElementsPerNode;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + maxElementsPerNode;
- return result;
- }
-
- @Override
- public void reset() {
- super.reset();
- setMaxElementsPerNode(-1);
- evictionAlgorithmClassName = ElementSizeAlgorithm.class.getName();
- }
-
- @Override
- public ElementSizeAlgorithmConfig clone() throws CloneNotSupportedException {
- return (ElementSizeAlgorithmConfig) super.clone();
- }
-}
\ No newline at end of file
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/ElementSizeQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,176 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction;
-
-import org.horizon.eviction.algorithms.SortedEvictionQueue;
-
-import java.util.*;
-
-/**
- * @author Daniel Huang
- * @since 1.0
- */
-public class ElementSizeQueue<K> implements SortedEvictionQueue<K> {
- private Map<K, KeyEntry<K>> nodeMap;
- private LinkedList<KeyEntry<K>> evictionList;
- private Comparator<KeyEntry> comparator;
-
- private Set<KeyEntry> removalQueue;
- private int numElements = 0;
-
- public ElementSizeQueue() {
- nodeMap = new HashMap<K, KeyEntry<K>>();
- evictionList = new LinkedList<KeyEntry<K>>();
- comparator = new MaxElementComparator();
- removalQueue = new HashSet<KeyEntry>();
- }
-
- public void resortEvictionQueue() {
- Collections.sort(evictionList, comparator);
- }
-
- public KeyEntry<K> getFirstNodeEntry() {
- try {
- KeyEntry<K> ne;
- while ((ne = evictionList.getFirst()) != null) {
- if (removalQueue.contains(ne)) {
- evictionList.removeFirst();
- removalQueue.remove(ne);
- } else {
- break;
- }
- }
- return ne;
- }
- catch (NoSuchElementException e) {
- //
- }
- return null;
- }
-
- public KeyEntry<K> getNodeEntry(K key) {
- return nodeMap.get(key);
- }
-
- public boolean containsNodeEntry(KeyEntry<K> entry) {
- K key = entry.getKey();
- return this.getNodeEntry(key) != null;
- }
-
- public void removeNodeEntry(KeyEntry<K> entry) {
- KeyEntry ne = nodeMap.remove(entry.getKey());
- if (ne != null) {
- // don't remove directly from the LinkedList otherwise we will incur a O(n) = n
- // performance penalty for every removal! In the prune method for LFU, we will iterate the LinkedList through ONCE
- // doing a single O(n) = n operation and removal. This is much preferred over running O(n) = n every single time
- // remove is called. There is also special logic in the getFirstNodeEntry that will know to check
- // the removalQueue before returning.
- this.removalQueue.add(ne);
-/* if(!evictionList.remove(ne)) {
- throw new RuntimeException("");
- } */
- this.numElements -= ne.getNumberOfElements();
- }
- }
-
- public void addNodeEntry(KeyEntry<K> entry) {
- if (!this.containsNodeEntry(entry)) {
- K key = entry.getKey();
- nodeMap.put(key, entry);
- evictionList.add(entry);
- this.numElements += entry.getNumberOfElements();
- }
- }
-
- public int getNumberOfNodes() {
- return nodeMap.size();
- }
-
- public int getNumberOfElements() {
- return this.numElements;
- }
-
- public void modifyElementCount(int difference) {
- this.numElements += difference;
- }
-
- public void clear() {
- nodeMap.clear();
- evictionList.clear();
- removalQueue.clear();
- this.numElements = 0;
- }
-
- protected final List<KeyEntry<K>> getEvictionList() {
- return evictionList;
- }
-
- protected final Set<KeyEntry> getRemovalQueue() {
- return removalQueue;
- }
-
- public final void prune() {
- Iterator<KeyEntry<K>> it = evictionList.iterator();
- while (it.hasNext() && removalQueue.size() > 0) {
- if (removalQueue.remove(it.next())) {
- it.remove();
- }
- }
- }
-
- public Iterator<KeyEntry<K>> iterator() {
- return evictionList.iterator();
- }
-
- /**
- * Comparator class for Max Elements.
- * <p/>
- * This class will sort the eviction queue in the correct eviction order. The top of the list should evict before the
- * bottom of the list.
- * <p/>
- * The sort is based on descending order of numElements.
- * <p/>
- * Note: this class has a natural ordering that is inconsistent with equals as defined by the java.lang.Comparator
- * contract.
- */
- protected static class MaxElementComparator implements Comparator<KeyEntry> {
-
- public int compare(KeyEntry ne1, KeyEntry ne2) {
- if (ne1.equals(ne2)) {
- return 0;
- }
- int neNumElements = ne1.getNumberOfElements();
- int neNumElements2 = ne2.getNumberOfElements();
-
- if (neNumElements > neNumElements2) {
- return -1;
- } else if (neNumElements < neNumElements2) {
- return 1;
- } else if (neNumElements == neNumElements2) {
- return 0;
- }
- throw new RuntimeException("Should never reach this condition");
- }
- }
-}
-
-
Copied: core/branches/flat/src/main/java/org/horizon/eviction/EntryEvictionData.java (from rev 7621, core/branches/flat/src/main/java/org/horizon/eviction/KeyEntry.java)
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EntryEvictionData.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EntryEvictionData.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.horizon.eviction;
+
+/**
+ * Value object used in queue
+ *
+ * @author Ben Wang 2-2004
+ * @author Daniel Huang - dhuang(a)jboss.org
+ * @since 1.0
+ */
+public class EntryEvictionData {
+ private long modifiedTimeStamp;
+ private long creationTimeStamp;
+ private int numberOfVisits;
+ private Object key;
+
+ private long inUseTimeoutTimestamp;
+ private boolean currentlyInUse = false;
+
+ /**
+ * Private constructor that automatically sets the creation time stamp of the node entry.
+ */
+ private EntryEvictionData() {
+ this.creationTimeStamp = System.currentTimeMillis();
+ }
+
+ public EntryEvictionData(Object key) {
+ this();
+ setKey(key);
+ }
+
+ public EntryEvictionData(int numberOfVisits, long modifiedTimeStamp, Object key) {
+ this(key);
+ this.numberOfVisits = numberOfVisits;
+ this.modifiedTimeStamp = modifiedTimeStamp;
+ }
+
+ /**
+ * Is the node currently in use.
+ *
+ * @return true if the node is currently marked as in use.
+ */
+ public boolean isCurrentlyInUse() {
+ return currentlyInUse;
+ }
+
+ public void setCurrentlyInUse(boolean currentlyInUse, long inUseTimeout) {
+ this.currentlyInUse = currentlyInUse;
+ if (inUseTimeout > 0) {
+ this.inUseTimeoutTimestamp = System.currentTimeMillis() + inUseTimeout;
+ }
+ }
+
+ public long getInUseTimeoutTimestamp() {
+ return this.inUseTimeoutTimestamp;
+ }
+
+ /**
+ * Get modified time stamp. This stamp is created during the node is processed so it has some fuzy tolerance in
+ * there.
+ *
+ * @return The last modified time stamp
+ */
+ public long getModifiedTimeStamp() {
+ return modifiedTimeStamp;
+ }
+
+ public void setModifiedTimeStamp(long modifiedTimeStamp) {
+ this.modifiedTimeStamp = modifiedTimeStamp;
+ }
+
+ /**
+ * Get the time stamp for when the node entry was created.
+ *
+ * @return The node entry creation time stamp
+ */
+ public long getCreationTimeStamp() {
+ return creationTimeStamp;
+ }
+
+ public void setCreationTimeStamp(long creationTimeStamp) {
+ this.creationTimeStamp = creationTimeStamp;
+ }
+
+ public int getNumberOfVisits() {
+ return numberOfVisits;
+ }
+
+ public void setNumberOfVisits(int numberOfVisits) {
+ this.numberOfVisits = numberOfVisits;
+ }
+
+ public void incerementNumberOfNodeVisits() {
+ this.numberOfVisits++;
+ }
+
+ public Object getKey() {
+ return key;
+ }
+
+ void setKey(Object key) {
+ this.key = key;
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode();
+ }
+
+ public boolean isNodeInUseAndNotTimedOut() {
+ if (isCurrentlyInUse()) {
+ if (getInUseTimeoutTimestamp() == 0) {
+ return true;
+ }
+
+ if (System.currentTimeMillis() < getInUseTimeoutTimestamp()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof EntryEvictionData))
+ return false;
+ EntryEvictionData ne = (EntryEvictionData) o;
+ return key.equals(ne.getKey());
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+ output.append("Fqn: ");
+ if (key != null) {
+ output.append(key);
+ } else {
+ output.append(" null");
+ }
+
+ output.append(" CreateTime: ").append(this.getCreationTimeStamp());
+ output.append(" Visits: ").append(this.getNumberOfVisits());
+ output.append(" ModifiedTime: ").append(this.getModifiedTimeStamp());
+ output.append(" CurrentlyInUse: ").append(this.isCurrentlyInUse());
+ return output.toString();
+ }
+}
Property changes on: core/branches/flat/src/main/java/org/horizon/eviction/EntryEvictionData.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: core/branches/flat/src/main/java/org/horizon/eviction/EvictionAction.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionAction.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionAction.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -24,23 +24,24 @@
import org.horizon.Cache;
/**
- * Performs an eviction on a given Fqn.
+ * Performs an eviction on a given cache entry
*
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
* @since 1.0
*/
-public interface EvictionAction<K> {
+public interface EvictionAction {
/**
* Sets a reference to the cache.
*
* @param cache cache
*/
- void setCache(Cache<K, ?> cache);
+ void setCache(Cache<?, ?> cache);
/**
* Performs an eviction on a given node.
*
+ * @param key key of entry to evict
* @return true if the eviction was successful, false if not.
*/
- boolean evict(K key);
+ boolean evict(Object key);
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,7 +21,7 @@
*/
package org.horizon.eviction;
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
import org.horizon.config.EvictionAlgorithmConfig;
import org.horizon.eviction.EvictionEvent.Type;
@@ -33,16 +33,18 @@
* Note: None of the Eviction classes are thread safe. It is assumed that an individual instance of an EvictionPolicy/
* EvictionAlgorithm/EvictionQueue/EvictionConfiguration are only operated on by one thread at any given time.
*
- * @author Ben Wang 2-2004
- * @author Daniel Huang - dhuang(a)jboss.org - 10/2005
+ * @author (various)
* @since 1.0
*/
-public interface EvictionAlgorithm<K> {
+public interface EvictionAlgorithm {
/**
* Entry point for eviction algorithm. Invoking this will cause the algorithm to process the queue of {@link
- * EvictionEvent} passed in.
+ * EvictionEvent}s passed in.
+ *
+ * @param queue blocking queue of {@link org.horizon.eviction.EvictionEvent}s to process.
+ * @throws EvictionException if there is a problem processing any of these events
*/
- void process(BlockingQueue<EvictionEvent<K>> queue) throws EvictionException;
+ void process(BlockingQueue<EvictionEvent> queue) throws EvictionException;
/**
* Reset the whole eviction queue. The queue may need to be reset due to corrupted state, for example.
@@ -51,18 +53,25 @@
/**
* Get the EvictionQueue implementation used by this algorithm.
+ *
+ * @return an EvictionQueue instance that is able to sort keys for eviction as dictated by the eviction algorithm
*/
EvictionQueue getEvictionQueue();
/**
* Sets the eviction action policy, so the algorithm knows what to do when a node is to be evicted.
+ *
+ * @param evictionAction eviction action instance to use
*/
- void setEvictionAction(EvictionAction<K> evictionAction);
+ void setEvictionAction(EvictionAction evictionAction);
/**
* Assigns the algorithm instance to a given Cache.
+ *
+ * @param cache cache to work with
+ * @param evictionAlgorithmConfig algorithm configuration to use
*/
- void assignToCache(CacheSPI<K, ?> cache, EvictionAlgorithmConfig evictionAlgorithmConfig);
+ void assignToCache(Cache<?, ?> cache, EvictionAlgorithmConfig evictionAlgorithmConfig);
/**
* Tests whether the algorithm would ignore certain event types on certain Fqns.
@@ -77,5 +86,9 @@
*/
void initialize();
+ /**
+ * @return the type of the {@link org.horizon.config.EvictionAlgorithmConfig} bean used to configure this
+ * implementation of {@link org.horizon.eviction.EvictionAlgorithm}
+ */
Class<? extends EvictionAlgorithmConfig> getConfigurationClass();
}
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-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionAlgorithmConfigBase.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -39,7 +39,7 @@
protected String evictionAlgorithmClassName;
@Dynamic
- protected int maxNodes = 0;
+ protected int maxEntries = 0;
@Dynamic
protected long minTimeToLive;
@@ -53,13 +53,13 @@
return evictionAlgorithmClassName;
}
- public int getMaxNodes() {
- return maxNodes;
+ public int getMaxEntries() {
+ return maxEntries;
}
- public void setMaxNodes(int maxNodes) {
- testImmutability("maxNodes");
- this.maxNodes = maxNodes;
+ public void setMaxEntries(int maxEntries) {
+ testImmutability("maxEntries");
+ this.maxEntries = maxEntries;
}
/**
@@ -93,7 +93,7 @@
EvictionAlgorithmConfigBase that = (EvictionAlgorithmConfigBase) o;
- if (maxNodes != that.maxNodes) return false;
+ if (maxEntries != that.maxEntries) return false;
if (minTimeToLive != that.minTimeToLive) return false;
if (evictionAlgorithmClassName != null ? !evictionAlgorithmClassName.equals(that.evictionAlgorithmClassName) : that.evictionAlgorithmClassName != null)
return false;
@@ -104,18 +104,22 @@
public int hashCode() {
int result;
result = (evictionAlgorithmClassName != null ? evictionAlgorithmClassName.hashCode() : 0);
- result = 31 * result + maxNodes;
+ result = 31 * result + maxEntries;
result = (int) (31 * result + minTimeToLive);
result = 31 * result + (int) (minTimeToLive ^ (minTimeToLive >>> 32));
return result;
}
public void reset() {
- maxNodes = 0;
+ maxEntries = 0;
minTimeToLive = 0;
}
- public EvictionAlgorithmConfig clone() throws CloneNotSupportedException {
- return (EvictionAlgorithmConfig) super.clone();
+ public EvictionAlgorithmConfig clone() {
+ try {
+ return (EvictionAlgorithmConfig) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Should never happen", e);
+ }
}
}
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManager.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManager.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManager.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,51 +0,0 @@
-package org.horizon.eviction;
-
-import org.horizon.config.EvictionCacheConfig;
-
-/**
- * There is one eviction manager per cache.
- *
- * @author Mircea.Markus(a)jboss.com
- * @since 1.0
- */
-public interface EvictionCacheManager<K> {
- /**
- * Processes the eviction queues (primary and recycle queues) associated with this cache.
- */
- void processEvictionQueues();
-
- /**
- * Clears the node event queue used for processing eviction.
- */
- void resetEvictionQueues();
-
- /**
- * Configures this EvictionCacheManager for eviction.
- *
- * @param evictionCacheConfig configuration to set
- */
- void configure(EvictionCacheConfig evictionCacheConfig);
-
- /**
- * Registers an eviction event on the cache's eviction event queue for later processing by {@link
- * #processEvictionQueues()}.
- */
- EvictionEvent registerEvictionEvent(K key, EvictionEvent.Type eventType, int elementDifference);
-
- /**
- * An overloaded version of {@link #registerEvictionEvent(Object, org.horizon.eviction.EvictionEvent.Type, int)}
- * which uses a default elementDifference value.
- *
- * @param eventType passed in to the constructor of {@link org.horizon.eviction.EvictionEvent}
- * @return an EvictedEventNode that has been created for this queue
- */
- EvictionEvent registerEvictionEvent(K key, EvictionEvent.Type eventType);
-
- /**
- * Adds an event to the eviction queue indicating that a node is no longer in use.
- *
- * @param key Fqn of the node.
- */
- void unmarkNodeCurrentlyInUse(K key);
-}
-
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManagerImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManagerImpl.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionCacheManagerImpl.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,123 +0,0 @@
-package org.horizon.eviction;
-
-import org.horizon.CacheSPI;
-import org.horizon.config.EvictionAlgorithmConfig;
-import org.horizon.config.EvictionCacheConfig;
-import org.horizon.logging.Log;
-import org.horizon.logging.LogFactory;
-import org.horizon.util.Util;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * @author Mircea.Markus(a)jboss.com
- * @since 1.0
- */
-public class EvictionCacheManagerImpl<K> implements EvictionCacheManager<K> {
- private static Log log = LogFactory.getLog(EvictionCacheManagerImpl.class);
- private static boolean trace = log.isTraceEnabled();
-
- private BlockingQueue<EvictionEvent<K>> evictionEventQueue = null;
- private int capacityWarnThreshold = 0;
- private EvictionCacheConfig evictionCacheConfig;
- private EvictionAlgorithm<K> evictionAlgorithm;
- private CacheSPI<K, ?> cache;
-
- public EvictionCacheManagerImpl(CacheSPI<K, ?> cache) {
- this.cache = cache;
- }
-
- public void processEvictionQueues() {
- evictionAlgorithm.process(evictionEventQueue);
- }
-
- public void resetEvictionQueues() {
- evictionEventQueue.clear();
- }
-
- public EvictionEvent registerEvictionEvent(K key, EvictionEvent.Type eventType, int elementDifference) {
- if (evictionAlgorithm.canIgnoreEvent(eventType)) return null;
- EvictionEvent<K> event = new EvictionEvent<K>(key, eventType, elementDifference);
- registerEvictionEvent(event);
- return event;
- }
-
- public EvictionEvent registerEvictionEvent(K key, EvictionEvent.Type eventType) {
- return registerEvictionEvent(key, eventType, 0);
- }
-
- public void markNodeCurrentlyInUse(K key, long timeout) {
- registerEvictionEvent(key, EvictionEvent.Type.MARK_IN_USE_EVENT, 0).setInUseTimeout(timeout);
- }
-
- public void unmarkNodeCurrentlyInUse(K key) {
- registerEvictionEvent(key, EvictionEvent.Type.UNMARK_USE_EVENT, 0);
- }
-
- public void configure(EvictionCacheConfig evictionCacheConfig) {
- this.evictionCacheConfig = evictionCacheConfig;
- evictionAlgorithm = createEvictionAlgorithm(evictionCacheConfig.getEvictionAlgorithmConfig(), evictionCacheConfig.getEvictionActionClassName());
- if (evictionEventQueue == null) createQueue();
- evictionAlgorithm.initialize();
- }
-
- private void registerEvictionEvent(EvictionEvent<K> ee) {
- try {
- createQueue();// in case the queue does not exist yet.
- if (evictionEventQueue.size() > capacityWarnThreshold) {
- if (log.isWarnEnabled())
- log.warn("putNodeEvent(): eviction node event queue size is at 98% threshold value of capacity: " + evictionCacheConfig.getEventQueueSize() +
- " Cache name: " + cache.getName() + " You will need to reduce the wakeUpIntervalSeconds parameter.");
- }
- evictionEventQueue.put(ee);
- }
- catch (InterruptedException e) {
- if (log.isDebugEnabled()) log.debug("Interrupted on adding event", e);
- // reinstate interrupt flag
- Thread.currentThread().interrupt();
- }
- }
-
- private void createQueue() {
- if (evictionEventQueue == null) {
- if (evictionCacheConfig == null) {
- throw new IllegalArgumentException("null eviction configuration");
- }
- int size = evictionCacheConfig.getEventQueueSize();
- capacityWarnThreshold = (98 * size) / 100 - 100;
- if (capacityWarnThreshold <= 0) {
- if (log.isWarnEnabled()) log.warn("Capacity warn threshold used in eviction is smaller than 1.");
- }
- evictionEventQueue = new LinkedBlockingQueue<EvictionEvent<K>>(size);
- }
- }
-
- private EvictionAlgorithm<K> createEvictionAlgorithm(EvictionAlgorithmConfig algoConfig, String evictionActionClass) {
- if (algoConfig == null)
- throw new IllegalArgumentException("Eviction algorithm class must not be null!");
-
- if (evictionActionClass == null)
- throw new IllegalArgumentException("Eviction action policy class must not be null!");
-
- try {
- if (trace) log.trace("Instantiating " + evictionActionClass);
- EvictionAction<K> evictionAction = (EvictionAction<K>) Util.getInstance(evictionActionClass);
- evictionAction.setCache(cache);
-
- if (trace) log.trace("Instantiating " + algoConfig.getEvictionAlgorithmClassName());
- EvictionAlgorithm<K> algorithm = (EvictionAlgorithm) Util.getInstance(algoConfig.getEvictionAlgorithmClassName());
- algorithm.setEvictionAction(evictionAction);
- algorithm.assignToCache(cache, algoConfig);
- return algorithm;
- }
- catch (Exception e) {
- log.fatal("Unable to instantiate eviction algorithm " + algoConfig.getEvictionAlgorithmClassName(), e);
- throw new IllegalStateException(e);
- }
- }
-
- public String getCacheName() {
- return cache.getName();
- }
-}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/EvictionEvent.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionEvent.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionEvent.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -27,10 +27,9 @@
* @author (various)
* @since 1.0
*/
-public class EvictionEvent<K> {
- private K key;
+public class EvictionEvent {
+ private Object key;
private Type type;
- private int elementDifference;
private long inUseTimeout;
private long creationTimestamp;
@@ -39,19 +38,17 @@
}
public static enum Type {
- ADD_NODE_EVENT,
- REMOVE_NODE_EVENT,
- VISIT_NODE_EVENT,
- ADD_ELEMENT_EVENT,
- REMOVE_ELEMENT_EVENT,
+ ADD_ENTRY_EVENT,
+ REMOVE_ENTRY_EVENT,
+ VISIT_ENTRY_EVENT,
+ CLEAR_CACHE_EVENT,
MARK_IN_USE_EVENT,
- UNMARK_USE_EVENT
+ UNMARK_IN_USE_EVENT
}
- public EvictionEvent(K key, Type type, int elementDifference) {
+ public EvictionEvent(Object key, Type type) {
this.key = key;
this.type = type;
- this.elementDifference = elementDifference;
this.creationTimestamp = System.currentTimeMillis();
}
@@ -67,19 +64,11 @@
this.inUseTimeout = inUseTimeout;
}
- public int getElementDifference() {
- return elementDifference;
- }
-
- public void setElementDifference(int elementDifference) {
- this.elementDifference = elementDifference;
- }
-
- public K getKey() {
+ public Object getKey() {
return key;
}
- public void setKey(K key) {
+ public void setKey(Object key) {
this.key = key;
}
@@ -93,7 +82,7 @@
@Override
public String toString() {
- return "EvictedEventNode[key=" + key + " event=" + type + " diff=" + elementDifference + "]";
+ return "EvictedEventNode[key=" + key + " event=" + type + "]";
}
/**
@@ -102,7 +91,7 @@
* @param key new Fqn root to use
* @return a new EvictedEventNode instance
*/
- public EvictionEvent copy(K key) {
- return new EvictionEvent<K>(key, type, elementDifference);
+ public EvictionEvent copy(Object key) {
+ return new EvictionEvent(key, type);
}
}
Copied: core/branches/flat/src/main/java/org/horizon/eviction/EvictionManager.java (from rev 7621, core/branches/flat/src/main/java/org/horizon/EvictionManager.java)
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionManager.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionManager.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,59 @@
+package org.horizon.eviction;
+
+import net.jcip.annotations.ThreadSafe;
+import org.horizon.factories.annotations.NonVolatile;
+import org.horizon.factories.scopes.Scope;
+import org.horizon.factories.scopes.Scopes;
+import org.horizon.lifecycle.Lifecycle;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Central component that deals with eviction of cache entries
+ *
+ * @author Mircea.Markus(a)jboss.com
+ * @author Manik Surtani
+ * @since 1.0
+ */
+@ThreadSafe
+@NonVolatile
+(a)Scope(Scopes.NAMED_CACHE)
+public interface EvictionManager extends Lifecycle {
+
+ /**
+ * Processes the eviction event queue by passing it to the configured eviction algorithm
+ */
+ void processEvictionQueues();
+
+ /**
+ * Clears the eviction event queue used for processing eviction.
+ */
+ void resetEvictionQueues();
+
+ /**
+ * Registers an eviction event eviction event queue for later processing by {@link #processEvictionQueues()}.
+ *
+ * @param key key of the cache entry to register an event for
+ * @param eventType type of event
+ * @return the EvictionEvent instance after being registered
+ */
+ EvictionEvent registerEvictionEvent(Object key, EvictionEvent.Type eventType);
+
+ /**
+ * Marks a key as being currently in use, so that it is not considered for eviction even if the condifured algorithm
+ * selects it for eviction.
+ *
+ * @param key entry key to mark
+ * @param timeout duration for which the entry should be considered as in-use
+ * @param unit time unit
+ */
+ void markNodeCurrentlyInUse(Object key, long timeout, TimeUnit unit);
+
+ /**
+ * Un-marks a key as being currently in use, if it was marked using {@link #markNodeCurrentlyInUse(Object, long,
+ * java.util.concurrent.TimeUnit)} Unmarking makes the node vulnerable to eviction again.
+ *
+ * @param key entry key to unmark
+ */
+ void unmarkNodeCurrentlyInUse(Object key);
+}
Property changes on: core/branches/flat/src/main/java/org/horizon/eviction/EvictionManager.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: core/branches/flat/src/main/java/org/horizon/eviction/EvictionManagerImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionManagerImpl.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionManagerImpl.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,13 +1,24 @@
package org.horizon.eviction;
import net.jcip.annotations.ThreadSafe;
-import org.horizon.EvictionManager;
+import org.horizon.Cache;
+import org.horizon.config.Configuration;
+import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.config.EvictionConfig;
+import org.horizon.factories.KnownComponentNames;
+import org.horizon.factories.annotations.ComponentName;
+import org.horizon.factories.annotations.Inject;
+import org.horizon.factories.annotations.Start;
+import org.horizon.factories.annotations.Stop;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
+import org.horizon.util.Util;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
/**
* @author Mircea.Markus(a)jboss.com
@@ -15,54 +26,130 @@
*/
@ThreadSafe
public class EvictionManagerImpl implements EvictionManager {
- private static Log log = LogFactory.getLog(EvictionManagerImpl.class);
- private boolean externalEvictionThread;
- private EvictionTimerTask evictionTimerTask;
- private final Map<String, EvictionCacheManager> evictionCacheManagers = new HashMap<String, EvictionCacheManager>(4);
- private ThreadFactory threadFactory;
- private long wakeUpInterval;
+ private static final Log log = LogFactory.getLog(EvictionManagerImpl.class);
+ private static final boolean trace = log.isTraceEnabled();
+ // elements
+ EvictionAlgorithm evictionAlgorithm;
+ EvictionAlgorithmConfig evictionAlgorithmConfig;
+ EvictionConfig evictionConfig;
+ ScheduledFuture evictionTask;
- public synchronized void configureEvictionThread(long wakeUpInterval, ThreadFactory threadFactory) {
- if (wakeUpInterval <= 0) {
- log.info("wakeUpInterval is <= 0, not starting eviction thread");
- externalEvictionThread = true;
- return;
- }
- this.wakeUpInterval = wakeUpInterval;
- this.threadFactory = threadFactory;
- evictionTimerTask = new EvictionTimerTask(this);
+ // event queue
+ private BlockingQueue<EvictionEvent> evictionEventQueue;
+ int capacityWarnThreshold = 0;
+
+ // components to be injected
+ ScheduledExecutorService executor;
+ Configuration configuration;
+ Cache cache;
+
+ @Inject
+ public void initialize((a)ComponentName(KnownComponentNames.EVICTION_SCHEDULED_EXECUTOR) ScheduledExecutorService executor,
+ Configuration configuration, Cache cache) {
+ this.executor = executor;
+ this.configuration = configuration;
+ this.cache = cache;
}
- public synchronized void cacheCreated(String cacheName, EvictionCacheManager cacheManager) {
- if (!externalEvictionThread && evictionCacheManagers.isEmpty())//this is the first cache to be added, also start ev thread here
- {
- evictionTimerTask.init(wakeUpInterval, threadFactory);
+ @Start
+ public void start() {
+ // first check if eviction is enabled!
+ if (configuration.getEvictionConfig() != null) {
+ evictionConfig = configuration.getEvictionConfig();
+
+ // 1. set up the eviction event queue
+ int size = evictionConfig.getEventQueueSize();
+ capacityWarnThreshold = (98 * size) / 100 - 100;
+ if (capacityWarnThreshold <= 0) {
+ if (log.isWarnEnabled()) log.warn("Capacity warn threshold used in eviction is smaller than 1.");
+ }
+ evictionEventQueue = new LinkedBlockingQueue<EvictionEvent>(size);
+
+ // 2. now ensure we instantiate the eviction algorithm class
+ evictionAlgorithmConfig = evictionConfig.getAlgorithmConfig();
+ evictionAlgorithm = createEvictionAlgorithm(evictionAlgorithmConfig, evictionConfig.getActionPolicyClass());
+
+ // 3. And finally set up the eviction timer task
+ if (evictionConfig.getWakeUpInterval() <= 0) {
+ log.info("wakeUpInterval is <= 0, not starting eviction thread");
+ } else {
+ evictionTask = executor.scheduleWithFixedDelay(new Runnable() {
+ public void run() {
+ processEvictionQueues();
+ }
+ }, evictionConfig.getWakeUpInterval(), evictionConfig.getWakeUpInterval(), TimeUnit.MILLISECONDS);
+ }
}
- evictionCacheManagers.put(cacheName, cacheManager);
}
- public synchronized void cacheStopped(String cacheName) {
- if (evictionCacheManagers.remove(cacheName) == null) {
- throw new IllegalStateException("Attempting to stop an unregistred cache: " + cacheName);
+ @Stop
+ public void stop() {
+ if (evictionTask != null) evictionTask.cancel(true);
+ if (evictionAlgorithm != null) evictionAlgorithm.resetEvictionQueue();
+ evictionAlgorithm = null;
+ if (evictionEventQueue != null) evictionEventQueue.clear();
+ evictionEventQueue = null;
+ }
+
+ public void processEvictionQueues() {
+ evictionAlgorithm.process(evictionEventQueue);
+ }
+
+ public void resetEvictionQueues() {
+ evictionEventQueue.clear();
+ }
+
+ public EvictionEvent registerEvictionEvent(Object key, EvictionEvent.Type eventType) {
+ if (evictionAlgorithm.canIgnoreEvent(eventType)) return null;
+ EvictionEvent ee = new EvictionEvent(key, eventType);
+ registerEvictionEvent(ee);
+ return ee;
+ }
+
+ public void markNodeCurrentlyInUse(Object key, long duration, TimeUnit unit) {
+ registerEvictionEvent(key, EvictionEvent.Type.MARK_IN_USE_EVENT).setInUseTimeout(unit.toMillis(duration));
+ }
+
+ public void unmarkNodeCurrentlyInUse(Object key) {
+ registerEvictionEvent(key, EvictionEvent.Type.UNMARK_IN_USE_EVENT);
+ }
+
+ private void registerEvictionEvent(EvictionEvent ee) {
+ try {
+ if (evictionEventQueue.size() > capacityWarnThreshold) {
+ if (log.isWarnEnabled())
+ log.warn("Eviction event queue size is at 98% capacity of {0} on cache {1}. You should reduce the wakeUpInterval attribute.",
+ evictionConfig.getEventQueueSize(), cache.getName());
+ }
+ evictionEventQueue.put(ee);
}
- if (!externalEvictionThread && evictionCacheManagers.isEmpty()) {
- evictionTimerTask.stop();
+ catch (InterruptedException e) {
+ if (log.isDebugEnabled()) log.debug("Interrupted on adding event", e);
+ // reinstate interrupt flag
+ Thread.currentThread().interrupt();
}
}
- public void runEviction() {
- synchronized (evictionCacheManagers) {
- for (EvictionCacheManager evictionCacheManager : evictionCacheManagers.values()) {
- try {
- evictionCacheManager.processEvictionQueues();
- }
- catch (EvictionException e) {
- //we cannot die in peace here, as this is not the main thread and the user won't get informed...
- log.error("run(): error processing eviction with exception: " + e.toString()
- + " will reset the eviction queue list.", e);
- evictionCacheManager.resetEvictionQueues();
- }
- }
+ private EvictionAlgorithm createEvictionAlgorithm(EvictionAlgorithmConfig algoConfig, String evictionActionClass) {
+ if (algoConfig == null)
+ throw new IllegalArgumentException("Eviction algorithm class must not be null!");
+
+ if (evictionActionClass == null)
+ throw new IllegalArgumentException("Eviction action policy class must not be null!");
+
+ try {
+ if (trace) log.trace("Instantiating {0}", evictionActionClass);
+ EvictionAction evictionAction = (EvictionAction) Util.getInstance(evictionActionClass);
+ evictionAction.setCache(cache);
+
+ if (trace) log.trace("Instantiating {0}", algoConfig.getEvictionAlgorithmClassName());
+ EvictionAlgorithm algorithm = (EvictionAlgorithm) Util.getInstance(algoConfig.getEvictionAlgorithmClassName());
+ algorithm.setEvictionAction(evictionAction);
+ algorithm.assignToCache(cache, algoConfig);
+ return algorithm;
+ } catch (Exception e) {
+ log.fatal("Unable to instantiate eviction algorithm {0}", e, algoConfig.getEvictionAlgorithmClassName());
+ throw new IllegalStateException(e);
}
}
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/EvictionQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -30,69 +30,60 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public interface EvictionQueue<K> extends Iterable<KeyEntry<K>> {
- /**
- * Get the first entry in the queue.
- * <p/>
- * If there are no entries in queue, this method will return null.
- * <p/>
- * The first node returned is expected to be the first node to evict.
- *
- * @return first NodeEntry in queue.
- */
- KeyEntry<K> getFirstNodeEntry();
+public interface EvictionQueue extends Iterable<EntryEvictionData> {
+// /**
+// * Get the first entry in the queue.
+// * <p/>
+// * If there are no entries in queue, this method will return null.
+// * <p/>
+// * The first node returned is expected to be the first node to evict.
+// *
+// * @return first NodeEntry in queue.
+// */
+// EntryEvictionData getFirstNodeEntry();
+ //
/**
- * Retrieve a node entry by Fqn.
+ * Retrieve eviction entry data representing a specific key
* <p/>
* This will return null if the entry is not found.
*
- * @return Node Entry object associated with given Fqn param.
+ * @param key key to find
+ * @return eviction entry data representing the specified key
*/
- KeyEntry<K> getNodeEntry(K key);
+ EntryEvictionData get(Object key);
/**
- * Check if queue contains the given NodeEntry.
+ * Check if eviction entry data exists in the queue
*
- * @param entry NodeEntry to check for existence in queue.
- * @return true/false if NodeEntry exists in queue.
+ * @param entryEvictionData to check for
+ * @return true if the entry exists, false otherwise
*/
- boolean containsNodeEntry(KeyEntry<K> entry);
+ boolean contains(EntryEvictionData entryEvictionData);
/**
- * Remove a NodeEntry from queue.
- * <p/>
- * If the NodeEntry does not exist in the queue, this method will return normally.
+ * Remove eviction entry data from the queue. A no-op if the specified object does not exist.
*
- * @param entry The NodeEntry to remove from queue.
+ * @param entryEvictionData to remove
*/
- void removeNodeEntry(KeyEntry<K> entry);
+ void remove(EntryEvictionData entryEvictionData);
/**
- * Add a NodeEntry to the queue.
+ * Add entry eviction data to the queue
*
- * @param entry The NodeEntry to add to queue.
+ * @param entryEvictionData to add. Must not be null.
*/
- void addNodeEntry(KeyEntry<K> entry);
+ void add(EntryEvictionData entryEvictionData);
/**
- * Get the number of nodes in the queue.
+ * Get the size of the queue
*
- * @return The number of nodes in the queue.
+ * @return the size of the queue
*/
- int getNumberOfNodes();
+ int size();
/**
- * Get the number of elements in the queue.
- *
- * @return The number of elements in the queue.
- */
- int getNumberOfElements();
-
- void modifyElementCount(int difference);
-
- /**
* Clear the queue.
*/
void clear();
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/EvictionTimerTask.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionTimerTask.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionTimerTask.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,91 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction;
-
-import org.horizon.EvictionManager;
-import org.horizon.logging.Log;
-import org.horizon.logging.LogFactory;
-
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Timer threads to do periodic node clean up by running the eviction policy.
- *
- * @author Ben Wang 2-2004
- * @author Daniel Huang (dhuang(a)jboss.org)
- * @since 1.0
- */
-public class EvictionTimerTask {
- private Log log = LogFactory.getLog(EvictionTimerTask.class);
-
- private static AtomicInteger tcount = new AtomicInteger();
- private long wakeupInterval;
- private ScheduledExecutorService scheduledExecutor;
- private Task task;
- private EvictionManager evictionManager;
-
-
- public EvictionTimerTask(EvictionManager evManager) {
- this.evictionManager = evManager;
- task = new Task();
- }
-
- public void init(long wakeupInterval, ThreadFactory evictionThreadFactory) {
- if (log.isTraceEnabled())
- log.trace("Creating a new eviction timer task with wakeupInterval millis set at " + wakeupInterval);
- this.wakeupInterval = wakeupInterval;
- start(evictionThreadFactory);
- }
-
-
- public void stop() {
- if (log.isDebugEnabled()) log.debug("Stopping eviction timer");
- if (scheduledExecutor != null) {
- scheduledExecutor.shutdownNow();
- }
- scheduledExecutor = null;
- }
-
- private void start(ThreadFactory tf) {
- if (tf == null) tf = new ThreadFactory() {
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r, "EvictionTimer-" + tcount.getAndIncrement());
- t.setDaemon(true);
- return t;
- }
- };
- scheduledExecutor = Executors.newSingleThreadScheduledExecutor(tf);
- scheduledExecutor.scheduleWithFixedDelay(task, wakeupInterval, wakeupInterval, TimeUnit.MILLISECONDS);
- }
-
- public class Task implements Runnable {
- public void run() {
- evictionManager.runEviction();
- }
- }
-}
-
-
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/EvictionWatcher.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/EvictionWatcher.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/EvictionWatcher.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,47 +0,0 @@
-package org.horizon.eviction;
-
-import org.horizon.Cache;
-import org.horizon.notifications.Listener;
-import org.horizon.notifications.cachelistener.annotation.CacheEntryEvicted;
-import org.horizon.notifications.cachelistener.event.CacheEntryEvictedEvent;
-import org.horizon.tree.Fqn;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Watches and waits for eviction events
- *
- * @author Manik Surtani (<a href="mailto:manik AT jboss DOT org">manik AT jboss DOT org</a>)
- * @since 1.0
- */
-@Listener
-public class EvictionWatcher {
- Cache<?, ?> cache;
- List<Object> keysToWaitFor;
-
- public EvictionWatcher(Cache<?, ?> cache, Fqn... keysToWaitFor) {
-// this(cache, Arrays.asList(keysToWaitFor));
- }
-
- public EvictionWatcher(Cache<?, ?> cache, List<Object> keysToWaitFor) {
- this.cache = cache;
- this.keysToWaitFor = new ArrayList<Object>(keysToWaitFor);
- cache.addListener(this);
- }
-
- @CacheEntryEvicted
- public void receive(CacheEntryEvictedEvent ee) {
- boolean xpect = false;
- if (ee.isPre() && keysToWaitFor.contains(ee.getKey())) {
- xpect = true;
- keysToWaitFor.remove(ee.getKey());
- }
-
- if (ee.isPre()) System.out.println("Saw " + ee.getKey() + " was expecting? " + xpect);
- }
-
- public boolean allNodesEvicted() {
- return keysToWaitFor.isEmpty();
- }
-}
\ No newline at end of file
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/ExpirationAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/ExpirationAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/ExpirationAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,143 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction;
-
-import org.horizon.config.Dynamic;
-import org.horizon.eviction.algorithms.ExpirationAlgorithm;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Configuration for indicating the Node key for setting a specific eviction time.
- *
- * @author (various)
- * @since 1.0
- */
-public class ExpirationAlgorithmConfig extends EvictionAlgorithmConfigBase {
-
- private static final long serialVersionUID = 47338798734219507L;
-
- /**
- * Default key name for indicating expiration time.
- */
- public static final String EXPIRATION_KEY = "expiration";
-
- /**
- * Node key name used to indicate the expiration of a node.
- */
- @Dynamic
- private String expirationKeyName = EXPIRATION_KEY;
-
- @Dynamic
- private boolean warnNoExpirationKey = true;
-
- @Dynamic
- private long timeToLive = 0;
-
- public ExpirationAlgorithmConfig() {
- evictionAlgorithmClassName = ExpirationAlgorithm.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 isWarnNoExpirationKey() {
- 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;
- }
-
- /**
- * @return time to live, in milliseconds
- */
- public long getTimeToLive() {
- return timeToLive;
- }
-
- /**
- * Sets the time to live
- *
- * @param timeToLive value in milliseconds
- */
- public void setTimeToLive(long timeToLive) {
- this.timeToLive = timeToLive;
- }
-
- public void setTimeToLive(long timeToLive, TimeUnit timeUnit) {
- this.timeToLive = timeUnit.toMillis(timeToLive);
- }
-
- @Override
- public ExpirationAlgorithmConfig clone() throws CloneNotSupportedException {
- return (ExpirationAlgorithmConfig) super.clone();
- }
-
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- if (!super.equals(o)) return false;
-
- ExpirationAlgorithmConfig that = (ExpirationAlgorithmConfig) o;
-
- if (timeToLive != that.timeToLive) return false;
- if (warnNoExpirationKey != that.warnNoExpirationKey) return false;
- if (expirationKeyName != null ? !expirationKeyName.equals(that.expirationKeyName) : that.expirationKeyName != null)
- return false;
-
- return true;
- }
-
- public int hashCode() {
- int result = super.hashCode();
- result = 31 * result + (expirationKeyName != null ? expirationKeyName.hashCode() : 0);
- result = 31 * result + (warnNoExpirationKey ? 1 : 0);
- result = 31 * result + (int) (timeToLive ^ (timeToLive >>> 32));
- return result;
- }
-
- @Override
- public void reset() {
- super.reset();
- evictionAlgorithmClassName = ExpirationAlgorithm.class.getName();
- warnNoExpirationKey = true;
- timeToLive = 0;
- }
-}
\ No newline at end of file
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/KeyEntry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/KeyEntry.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/KeyEntry.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,200 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction;
-
-/**
- * Value object used in queue
- *
- * @author Ben Wang 2-2004
- * @author Daniel Huang - dhuang(a)jboss.org
- * @since 1.0
- */
-public class KeyEntry<K> {
- private long modifiedTimeStamp;
- private long creationTimeStamp;
- private int numberOfNodeVisits;
- private int numberOfElements;
- private K key;
-
- private long inUseTimeoutTimestamp;
- private boolean currentlyInUse = false;
-
- private EvictionQueue queue;
-
- /**
- * Private constructor that automatically sets the creation time stamp of the node entry.
- */
- private KeyEntry() {
- this.creationTimeStamp = System.currentTimeMillis();
- }
-
- public KeyEntry(K key) {
- this();
- setKey(key);
- }
-
- public KeyEntry(int numberOfNodeVisits, long modifiedTimeStamp, int numberOfElements, K key) {
- this(key);
- this.numberOfNodeVisits = numberOfNodeVisits;
- this.modifiedTimeStamp = modifiedTimeStamp;
- this.numberOfElements = numberOfElements;
- }
-
- /**
- * Is the node currently in use.
- *
- * @return True/false if the node is currently marked as in use.
- */
- public boolean isCurrentlyInUse() {
- return currentlyInUse;
- }
-
- public void setCurrentlyInUse(boolean currentlyInUse, long inUseTimeout) {
- this.currentlyInUse = currentlyInUse;
- if (inUseTimeout > 0) {
- this.inUseTimeoutTimestamp = System.currentTimeMillis() + inUseTimeout;
- }
- }
-
- public long getInUseTimeoutTimestamp() {
- return this.inUseTimeoutTimestamp;
- }
-
- /**
- * Get modified time stamp. This stamp is created during the node is processed so it has some fuzy tolerance in
- * there.
- *
- * @return The last modified time stamp
- */
- public long getModifiedTimeStamp() {
- return modifiedTimeStamp;
- }
-
- public void setModifiedTimeStamp(long modifiedTimeStamp) {
-// log.error("Being modified to " + modifiedTimeStamp, new Throwable());
- this.modifiedTimeStamp = modifiedTimeStamp;
- }
-
- /**
- * Get the time stamp for when the node entry was created.
- *
- * @return The node entry creation time stamp
- */
- public long getCreationTimeStamp() {
- return creationTimeStamp;
- }
-
- public void setCreationTimeStamp(long creationTimeStamp) {
- this.creationTimeStamp = creationTimeStamp;
- }
-
- public int getNumberOfNodeVisits() {
- return numberOfNodeVisits;
- }
-
- public void setNumberOfNodeVisits(int numberOfNodeVisits) {
- this.numberOfNodeVisits = numberOfNodeVisits;
- }
-
- public void incerementNumberOfNodeVisits() {
- this.numberOfNodeVisits++;
- }
-
- public int getNumberOfElements() {
- return numberOfElements;
- }
-
- public void setNumberOfElements(int numberOfElements) {
- if (queue != null) {
- int difference = numberOfElements - this.numberOfElements;
- queue.modifyElementCount(difference);
- }
- this.numberOfElements = numberOfElements;
- }
-
- public K getKey() {
- return key;
- }
-
- void setKey(K key) {
- this.key = key;
- }
-
- @Override
- public int hashCode() {
- return key.hashCode();
- }
-
- public boolean isNodeInUseAndNotTimedOut() {
- if (isCurrentlyInUse()) {
- if (getInUseTimeoutTimestamp() == 0) {
- return true;
- }
-
- if (System.currentTimeMillis() < getInUseTimeoutTimestamp()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests whether a node entry is younger than the minimum time to live - if one is configured.
- *
- * @return true if the node is younger than - or exactly equal to - the minimum time to live, if one is configured
- * for the given region. False otherwise.
- */
- public boolean isYoungerThanMinimumTimeToLive(long minTTL) {
- return minTTL >= 1 && (getModifiedTimeStamp() + minTTL > System.currentTimeMillis());
- }
-
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof KeyEntry))
- return false;
- KeyEntry ne = (KeyEntry) o;
- return key.equals(ne.getKey());
- }
-
- @Override
- public String toString() {
- StringBuilder output = new StringBuilder();
- output.append("Fqn: ");
- if (key != null) {
- output.append(key);
- } else {
- output.append(" null");
- }
-
- output.append(" CreateTime: ").append(this.getCreationTimeStamp());
- output.append(" NodeVisits: ").append(this.getNumberOfNodeVisits());
- output.append(" ModifiedTime: ").append(this.getModifiedTimeStamp());
- output.append(" NumberOfElements: ").append(this.getNumberOfElements());
- output.append(" CurrentlyInUse: ").append(this.isCurrentlyInUse());
- return output.toString();
- }
-
- public void setQueue(EvictionQueue queue) {
- this.queue = queue;
- }
-}
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/RegionNameConflictException.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/RegionNameConflictException.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/RegionNameConflictException.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,45 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction;
-
-/**
- * MarshRegion name conflicts with pre-existing regions.
- *
- * @author Ben Wang 2-2004
- * @since 1.0
- */
-public class RegionNameConflictException extends Exception {
-
- private static final long serialVersionUID = -6796150029431162837L;
-
- public RegionNameConflictException() {
- super();
- }
-
- public RegionNameConflictException(String msg) {
- super(msg);
- }
-
- public RegionNameConflictException(String msg, Throwable cause) {
- super(msg, cause);
- }
-}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/RemoveOnEvictActionPolicy.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/RemoveOnEvictActionPolicy.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/RemoveOnEvictActionPolicy.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -31,21 +31,21 @@
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
* @since 1.0
*/
-public class RemoveOnEvictActionPolicy<K> implements EvictionAction<K> {
- private Cache<K, ?> cache;
+public class RemoveOnEvictActionPolicy implements EvictionAction {
+ private Cache cache;
private static final Log log = LogFactory.getLog(DefaultEvictionAction.class);
- public void setCache(Cache<K, ?> cache) {
+ public void setCache(Cache cache) {
this.cache = cache;
}
- public boolean evict(K key) {
+ public boolean evict(Object key) {
try {
cache.remove(key);
return true;
}
catch (Exception e) {
- if (log.isDebugEnabled()) log.debug("Unable to evict " + key, e);
+ if (log.isDebugEnabled()) log.debug("Unable to evict {0}", e, key);
return false;
}
}
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-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseEvictionAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,15 +21,15 @@
*/
package org.horizon.eviction.algorithms;
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionAction;
import org.horizon.eviction.EvictionAlgorithm;
import org.horizon.eviction.EvictionEvent;
import org.horizon.eviction.EvictionEvent.Type;
import org.horizon.eviction.EvictionException;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
@@ -42,18 +42,20 @@
* Algorithms. To extend this abstract class to make an Eviction Algorithm, implement the abstract methods and a
* policy.
*
- * @author Daniel Huang - dhuang(a)jboss.org 10/2005
+ * @author (various)
* @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
+ * @author Manik Surtani
* @since 1.0
*/
-public abstract class BaseEvictionAlgorithm<K> implements EvictionAlgorithm<K> {
+public abstract class BaseEvictionAlgorithm implements EvictionAlgorithm {
private static final Log log = LogFactory.getLog(BaseEvictionAlgorithm.class);
private static final boolean trace = log.isTraceEnabled();
- protected EvictionAction<K> evictionAction;
+
+ protected EvictionAction evictionAction;
protected EvictionAlgorithmConfig evictionAlgorithmConfig;
- protected BlockingQueue<K> recycleQueue;
- protected EvictionQueue<K> evictionQueue;
- protected CacheSPI<K, ?> cache;
+ protected BlockingQueue recycleQueue;
+ protected EvictionQueue evictionQueue;
+ protected Cache cache;
/**
* This method will create an EvictionQueue implementation and prepare it for use.
@@ -61,7 +63,7 @@
* @return The created EvictionQueue to be used as the eviction queue for this algorithm.
* @see org.horizon.eviction.EvictionQueue
*/
- protected abstract EvictionQueue<K> setupEvictionQueue() throws EvictionException;
+ protected abstract EvictionQueue setupEvictionQueue() throws EvictionException;
/**
* This method will check whether the given node should be evicted or not.
@@ -69,10 +71,10 @@
* @param ne NodeEntry to test eviction for.
* @return True if the given node should be evicted. False if the given node should not be evicted.
*/
- protected abstract boolean shouldEvictNode(KeyEntry<K> ne);
+ protected abstract boolean shouldEvictNode(EntryEvictionData ne);
protected BaseEvictionAlgorithm() {
- recycleQueue = new LinkedBlockingQueue<K>(500000);
+ recycleQueue = new LinkedBlockingQueue(500000);
}
public synchronized void initialize() {
@@ -81,25 +83,17 @@
}
}
- public EvictionAction getEvictionActionPolicy() {
- return evictionAction;
- }
-
- public void setEvictionAction(EvictionAction<K> evictionAction) {
+ public void setEvictionAction(EvictionAction evictionAction) {
this.evictionAction = evictionAction;
}
- public EvictionAlgorithmConfig getEvictionAlgorithmConfig() {
- return evictionAlgorithmConfig;
- }
-
- public void assignToCache(CacheSPI<K, ?> cache, EvictionAlgorithmConfig evictionAlgorithmConfig) {
+ public void assignToCache(Cache<?, ?> cache, EvictionAlgorithmConfig evictionAlgorithmConfig) {
this.cache = cache;
this.evictionAlgorithmConfig = evictionAlgorithmConfig;
}
public boolean canIgnoreEvent(Type eventType) {
- return false; // don't ignore anything!
+ return false; // don't ignore anything by default
}
/**
@@ -109,11 +103,10 @@
* evicted but locked (during actual cache eviction) nodes.
*
* @param eventQueue queue containing eviction events
- * @throws org.horizon.eviction.EvictionException
- *
+ * @throws EvictionException
*/
- public void process(BlockingQueue<EvictionEvent<K>> eventQueue) throws org.horizon.eviction.EvictionException {
- if (trace) log.trace("process(): cache: " + cache);
+ public void process(BlockingQueue<EvictionEvent> eventQueue) throws EvictionException {
+ if (trace) log.trace("processing eviction event queue");
initialize();
this.processQueues(eventQueue);
this.emptyRecycleQueue();
@@ -128,13 +121,13 @@
* Get the underlying EvictionQueue implementation.
*
* @return the EvictionQueue used by this algorithm
- * @see org.horizon.eviction.EvictionQueue
+ * @see EvictionQueue
*/
public EvictionQueue getEvictionQueue() {
return this.evictionQueue;
}
- protected EvictionEvent<K> getNextInQueue(BlockingQueue<EvictionEvent<K>> queue) {
+ protected EvictionEvent getNextInQueue(BlockingQueue<EvictionEvent> queue) {
try {
return queue.poll(0, TimeUnit.SECONDS);
}
@@ -149,57 +142,50 @@
* <p/>
* - On AddEvents a new element is added into the eviction queue - On RemoveEvents, the removed element is removed
* from the eviction queue. - On VisitEvents, the visited node has its eviction statistics updated (idleTime,
- * numberOfNodeVisists, etc..)
+ * numberOfVisists, etc..)
*
* @param queue queue to inspect
- * @throws org.horizon.eviction.EvictionException
- * in the event of problems
+ * @throws EvictionException in the event of problems
*/
- protected void processQueues(BlockingQueue<EvictionEvent<K>> queue) throws org.horizon.eviction.EvictionException {
- EvictionEvent<K> node;
+ protected void processQueues(BlockingQueue<EvictionEvent> queue) throws EvictionException {
+ EvictionEvent event;
int count = 0;
- while ((node = getNextInQueue(queue)) != null) {
+ while ((event = getNextInQueue(queue)) != null) {
count++;
- switch (node.getEventType()) {
- case ADD_NODE_EVENT:
- this.processAddedNodes(node);
+ switch (event.getEventType()) {
+ case ADD_ENTRY_EVENT:
+ this.processAddedNodes(event);
break;
- case REMOVE_NODE_EVENT:
- this.processRemovedNodes(node);
+ case REMOVE_ENTRY_EVENT:
+ this.processRemovedNodes(event);
break;
- case VISIT_NODE_EVENT:
- this.processVisitedNodes(node);
+ case VISIT_ENTRY_EVENT:
+ this.processVisitedNodes(event);
break;
- case ADD_ELEMENT_EVENT:
- this.processAddedElement(node);
- break;
- case REMOVE_ELEMENT_EVENT:
- this.processRemovedElement(node);
- break;
case MARK_IN_USE_EVENT:
- this.processMarkInUseNodes(node.getKey(), node.getInUseTimeout());
+ this.processMarkInUseNodes(event.getKey(), event.getInUseTimeout());
break;
- case UNMARK_USE_EVENT:
- this.processUnmarkInUseNodes(node.getKey());
+ case UNMARK_IN_USE_EVENT:
+ this.processUnmarkInUseNodes(event.getKey());
break;
default:
- throw new RuntimeException("Illegal Eviction Event type " + node.getEventType());
+ throw new RuntimeException("Illegal Eviction Event type " + event.getEventType());
}
}
- if (trace) log.trace("processed " + count + " node events");
+ if (trace) log.trace("processed {0} eviction events", count);
}
- protected void evict(KeyEntry<K> ne) {
- if (ne != null) {
- evictionQueue.removeNodeEntry(ne);
- if (!evictionAction.evict(ne.getKey())) {
+ protected void evict(EntryEvictionData data) {
+ if (data != null) {
+ evictionQueue.remove(data);
+ if (!evictionAction.evict(data.getKey())) {
try {
- boolean result = recycleQueue.offer(ne.getKey(), 5, TimeUnit.SECONDS);
+ boolean result = recycleQueue.offer(data.getKey(), 5, TimeUnit.SECONDS);
if (!result) {
- log.warn("Unable to add Fqn[" + ne.getKey() + "] to recycle " +
- "queue because it's full. This is often sign that " +
+ log.warn("Unable to add key {0} to the recycle queue." +
+ "This is often sign that " +
"evictions are not occurring and nodes that should be " +
- "evicted are piling up waiting to be evicted.");
+ "evicted are piling up waiting to be evicted.", data.getKey());
}
}
catch (InterruptedException e) {
@@ -209,150 +195,84 @@
}
}
- protected void processMarkInUseNodes(K key, long inUseTimeout) throws EvictionException {
- if (trace) {
- log.trace("Marking " + key + " as in use with a usage timeout of " + inUseTimeout);
- }
+ 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);
- KeyEntry ne = evictionQueue.getNodeEntry(key);
+ EntryEvictionData ne = evictionQueue.get(key);
if (ne != null) {
ne.setCurrentlyInUse(true, inUseTimeout);
}
}
- protected void processUnmarkInUseNodes(K key) throws EvictionException {
- if (trace) {
- log.trace("Unmarking node " + key + " as in use");
- }
+ protected void processUnmarkInUseNodes(Object key) throws EvictionException {
+ if (trace) log.trace("Unmarking node {0} as in use", key);
- KeyEntry ne = evictionQueue.getNodeEntry(key);
+ EntryEvictionData ne = evictionQueue.get(key);
if (ne != null) {
ne.setCurrentlyInUse(false, 0);
}
}
- /**
- * Convenience method, which calls {@link #processAddedNodes(EvictionEvent , int)} using values in the
- * evictedEventNode for number of added elements and the resetElementCount flag.
- *
- * @param evictedEventNode an evictedEventNode to process
- * @throws EvictionException on problems
- */
- protected void processAddedNodes(EvictionEvent<K> evictedEventNode) throws EvictionException {
- processAddedNodes(evictedEventNode, evictedEventNode.getElementDifference());
- }
-
- protected void processAddedNodes(EvictionEvent<K> evictedEventNode, int numAddedElements) throws EvictionException {
- K key = evictedEventNode.getKey();
- if (trace) log.trace("Adding node " + key + " with " + numAddedElements + " elements to eviction queue");
- KeyEntry<K> ne = evictionQueue.getNodeEntry(key);
- if (ne != null) {
- ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
- ne.incerementNumberOfNodeVisits();
- ne.setNumberOfElements(ne.getNumberOfElements() + numAddedElements);
- if (trace) log.trace("Queue already contains " + ne.getKey() + " processing it as visited");
+ protected void processAddedNodes(EvictionEvent evictedEventNode) throws EvictionException {
+ Object key = evictedEventNode.getKey();
+ if (trace) log.trace("Adding entry {0} to eviction queue", key);
+ EntryEvictionData data = evictionQueue.get(key);
+ if (data != null) {
+ data.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
+ data.incerementNumberOfNodeVisits();
+ if (trace) log.trace("Queue already contains key. Processing it as visited.");
processVisitedNodes(evictedEventNode);
return;
}
- ne = new KeyEntry<K>(1, evictedEventNode.getCreationTimestamp(), numAddedElements, key);
- evictionQueue.addNodeEntry(ne);
- ne.setQueue(evictionQueue);
- if (trace) log.trace(ne.getKey() + " added successfully to eviction queue");
+ data = new EntryEvictionData(1, evictedEventNode.getCreationTimestamp(), key);
+ evictionQueue.add(data);
+ if (trace) log.trace("Added successfully to eviction queue");
}
- /**
- * Remove a node from cache.
- * <p/>
- * This method will remove the node from the eviction queue as well as evict the node from cache.
- * <p/>
- * If a node cannot be removed from cache, this method will remove it from the eviction queue and place the element
- * into the recycleQueue. Each node in the recycle queue will get retried until proper cache eviction has taken
- * place.
- * <p/>
- * Because EvictionQueues are collections, when iterating them from an iterator, use iterator.remove() to avoid
- * ConcurrentModificationExceptions. Use the boolean parameter to indicate the calling context.
- *
- * @throws EvictionException
- */
- protected void processRemovedNodes(EvictionEvent<K> evictedEventNode) throws EvictionException {
- K key = evictedEventNode.getKey();
+ protected void processRemovedNodes(EvictionEvent evictedEventNode) throws EvictionException {
+ Object key = evictedEventNode.getKey();
- if (trace) {
- log.trace("Removing key " + key + " from eviction queue and attempting eviction");
- }
+ if (trace) log.trace("Removing key {0} from eviction queue and attempting eviction", key);
- KeyEntry<K> ne = evictionQueue.getNodeEntry(key);
- if (ne != null) {
- evictionQueue.removeNodeEntry(ne);
+ EntryEvictionData data = evictionQueue.get(key);
+ if (data != null) {
+ evictionQueue.remove(data);
} else {
if (trace)
- log.trace("processRemoveNodes(): Can't find node associated with key: " + key
- + "Could have been evicted earlier. Will just continue.");
+ log.trace("Can't find entry eviction data associated with key {0}. Could have been evicted earlier.",
+ key);
return;
}
- if (trace) {
- log.trace(key + " removed from eviction queue");
- }
+ if (trace) log.trace("Removed from eviction queue");
}
/**
* Visit a node in cache.
* <p/>
- * This method will update the numVisits and modifiedTimestamp properties of the Node. These properties are used as
- * statistics to determine eviction (LRU, LFU, MRU, etc..)
+ * This method will update the numVisits and modifiedTimestamp properties. These properties are used as statistics to
+ * determine eviction (LRU, LFU, MRU, etc..)
* <p/>
- * *Note* that this method updates Node Entries by reference and does not put them back into the queue. For some
- * sorted collections, a remove, and a re-add is required to maintain the sorted order of the elements.
+ * *Note* that this method updates entries by reference and does not put them back into the queue. For some sorted
+ * collections, a remove, and a re-add is required to maintain the sorted order of the elements.
*
* @throws EvictionException
*/
- protected void processVisitedNodes(EvictionEvent<K> evictedEventNode) throws EvictionException {
- K key = evictedEventNode.getKey();
- KeyEntry<K> ne = evictionQueue.getNodeEntry(key);
- if (ne == null) {
- if (trace) log.trace("Visiting node that was not added to eviction queues. Assuming that it has 1 element.");
- this.processAddedNodes(evictedEventNode, 1);
+ protected void processVisitedNodes(EvictionEvent evictedEventNode) throws EvictionException {
+ Object key = evictedEventNode.getKey();
+ EntryEvictionData data = evictionQueue.get(key);
+ if (data == null) {
+ if (trace) log.trace("Visiting entry {0} that has not added to eviction queues before.", key);
+ this.processAddedNodes(evictedEventNode);
return;
}
// note this method will visit and modify the node statistics by reference!
// if a collection is only guaranteed sort order by adding to the collection,
// this implementation will not guarantee sort order.
- ne.incerementNumberOfNodeVisits();
- ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
+ data.incerementNumberOfNodeVisits();
+ data.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
}
- protected void processRemovedElement(EvictionEvent<K> evictedEventNode) throws EvictionException {
- K key = evictedEventNode.getKey();
- KeyEntry<K> ne = evictionQueue.getNodeEntry(key);
-
- if (ne == null) {
- if (trace)
- log.trace("Removing element from " + key + " but eviction queue does not contain this node. " +
- "Ignoring removeElement event.");
- return;
- }
-
- ne.setNumberOfElements(ne.getNumberOfElements() - 1);
- // also treat it as a node visit.
- ne.incerementNumberOfNodeVisits();
- ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
- }
-
- protected void processAddedElement(EvictionEvent<K> evictedEventNode) throws EvictionException {
- K key = evictedEventNode.getKey();
- KeyEntry<K> ne = evictionQueue.getNodeEntry(key);
- if (ne == null) {
- if (trace) log.trace("Adding element " + key + " for a node that doesn't exist yet. Process as an add.");
- this.processAddedNodes(evictedEventNode, 1);
- return;
- }
- ne.setNumberOfElements(ne.getNumberOfElements() + 1);
- ne.incerementNumberOfNodeVisits();// also treat it as a node visit.
- ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
- }
-
-
/**
* Empty the Recycle Queue.
* <p/>
@@ -362,7 +282,7 @@
*/
protected void emptyRecycleQueue() throws EvictionException {
while (true) {
- K key;
+ Object key;
try {
key = recycleQueue.poll(0, TimeUnit.SECONDS);
}
@@ -392,12 +312,11 @@
}
protected void prune() throws EvictionException {
- KeyEntry<K> entry;
- while ((entry = evictionQueue.getFirstNodeEntry()) != null) {
- if (this.shouldEvictNode(entry)) {
- this.evict(entry);
+ for (EntryEvictionData data : evictionQueue) {
+ if (data != null && shouldEvictNode(data)) {
+ evict(data);
} else {
- break;
+ break; // assume the rest won't need to be evicted either
}
}
}
@@ -407,6 +326,17 @@
*/
@Override
public String toString() {
- return super.toString() + " recycle=" + recycleQueue.size() + " evict=" + evictionQueue.getNumberOfNodes();
+ return super.toString() + " recycleQueueSize=" + recycleQueue.size() + " evictionQueueSize=" + evictionQueue.size();
}
+
+ /**
+ * A helper for implementations that support the minimul time to live property
+ *
+ * @param minTTL minimum time to live, in millis, for all entries in the cache
+ * @param data eviction data on the entry to consider
+ * @return true if the entry is younger than the minimum time to live, false otherwise.
+ */
+ protected boolean isYoungerThanMinimumTimeToLive(long minTTL, EntryEvictionData data) {
+ return minTTL >= 1 && (data.getModifiedTimeStamp() + minTTL > System.currentTimeMillis());
+ }
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseSortedEvictionAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseSortedEvictionAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/BaseSortedEvictionAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -40,68 +40,53 @@
* @author Daniel Huang - dhuang(a)jboss.org - 10/2005
* @since 1.0
*/
-public abstract class BaseSortedEvictionAlgorithm<K> extends BaseEvictionAlgorithm<K> {
+public abstract class BaseSortedEvictionAlgorithm extends BaseEvictionAlgorithm {
private static final Log log = LogFactory.getLog(BaseSortedEvictionAlgorithm.class);
private static final boolean trace = log.isTraceEnabled();
@Override
- protected void processQueues(BlockingQueue<EvictionEvent<K>> queue) throws EvictionException {
- boolean evictionNodesModified = false;
+ protected void processQueues(BlockingQueue<EvictionEvent> queue) throws EvictionException {
+ boolean evictionQueueRequiresSort = false;
- EvictionEvent<K> node;
+ EvictionEvent event;
int count = 0;
- while ((node = getNextInQueue(queue)) != null) {
+ while ((event = getNextInQueue(queue)) != null) {
count++;
- switch (node.getEventType()) {
- case ADD_NODE_EVENT:
- this.processAddedNodes(node);
- evictionNodesModified = true;
+ switch (event.getEventType()) {
+ case ADD_ENTRY_EVENT:
+ this.processAddedNodes(event);
+ evictionQueueRequiresSort = true;
break;
- case REMOVE_NODE_EVENT:
- this.processRemovedNodes(node);
+ case REMOVE_ENTRY_EVENT:
+ this.processRemovedNodes(event);
break;
- case VISIT_NODE_EVENT:
- this.processVisitedNodes(node);
- evictionNodesModified = true;
+ case VISIT_ENTRY_EVENT:
+ this.processVisitedNodes(event);
+ evictionQueueRequiresSort = true;
break;
- case ADD_ELEMENT_EVENT:
- this.processAddedElement(node);
- evictionNodesModified = true;
- break;
- case REMOVE_ELEMENT_EVENT:
- this.processRemovedElement(node);
- evictionNodesModified = true;
- break;
default:
- throw new RuntimeException("Illegal Eviction Event type " + node.getEventType());
+ throw new RuntimeException("Illegal Eviction Event type " + event.getEventType());
}
}
- if (trace) log.trace("Eviction nodes visited or added requires resort of queue " + evictionNodesModified);
- this.resortEvictionQueue(evictionNodesModified);
- if (trace) log.trace("processed " + count + " node events");
+ if (evictionQueueRequiresSort) {
+ if (trace) log.trace("Eviction queue requires re-sort. Re-sorting.");
+ resortEvictionQueue();
+ }
+
+ if (trace) log.trace("processed {0} eviction events", count);
}
/**
* This method is called to resort the queue after add or visit events have occurred.
- * <p/>
- * If the parameter is true, the queue needs to be resorted. If it is false, the queue does not need resorting.
- *
- * @param evictionQueueModified True if the queue was added to or visisted during event processing.
*/
- protected void resortEvictionQueue(boolean evictionQueueModified) {
- if (!evictionQueueModified) {
- if (trace) log.debug("Eviction queue not modified. Resort unnecessary.");
- return;
- }
+ protected void resortEvictionQueue() {
long begin = System.currentTimeMillis();
- ((SortedEvictionQueue) evictionQueue).resortEvictionQueue();
+ ((SortedEvictionQueue) evictionQueue).reSortEvictionQueue();
if (trace) {
- long end = System.currentTimeMillis();
- long diff = end - begin;
- log.trace("Took " + diff + "ms to sort queue with " + getEvictionQueue().getNumberOfNodes() + " elements");
+ log.trace("Took {0} millis to re-sort queue with {1} elements",
+ System.currentTimeMillis() - begin, getEvictionQueue().size());
}
}
-
}
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ElementSizeAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ElementSizeAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ElementSizeAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,62 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction.algorithms;
-
-import org.horizon.config.EvictionAlgorithmConfig;
-import org.horizon.eviction.ElementSizeAlgorithmConfig;
-import org.horizon.eviction.ElementSizeQueue;
-import org.horizon.eviction.EvictionException;
-import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
-
-/**
- * @author Daniel Huang
- * @since 1.0
- */
-public class ElementSizeAlgorithm<K> extends BaseSortedEvictionAlgorithm<K> {
- @Override
- protected EvictionQueue<K> setupEvictionQueue() throws EvictionException {
- return new ElementSizeQueue<K>();
- }
-
- @Override
- protected boolean shouldEvictNode(KeyEntry<K> ne) {
- // check the minimum time to live and see if we should not evict the node. This check will
- // ensure that, if configured, nodes are kept alive for at least a minimum period of time.
- if (ne.isYoungerThanMinimumTimeToLive(evictionAlgorithmConfig.getMinTimeToLive())) return false;
- int size = this.getEvictionQueue().getNumberOfNodes();
- ElementSizeAlgorithmConfig config = (ElementSizeAlgorithmConfig) evictionAlgorithmConfig;
- return config.getMaxNodes() > -1 && size > config.getMaxNodes() || ne.getNumberOfElements() > config.getMaxElementsPerNode();
- }
-
- @Override
- protected void prune() throws EvictionException {
- super.prune();
-
- // clean up the Queue's eviction removals
- ((ElementSizeQueue) this.evictionQueue).prune();
- }
-
- public Class<? extends EvictionAlgorithmConfig> getConfigurationClass() {
- return ElementSizeAlgorithmConfig.class;
- }
-}
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ExpirationAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ExpirationAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/ExpirationAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,322 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction.algorithms;
-
-import org.horizon.config.EvictionAlgorithmConfig;
-import org.horizon.eviction.EvictionEvent;
-import org.horizon.eviction.EvictionEvent.Type;
-import org.horizon.eviction.EvictionException;
-import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.ExpirationAlgorithmConfig;
-import org.horizon.eviction.KeyEntry;
-import org.horizon.logging.Log;
-import org.horizon.logging.LogFactory;
-
-import java.util.Iterator;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.BlockingQueue;
-
-/**
- * Eviction algorithm that uses a key in the Node data that indicates the time the node should be evicted. The key must
- * be a java.lang.Long object, with the time to expire as milliseconds past midnight January 1st, 1970 UTC (the same
- * relative time as provided by {@link java.lang.System#currentTimeMillis()}).
- * <p/>
- * This algorithm also obeys the configuration key {@link org.horizon.eviction.ExpirationAlgorithmConfig#getMaxNodes()},
- * and will evict the soonest to expire entires first to reduce the region size. If there are not enough nodes with
- * expiration keys set, a warning is logged.
- * <p/>
- * If a node in the eviction region does not have an expiration value, then {@link
- * org.horizon.eviction.ExpirationAlgorithmConfig#getTimeToLive()} (if set) will be used. The expiration is updated when
- * a node is added or updated.
- * <p/>
- * If there is no time-to-live set, and a node in the eviction region does not have an expiration value, then that node
- * will never be evicted. As forgetting to indicate an expiration value is likely a mistake, a warning message is
- * logged by this class. This warning, however, can be disabled through {@link org.horizon.eviction.ExpirationAlgorithmConfig#setWarnNoExpirationKey(boolean)}.
- * <p/>
- * A node's expiration time can be changed by setting a new value in the node.
- * <p/>
- * Example usage:
- * <pre>
- * Cache cache;
- * Fqn fqn1 = Fqn.fromString("/node/1");
- * Long future = new Long(System.currentTimeMillis() + 2000);
- * cache.put(fqn1, ExpirationConfiguration.EXPIRATION_KEY, future);
- * cache.put(fqn1, "foo");
- * assertTrue(cache.get(fqn1) != null);
- * <p/>
- * Thread.sleep(5000); // 5 seconds
- * assertTrue(cache.get(fqn1) == null);
- * <p/>
- * </pre>
- *
- * @author (various)
- * @since 1.0
- */
-public class ExpirationAlgorithm<K> extends BaseEvictionAlgorithm<K> {
-
- private static final Log log = LogFactory.getLog(ExpirationAlgorithm.class);
- private static final boolean trace = log.isTraceEnabled();
-
- private ExpirationAlgorithmConfig config;
-
- private SortedSet<ExpirationEntry<K>> set;
-
- /**
- * Constructs a new algorithm with a policy.
- */
- public ExpirationAlgorithm() {
- this.set = new TreeSet<ExpirationEntry<K>>();
- }
-
- private void addEvictionEntry(EvictionEvent<K> node) {
- K key = node.getKey();
- addEvictionEntry(key);
- }
-
- private void addEvictionEntry(K key) {
- Long l = getExpiration();
- if (l == null) {
- if (config.isWarnNoExpirationKey() && log.isWarnEnabled())
- log.warn("No expiration key '" + config.getExpirationKeyName() + "' for Node: " + key);
- else if (log.isDebugEnabled())
- log.debug("No expiration key for Node: " + key);
- } else {
- setExpiration(key, l);
- }
- }
-
- private void setExpiration(K key, Long l) {
- ExpirationEntry<K> ee = new ExpirationEntry<K>(key, l);
- if (trace) log.trace("adding eviction entry: " + ee);
- set.add(ee);
- }
-
- private Long getExpiration() {
- return (Long) cache.getDirect(config.getExpirationKeyName());
- }
-
- @Override
- protected void processQueues(BlockingQueue<EvictionEvent<K>> queue) throws EvictionException {
- EvictionEvent<K> node;
- int count = 0;
- while ((node = getNextInQueue(queue)) != null) {
- count++;
- switch (node.getEventType()) {
- case ADD_NODE_EVENT:
- case ADD_ELEMENT_EVENT:
- addEvictionEntry(node);
- break;
- case REMOVE_ELEMENT_EVENT:
- case REMOVE_NODE_EVENT:
- case UNMARK_USE_EVENT:
- // Removals will be noticed when double-checking expiry time
- // removeEvictionEntry(node);
- break;
- case VISIT_NODE_EVENT:
- // unused
- break;
- case MARK_IN_USE_EVENT:
- markInUse(node);
- break;
- default:
- throw new RuntimeException("Illegal Eviction Event type " + node.getEventType());
- }
- }
-
- if (trace) log.trace("processed " + count + " node events in cache: " + cache.getName());
- }
-
- private void markInUse(EvictionEvent<K> node) {
- long expiration = node.getInUseTimeout() + System.currentTimeMillis();
- setExpiration(node.getKey(), expiration);
- }
-
- @Override
- protected void prune() throws EvictionException {
- if (set.isEmpty())
- return;
- long now = System.currentTimeMillis();
- int max = config.getMaxNodes();
- for (Iterator<ExpirationEntry<K>> i = set.iterator(); i.hasNext();) {
- ExpirationEntry<K> ee = i.next();
- Long ce = getExpiration();
- if (ce == null || ce > ee.getExpiration()) {
- // Expiration now older
- i.remove();
- continue;
- }
- if (ee.getExpiration() < now || (max != 0 && set.size() > max)) {
- i.remove();
- evictionAction.evict(ee.getKey());
- } else {
- break;
- }
- }
- if (max != 0 && max > set.size())
- log.warn("Unable to remove nodes to reduce region size below " +
- config.getMaxNodes() + ". " +
- "Set expiration for nodes in this region");
- }
-
- @Override
- public void resetEvictionQueue() {
- for (ExpirationEntry<K> ee : set) {
- addEvictionEntry(ee.getKey());
- }
- }
-
- @Override
- @SuppressWarnings(value = "unchecked")
- protected EvictionQueue<K> setupEvictionQueue() throws EvictionException {
- this.config = (ExpirationAlgorithmConfig) evictionAlgorithmConfig;
- return new DummyEvictionQueue<K>();
- }
-
- @Override
- protected boolean shouldEvictNode(KeyEntry<K> ne) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean canIgnoreEvent(Type eventType) {
- return (eventType == EvictionEvent.Type.VISIT_NODE_EVENT);
- }
-
- public Class<? extends EvictionAlgorithmConfig> getConfigurationClass() {
- return ExpirationAlgorithmConfig.class;
- }
-
- /**
- * Ordered list of FQN, with the expiration taken from the Map at the time of processing.
- */
- static class ExpirationEntry<K> implements Comparable<ExpirationEntry> {
- private long expiration;
-
- private K key;
-
- public ExpirationEntry(K key) {
- this.key = key;
- }
-
- public ExpirationEntry(K key, long expiration) {
- this.key = key;
- this.expiration = expiration;
- }
-
- /**
- * Compares expiration, then FQN order.
- */
- public int compareTo(ExpirationEntry ee) {
- long n = expiration - ee.expiration;
- if (n < 0)
- return -1;
- if (n > 0)
- return 1;
- return 0;
- }
-
- /**
- * @return the expiration
- */
- public long getExpiration() {
- return expiration;
- }
-
- /**
- * @return the fqn
- */
- public K getKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof ExpirationEntry))
- return false;
- ExpirationEntry ee = (ExpirationEntry) o;
- return expiration == ee.expiration && key.equals(ee.key);
- }
-
- @Override
- public int hashCode() {
- return (int) expiration ^ key.hashCode();
- }
-
- @Override
- public String toString() {
- long now = System.currentTimeMillis();
- long ttl = expiration - now;
- String sttl;
- if (ttl > 1000 * 60)
- sttl = (ttl / (1000 * 60)) + "min";
- else if (ttl > 1000)
- sttl = (ttl / 1000) + "s";
- else
- sttl = ttl + "ms";
- return "EE key=" + key + " ttl=" + sttl;
- }
- }
-
- class DummyEvictionQueue<K> implements EvictionQueue<K> {
-
- public void addNodeEntry(KeyEntry entry) {
- throw new UnsupportedOperationException();
- }
-
- public void clear() {
- set.clear();
- }
-
- public boolean containsNodeEntry(KeyEntry entry) {
- return false;
- }
-
- public KeyEntry<K> getFirstNodeEntry() {
- return null;
- }
-
- public KeyEntry<K> getNodeEntry(K k) {
- return null;
- }
-
- public int getNumberOfElements() {
- return set.size();
- }
-
- public int getNumberOfNodes() {
- return set.size();
- }
-
- public Iterator<KeyEntry<K>> iterator() {
- return null;
- }
-
- public void modifyElementCount(int difference) {
- }
-
- public void removeNodeEntry(KeyEntry entry) {
- throw new UnsupportedOperationException();
- }
- }
-
-}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,10 +21,11 @@
*/
package org.horizon.eviction.algorithms.NULL;
-import org.horizon.CacheSPI;
+import org.horizon.Cache;
import org.horizon.config.EvictionAlgorithmConfig;
import org.horizon.eviction.EvictionAction;
import org.horizon.eviction.EvictionAlgorithm;
+import org.horizon.eviction.EvictionEvent;
import org.horizon.eviction.EvictionEvent.Type;
import org.horizon.eviction.EvictionException;
import org.horizon.eviction.EvictionQueue;
@@ -64,11 +65,11 @@
// no-op
}
- public void assignToCache(CacheSPI cache, EvictionAlgorithmConfig evictionAlgorithmConfig) {
+ public void assignToCache(Cache<?, ?> cache, EvictionAlgorithmConfig evictionAlgorithmConfig) {
// no-op
}
- public void process(BlockingQueue queue) throws EvictionException {
+ public void process(BlockingQueue<EvictionEvent> queue) throws EvictionException {
// no-op
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -52,11 +52,11 @@
// no-op
}
- public NullEvictionAlgorithmConfig clone() throws CloneNotSupportedException {
- return (NullEvictionAlgorithmConfig) super.clone();
+ public NullEvictionAlgorithmConfig clone() {
+ try {
+ return (NullEvictionAlgorithmConfig) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Should never happen", e);
+ }
}
-
- public long getMinTimeToLive() {
- throw new UnsupportedOperationException("Not implemented");//todo please implement!
- }
}
\ No newline at end of file
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/NULL/NullEvictionQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,8 +21,8 @@
*/
package org.horizon.eviction.algorithms.NULL;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -48,7 +48,7 @@
/**
* No-op
*/
- public void addNodeEntry(KeyEntry entry) {
+ public void add(EntryEvictionData entryEvictionData) {
// no-op
}
@@ -59,71 +59,39 @@
// no-op
}
+ public EntryEvictionData get(Object key) {
+ return null; // no-op
+ }
+
/**
* Returns <code>false</code>
*/
- public boolean containsNodeEntry(KeyEntry entry) {
+ public boolean contains(EntryEvictionData entryEvictionData) {
return false;
}
/**
- * Returns <code>null</code>
- */
- public KeyEntry getFirstNodeEntry() {
- return null;
- }
-
- /**
- * Returns <code>null</code>
- */
- public KeyEntry getNodeEntry(Object fqn) {
- return null;
- }
-
- /**
- * Returns <code>null</code>
- */
- public KeyEntry getNodeEntry(String fqn) {
- return null;
- }
-
- /**
* Returns <code>0</code>
*/
- public int getNumberOfElements() {
+ public int size() {
return 0;
}
/**
- * Returns <code>0</code>
- */
- public int getNumberOfNodes() {
- return 0;
- }
-
- /**
* Returns an <code>Iterator</code> whose <code>hasNext()</code> returns <code>false</code>.
*/
- public Iterator iterator() {
+ public Iterator<EntryEvictionData> iterator() {
return NullQueueIterator.INSTANCE;
}
-
/**
* No-op
*/
- public void modifyElementCount(int difference) {
+ public void remove(EntryEvictionData entryEvictionData) {
// no-op
}
- /**
- * No-op
- */
- public void removeNodeEntry(KeyEntry entry) {
- // no-op
- }
-
- static class NullQueueIterator implements Iterator<KeyEntry> {
+ static class NullQueueIterator implements Iterator<EntryEvictionData> {
private static final NullQueueIterator INSTANCE = new NullQueueIterator();
private NullQueueIterator() {
@@ -133,7 +101,7 @@
return false;
}
- public KeyEntry next() {
+ public EntryEvictionData next() {
throw new NoSuchElementException("No more elements");
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/SortedEvictionQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/SortedEvictionQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/SortedEvictionQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -29,9 +29,9 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public interface SortedEvictionQueue<K> extends EvictionQueue<K> {
+public interface SortedEvictionQueue extends EvictionQueue {
/**
- * Provide contract to resort a sorted queue.
+ * Provide contract to re-sort a sorted queue.
*/
- void resortEvictionQueue();
+ void reSortEvictionQueue();
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -22,9 +22,9 @@
package org.horizon.eviction.algorithms.fifo;
import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionException;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import org.horizon.eviction.algorithms.BaseEvictionAlgorithm;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
@@ -36,33 +36,39 @@
* @author Morten Kvistgaard
* @since 1.0
*/
-public class FIFOAlgorithm<K> extends BaseEvictionAlgorithm<K> {
+public class FIFOAlgorithm extends BaseEvictionAlgorithm {
private static final Log log = LogFactory.getLog(FIFOAlgorithm.class);
private static final boolean trace = log.isTraceEnabled();
+ private FIFOAlgorithmConfig fifoAlgorithmConfig;
@Override
- protected EvictionQueue<K> setupEvictionQueue() throws EvictionException {
- return new FIFOQueue<K>();
+ protected EvictionQueue setupEvictionQueue() throws EvictionException {
+ return new FIFOQueue();
}
/**
* For FIFO, a node should be evicted if the queue size is >= to the configured maxNodes size.
*/
@Override
- protected boolean shouldEvictNode(KeyEntry ne) {
+ protected boolean shouldEvictNode(EntryEvictionData data) {
// check the minimum time to live and see if we should not evict the node. This check will
// ensure that, if configured, nodes are kept alive for at least a minimum period of time.
- if (ne.isYoungerThanMinimumTimeToLive(evictionAlgorithmConfig.getMinTimeToLive())) return false;
+ if (isYoungerThanMinimumTimeToLive(fifoAlgorithmConfig.getMinTimeToLive(), data)) return false;
- FIFOAlgorithmConfig config = (FIFOAlgorithmConfig) evictionAlgorithmConfig;
- if (trace) log.trace("Deciding whether node in queue " + ne.getKey() + " requires eviction.");
+ if (trace) log.trace("Deciding whether node in queue {0} requires eviction.", data.getKey());
- int size = this.getEvictionQueue().getNumberOfNodes();
- return config.getMaxNodes() != 0 && size > config.getMaxNodes();
+ int size = this.getEvictionQueue().size();
+ return fifoAlgorithmConfig.getMaxEntries() != 0 && size > fifoAlgorithmConfig.getMaxEntries();
}
public Class<? extends EvictionAlgorithmConfig> getConfigurationClass() {
return FIFOAlgorithmConfig.class;
}
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ fifoAlgorithmConfig = (FIFOAlgorithmConfig) evictionAlgorithmConfig;
+ }
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -40,14 +40,14 @@
public FIFOAlgorithmConfig() {
evictionAlgorithmClassName = FIFOAlgorithm.class.getName();
- // We require that maxNodes is set
- setMaxNodes(-1);
+ // We require that maxEntries is set
+ setMaxEntries(-1);
}
public FIFOAlgorithmConfig(int maxNodes) {
evictionAlgorithmClassName = FIFOAlgorithm.class.getName();
- // We require that maxNodes is set
- setMaxNodes(maxNodes);
+ // We require that maxEntries is set
+ setMaxEntries(maxNodes);
}
/**
@@ -56,8 +56,8 @@
@Override
public void validate() throws ConfigurationException {
super.validate();
- if (getMaxNodes() < 0) {
- throw new ConfigurationException("maxNodes must be must be " +
+ if (getMaxEntries() < 0) {
+ throw new ConfigurationException("maxEntries must be must be " +
"configured to a value greater than or equal to 0");
}
}
@@ -65,7 +65,7 @@
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
- ret.append("FIFOAlgorithmConfig: maxNodes = ").append(getMaxNodes());
+ ret.append("FIFOAlgorithmConfig: maxEntries = ").append(getMaxEntries());
return ret.toString();
}
@@ -77,12 +77,12 @@
@Override
public void reset() {
super.reset();
- setMaxNodes(-1);
+ setMaxEntries(-1);
evictionAlgorithmClassName = FIFOAlgorithm.class.getName();
}
@Override
- public FIFOAlgorithmConfig clone() throws CloneNotSupportedException {
+ public FIFOAlgorithmConfig clone() {
return (FIFOAlgorithmConfig) super.clone();
}
}
\ No newline at end of file
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/fifo/FIFOQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,8 +21,8 @@
*/
package org.horizon.eviction.algorithms.fifo;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -34,62 +34,40 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public class FIFOQueue<K> implements EvictionQueue<K> {
- private Map<K, KeyEntry<K>> keyMap;
- private int numElements = 0;
+public class FIFOQueue implements EvictionQueue {
+ private Map<Object, EntryEvictionData> keyMap;
protected FIFOQueue() {
- keyMap = new LinkedHashMap<K, KeyEntry<K>>();
+ keyMap = new LinkedHashMap<Object, EntryEvictionData>();
// We use a LinkedHashMap here because we want to maintain FIFO ordering and still get the benefits of
// O(n) = 1 for add/remove/search.
}
- public KeyEntry<K> getFirstNodeEntry() {
- if (keyMap.size() > 0) {
- return keyMap.values().iterator().next();
- }
- return null;
- }
-
- public KeyEntry<K> getNodeEntry(K key) {
+ public EntryEvictionData get(Object key) {
return keyMap.get(key);
}
- public boolean containsNodeEntry(KeyEntry<K> entry) {
- K key = entry.getKey();
- return this.getNodeEntry(key) != null;
+ public boolean contains(EntryEvictionData entryEvictionData) {
+ return keyMap.containsKey(entryEvictionData.getKey());
}
- public void removeNodeEntry(KeyEntry<K> entry) {
- KeyEntry<K> e = keyMap.remove(entry.getKey());
- this.numElements -= e.getNumberOfElements();
+ public void remove(EntryEvictionData entryEvictionData) {
+ keyMap.remove(entryEvictionData.getKey());
}
- public void addNodeEntry(KeyEntry<K> entry) {
- if (!this.containsNodeEntry(entry)) {
- keyMap.put(entry.getKey(), entry);
- this.numElements += entry.getNumberOfElements();
- }
+ public void add(EntryEvictionData entryEvictionData) {
+ if (!keyMap.containsKey(entryEvictionData.getKey())) keyMap.put(entryEvictionData.getKey(), entryEvictionData);
}
- public int getNumberOfNodes() {
+ public int size() {
return keyMap.size();
}
- public int getNumberOfElements() {
- return this.numElements;
- }
-
- public void modifyElementCount(int difference) {
- this.numElements += difference;
- }
-
public void clear() {
keyMap.clear();
- this.numElements = 0;
}
- public Iterator<KeyEntry<K>> iterator() {
+ public Iterator<EntryEvictionData> iterator() {
return keyMap.values().iterator();
}
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -22,9 +22,9 @@
package org.horizon.eviction.algorithms.lfu;
import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionException;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import org.horizon.eviction.algorithms.BaseSortedEvictionAlgorithm;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
@@ -49,22 +49,18 @@
public class LFUAlgorithm extends BaseSortedEvictionAlgorithm {
private static final Log log = LogFactory.getLog(LFUAlgorithm.class);
private static final boolean trace = log.isTraceEnabled();
+ private LFUAlgorithmConfig lfuAlgorithmConfig;
@Override
- protected boolean shouldEvictNode(KeyEntry ne) {
- if (trace) {
- log.trace("Deciding whether node in queue " + ne.getKey() + " requires eviction.");
- }
-
+ protected boolean shouldEvictNode(EntryEvictionData data) {
// check the minimum time to live and see if we should not evict the node. This check will
// ensure that, if configured, nodes are kept alive for at least a minimum period of time.
- if (ne.isYoungerThanMinimumTimeToLive(evictionAlgorithmConfig.getMinTimeToLive())) return false;
+ if (isYoungerThanMinimumTimeToLive(lfuAlgorithmConfig.getMinTimeToLive(), data)) return false;
- LFUAlgorithmConfig config = (LFUAlgorithmConfig) evictionAlgorithmConfig;
- int size = this.getEvictionQueue().getNumberOfNodes();
- if (config.getMaxNodes() > -1 && size > config.getMaxNodes()) {
+ int size = this.getEvictionQueue().size();
+ if (lfuAlgorithmConfig.getMaxEntries() > -1 && size > lfuAlgorithmConfig.getMaxEntries()) {
return true;
- } else if (size > config.getMinNodes()) {
+ } else if (size > lfuAlgorithmConfig.getMinEntries()) {
return true;
}
@@ -94,4 +90,10 @@
public Class<? extends EvictionAlgorithmConfig> getConfigurationClass() {
return LFUAlgorithmConfig.class;
}
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ lfuAlgorithmConfig = (LFUAlgorithmConfig) evictionAlgorithmConfig;
+ }
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -37,38 +37,38 @@
private static final long serialVersionUID = 1865801530398969179L;
@Dynamic
- private int minNodes;
+ private int minEntries;
public LFUAlgorithmConfig() {
evictionAlgorithmClassName = LFUAlgorithm.class.getName();
}
- public LFUAlgorithmConfig(int maxNodes, int minNodes) {
+ public LFUAlgorithmConfig(int maxNodes, int minEntries) {
this();
- setMaxNodes(maxNodes);
- setMinNodes(minNodes);
+ setMaxEntries(maxNodes);
+ setMinEntries(minEntries);
}
- public int getMinNodes() {
- return minNodes;
+ public int getMinEntries() {
+ return minEntries;
}
- public void setMinNodes(int minNodes) {
- testImmutability("minNodes");
- this.minNodes = minNodes;
+ public void setMinEntries(int minEntries) {
+ testImmutability("minEntries");
+ this.minEntries = minEntries;
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
- ret.append("LFUAlgorithmConfig: maxNodes = ").append(getMaxNodes()).append(" minNodes = ").append(getMinNodes());
+ ret.append("LFUAlgorithmConfig: maxEntries = ").append(getMaxEntries()).append(" minEntries = ").append(getMinEntries());
return ret.toString();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof LFUAlgorithmConfig && super.equals(obj)) {
- return (this.minNodes == ((LFUAlgorithmConfig) obj).minNodes);
+ return (this.minEntries == ((LFUAlgorithmConfig) obj).minEntries);
}
return false;
}
@@ -76,19 +76,19 @@
@Override
public int hashCode() {
int result = super.hashCode();
- result = 31 * result + minNodes;
+ result = 31 * result + minEntries;
return result;
}
@Override
- public LFUAlgorithmConfig clone() throws CloneNotSupportedException {
+ public LFUAlgorithmConfig clone() {
return (LFUAlgorithmConfig) super.clone();
}
@Override
public void reset() {
super.reset();
- minNodes = -1;
+ minEntries = -1;
evictionAlgorithmClassName = LFUAlgorithm.class.getName();
}
}
\ No newline at end of file
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lfu/LFUQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,10 +21,17 @@
*/
package org.horizon.eviction.algorithms.lfu;
-import org.horizon.eviction.KeyEntry;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.algorithms.SortedEvictionQueue;
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
/**
* LFUQueue EvictionQueue implementation for LFU Policy.
@@ -34,117 +41,69 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public class LFUQueue<K> implements SortedEvictionQueue<K> {
- private Map<K, KeyEntry<K>> keyMap;
- private LinkedList<KeyEntry<K>> evictionList;
- private Set<KeyEntry<K>> removalQueue;
- private Comparator<KeyEntry<K>> comparator;
+public class LFUQueue implements SortedEvictionQueue {
+ private Map<Object, EntryEvictionData> keyMap;
+ private LinkedList<EntryEvictionData> evictionList;
+ private Set<EntryEvictionData> removalQueue;
+ private Comparator<EntryEvictionData> comparator;
- private int numElements = 0;
-
protected LFUQueue() {
- keyMap = new HashMap<K, KeyEntry<K>>();
- comparator = new LFUComparator<K>();
- evictionList = new LinkedList<KeyEntry<K>>();
- removalQueue = new HashSet<KeyEntry<K>>();
+ keyMap = new HashMap<Object, EntryEvictionData>();
+ comparator = new LFUComparator();
+ evictionList = new LinkedList<EntryEvictionData>();
+ removalQueue = new HashSet<EntryEvictionData>();
}
- /**
- * Return the first node to evict.
- * <p/>
- * This method will return the least frequently used entry in the queue.
- */
- public KeyEntry<K> getFirstNodeEntry() {
- try {
- KeyEntry<K> ne;
- while ((ne = evictionList.getFirst()) != null) {
- if (removalQueue.contains(ne)) {
- evictionList.removeFirst();
- removalQueue.remove(ne);
- } else {
- break;
- }
- }
- return ne;
- }
- catch (NoSuchElementException e) {
- //
- }
- return null;
- }
-
- public KeyEntry<K> getNodeEntry(K key) {
+ public EntryEvictionData get(Object key) {
return keyMap.get(key);
}
- public boolean containsNodeEntry(KeyEntry<K> entry) {
- K key = entry.getKey();
- return this.getNodeEntry(key) != null;
+ public boolean contains(EntryEvictionData entryEvictionData) {
+ return keyMap.containsKey(entryEvictionData.getKey());
}
- public void removeNodeEntry(KeyEntry<K> entry) {
- KeyEntry<K> ne = keyMap.remove(entry.getKey());
- if (ne != null) {
+ public void remove(EntryEvictionData entryEvictionData) {
+ EntryEvictionData data = keyMap.remove(entryEvictionData.getKey());
+ if (data != null) {
// don't remove directly from the LinkedList otherwise we will incur a O(n) = n
// performance penalty for every removal! In the prune method for LFU, we will iterate the LinkedList through ONCE
// doing a single O(n) = n operation and removal. This is much preferred over running O(n) = n every single time
// remove is called. There is also special logic in the getFirstNodeEntry that will know to check
// the removalQueue before returning.
- this.removalQueue.add(ne);
- this.numElements -= ne.getNumberOfElements();
+ this.removalQueue.add(data);
}
}
- public void addNodeEntry(KeyEntry<K> entry) {
- if (!this.containsNodeEntry(entry)) {
- K key = entry.getKey();
- keyMap.put(key, entry);
- evictionList.add(entry);
- this.numElements += entry.getNumberOfElements();
+ public void add(EntryEvictionData entryEvictionData) {
+ if (!keyMap.containsKey(entryEvictionData)) {
+ Object key = entryEvictionData.getKey();
+ keyMap.put(key, entryEvictionData);
+ evictionList.add(entryEvictionData);
}
}
- public int getNumberOfNodes() {
+ public int size() {
return keyMap.size();
}
- public int getNumberOfElements() {
- return this.numElements;
- }
-
public void clear() {
keyMap.clear();
evictionList.clear();
removalQueue.clear();
- this.numElements = 0;
}
- public void resortEvictionQueue() {
+ public void reSortEvictionQueue() {
Collections.sort(evictionList, comparator);
}
- public void modifyElementCount(int difference) {
- this.numElements += difference;
- }
-
protected void prune() {
- Iterator<KeyEntry<K>> it = this.iterator();
+ Iterator<EntryEvictionData> it = this.iterator();
while (it.hasNext() && removalQueue.size() > 0) {
- if (removalQueue.remove(it.next())) {
- it.remove();
- }
+ if (removalQueue.remove(it.next())) it.remove();
}
}
- protected final List<KeyEntry<K>> getEvictionList() {
- return this.evictionList;
- }
-
- protected final Set<KeyEntry<K>> getRemovalQueue() {
- return this.removalQueue;
- }
-
- public Iterator<KeyEntry<K>> iterator() {
+ public Iterator<EntryEvictionData> iterator() {
return evictionList.iterator();
}
@@ -154,20 +113,18 @@
* This class will sort the eviction queue in the correct eviction order. The top of the list should evict before the
* bottom of the list.
* <p/>
- * The sort is based on ascending order of nodeVisits.
+ * The sort is based on ascending order of visits.
* <p/>
- * Note: this class has a natural ordering that is inconsistent with equals as defined by the java.lang.Comparator
+ * This class has a natural ordering that is inconsistent with equals as defined by the java.lang.Comparator
* contract.
*/
- protected static class LFUComparator<K> implements Comparator<KeyEntry<K>> {
+ protected static class LFUComparator implements Comparator<EntryEvictionData> {
- public int compare(KeyEntry<K> ne1, KeyEntry<K> ne2) {
- if (ne1.equals(ne2)) {
- return 0;
- }
+ public int compare(EntryEvictionData data1, EntryEvictionData data2) {
+ if (data1.equals(data2)) return 0;
- int neNodeHits = ne1.getNumberOfNodeVisits();
- int ne2NodeHits = ne2.getNumberOfNodeVisits();
+ int neNodeHits = data1.getNumberOfVisits();
+ int ne2NodeHits = data2.getNumberOfVisits();
if (neNodeHits > ne2NodeHits) {
return 1;
@@ -179,6 +136,5 @@
throw new RuntimeException("Should never reach this condition");
}
}
-
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -22,9 +22,9 @@
package org.horizon.eviction.algorithms.lru;
import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionException;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import org.horizon.eviction.algorithms.BaseEvictionAlgorithm;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
@@ -38,66 +38,67 @@
* @author Daniel Huang - dhuang(a)jboss.org
* @since 1.0
*/
-public class LRUAlgorithm<K> extends BaseEvictionAlgorithm<K> {
+public class LRUAlgorithm extends BaseEvictionAlgorithm {
private static final Log log = LogFactory.getLog(LRUAlgorithm.class);
private static final boolean trace = log.isTraceEnabled();
+ private LRUAlgorithmConfig lruAlgorithmConfig;
+
@Override
- protected EvictionQueue<K> setupEvictionQueue() throws EvictionException {
- return new LRUQueue<K>();
+ protected EvictionQueue setupEvictionQueue() throws EvictionException {
+ return new LRUQueue();
}
@Override
- protected boolean shouldEvictNode(KeyEntry<K> entry) {
+ protected boolean shouldEvictNode(EntryEvictionData entryEvictionData) {
// check the minimum time to live and see if we should not evict the node. This check will
// ensure that, if configured, nodes are kept alive for at least a minimum period of time.
- if (entry.isYoungerThanMinimumTimeToLive(evictionAlgorithmConfig.getMinTimeToLive())) return false;
+ if (isYoungerThanMinimumTimeToLive(lruAlgorithmConfig.getMinTimeToLive(), entryEvictionData)) return false;
- LRUAlgorithmConfig config = (LRUAlgorithmConfig) evictionAlgorithmConfig;
// no idle or max time limit
- if (config.getTimeToLive() < 0 && config.getMaxAge() < 0) return false;
+ if (lruAlgorithmConfig.getTimeToLive() < 0 && lruAlgorithmConfig.getMaxAge() < 0) return false;
long currentTime = System.currentTimeMillis();
- if (config.getTimeToLive() > -1) {
- long idleTime = currentTime - entry.getModifiedTimeStamp();
+ if (lruAlgorithmConfig.getTimeToLive() > -1) {
+ long idleTime = currentTime - entryEvictionData.getModifiedTimeStamp();
if (trace) {
- log.trace("Node " + entry.getKey() + " has been idle for " + idleTime + "ms");
+ log.trace("Node " + entryEvictionData.getKey() + " has been idle for " + idleTime + "ms");
}
- if ((idleTime >= (config.getTimeToLive()))) {
+ if ((idleTime >= (lruAlgorithmConfig.getTimeToLive()))) {
if (trace) {
- log.trace("Node " + entry.getKey() + " should be evicted because of idle time");
- log.trace("Time to live in millies is: " + (config.getTimeToLive()));
- log.trace("Config instance is: " + System.identityHashCode(config));
+ log.trace("Node " + entryEvictionData.getKey() + " should be evicted because of idle time");
+ log.trace("Time to live in millies is: " + (lruAlgorithmConfig.getTimeToLive()));
+ log.trace("Config instance is: " + System.identityHashCode(lruAlgorithmConfig));
}
return true;
}
}
- if (config.getMaxAge() > -1) {
- long objectLifeTime = currentTime - entry.getCreationTimeStamp();
+ if (lruAlgorithmConfig.getMaxAge() > -1) {
+ long objectLifeTime = currentTime - entryEvictionData.getCreationTimeStamp();
if (trace) {
- log.trace("Node " + entry.getKey() + " has been alive for " + objectLifeTime + "ms");
+ log.trace("Node " + entryEvictionData.getKey() + " has been alive for " + objectLifeTime + "ms");
}
- if ((objectLifeTime >= config.getMaxAge())) {
+ if ((objectLifeTime >= lruAlgorithmConfig.getMaxAge())) {
if (trace) {
- log.trace("Node " + entry.getKey() + " should be evicted because of max age");
+ log.trace("Node " + entryEvictionData.getKey() + " should be evicted because of max age");
}
return true;
}
}
if (trace) {
- log.trace("Node " + entry.getKey() + " should not be evicted");
+ log.trace("Node " + entryEvictionData.getKey() + " should not be evicted");
}
return false;
}
@Override
- protected void evict(KeyEntry<K> ne) {
- if (ne != null) {
- if (!evictionAction.evict(ne.getKey())) {
+ protected void evict(EntryEvictionData data) {
+ if (data != null) {
+ if (!evictionAction.evict(data.getKey())) {
try {
- recycleQueue.put(ne.getKey());
+ recycleQueue.put(data.getKey());
}
catch (InterruptedException e) {
log.debug("InterruptedException", e);
@@ -108,16 +109,16 @@
@Override
protected void prune() throws EvictionException {
- LRUQueue<K> lruQueue = (LRUQueue<K>) evictionQueue;
- KeyEntry<K> ne;
- Iterator<KeyEntry<K>> it = lruQueue.iterateLRUQueue();
+ LRUQueue lruQueue = (LRUQueue) evictionQueue;
+ EntryEvictionData data;
+ Iterator<EntryEvictionData> it = lruQueue.iterateLRUQueue();
while (it.hasNext()) {
- ne = it.next();
- if (ne.isNodeInUseAndNotTimedOut()) continue;
- if (this.shouldEvictNode(ne)) {
+ data = it.next();
+ if (data.isNodeInUseAndNotTimedOut()) continue;
+ if (this.shouldEvictNode(data)) {
it.remove();
- lruQueue.removeNodeEntryFromMaxAge(ne);
- this.evict(ne);
+ lruQueue.removeNodeEntryFromMaxAge(data);
+ this.evict(data);
} else {
break;
}
@@ -125,34 +126,34 @@
it = lruQueue.iterateMaxAgeQueue();
while (it.hasNext()) {
- ne = it.next();
- if (ne.isNodeInUseAndNotTimedOut()) continue;
- if (this.shouldEvictNode(ne)) {
+ data = it.next();
+ if (data.isNodeInUseAndNotTimedOut()) continue;
+ if (this.shouldEvictNode(data)) {
it.remove();
- lruQueue.removeNodeEntryFromLRU(ne);
- this.evict(ne);
+ lruQueue.removeNodeEntryFromLRU(data);
+ this.evict(data);
} else {
break;
}
}
- int maxNodes = ((LRUAlgorithmConfig) evictionAlgorithmConfig).getMaxNodes();
+ int maxNodes = ((LRUAlgorithmConfig) evictionAlgorithmConfig).getMaxEntries();
if (maxNodes <= 0) {
return;
}
it = lruQueue.iterateLRUQueue();
- while (evictionQueue.getNumberOfNodes() > maxNodes) {
- ne = it.next();
+ while (evictionQueue.size() > maxNodes) {
+ data = it.next();
if (trace) {
- log.trace("Node " + ne.getKey() + " will be evicted because of exceeding the maxNode limit." +
- " maxNode: " + maxNodes + " but current queue size is: " + evictionQueue.getNumberOfNodes());
+ log.trace("Node " + data.getKey() + " will be evicted because of exceeding the maxNode limit." +
+ " maxNode: " + maxNodes + " but current queue size is: " + evictionQueue.size());
}
- if (!ne.isNodeInUseAndNotTimedOut()) {
+ if (!data.isNodeInUseAndNotTimedOut()) {
it.remove();
- lruQueue.removeNodeEntryFromMaxAge(ne);
- this.evict(ne);
+ lruQueue.removeNodeEntryFromMaxAge(data);
+ this.evict(data);
}
}
}
@@ -160,4 +161,10 @@
public Class<? extends EvictionAlgorithmConfig> getConfigurationClass() {
return LRUAlgorithmConfig.class;
}
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ lruAlgorithmConfig = (LRUAlgorithmConfig) evictionAlgorithmConfig;
+ }
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -67,7 +67,7 @@
public LRUAlgorithmConfig(long timeToLive, int maxAge, int maxNodes) {
this(timeToLive, maxAge);
- this.maxNodes = maxNodes;
+ this.maxEntries = maxNodes;
}
/**
@@ -163,7 +163,7 @@
}
@Override
- public LRUAlgorithmConfig clone() throws CloneNotSupportedException {
+ public LRUAlgorithmConfig clone() {
return (LRUAlgorithmConfig) super.clone();
}
}
\ No newline at end of file
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/lru/LRUQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,8 +21,8 @@
*/
package org.horizon.eviction.algorithms.lru;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -37,121 +37,68 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public class LRUQueue<K> implements EvictionQueue<K> {
- private Map<K, KeyEntry<K>> maxAgeQueue;
- private Map<K, KeyEntry<K>> lruQueue;
- private long alternatingCount = 0;
- private int numElements = 0;
+public class LRUQueue implements EvictionQueue {
+ private Map<Object, EntryEvictionData> maxAgeQueue;
+ private Map<Object, EntryEvictionData> lruQueue;
protected LRUQueue() {
- maxAgeQueue = new LinkedHashMap<K, KeyEntry<K>>();
- lruQueue = new LinkedHashMap<K, KeyEntry<K>>(16, 0.75f, true);
+ maxAgeQueue = new LinkedHashMap<Object, EntryEvictionData>();
+ lruQueue = new LinkedHashMap<Object, EntryEvictionData>(16, 0.75f, true);
}
- /**
- * because the underlying queue is in two differently sorted queues, we alternate between them when calling a generic
- * getFirstNodeEntry. we must alternate to keep things balanced when evicting nodes based on the maxNodes attribute.
- * We don't want to just prune from one queue but rather we want to be able to prune from both.
- */
- public KeyEntry<K> getFirstNodeEntry() {
- KeyEntry<K> ne;
- if (alternatingCount % 2 == 0) {
- ne = this.getFirstLRUNodeEntry();
- if (ne == null) {
- ne = this.getFirstMaxAgeNodeEntry();
- }
- } else {
- ne = this.getFirstMaxAgeNodeEntry();
- if (ne == null) {
- ne = this.getFirstLRUNodeEntry();
- }
- }
- alternatingCount++;
- return ne;
- }
-
- public KeyEntry<K> getFirstLRUNodeEntry() {
- if (lruQueue.size() > 0) {
- return lruQueue.values().iterator().next();
- }
- return null;
- }
-
- public KeyEntry<K> getFirstMaxAgeNodeEntry() {
- if (maxAgeQueue.size() > 0) {
- return maxAgeQueue.values().iterator().next();
- }
- return null;
- }
-
- public KeyEntry<K> getNodeEntry(K key) {
+ public EntryEvictionData get(Object key) {
return lruQueue.get(key);
}
- public boolean containsNodeEntry(KeyEntry<K> entry) {
- return this.maxAgeQueue.containsKey(entry.getKey());
+ public boolean contains(EntryEvictionData entryEvictionData) {
+ return this.maxAgeQueue.containsKey(entryEvictionData.getKey());
}
- protected void removeNodeEntryFromLRU(KeyEntry<K> entry) {
- K key = entry.getKey();
- lruQueue.remove(key);
- }
-
- protected void removeNodeEntryFromMaxAge(KeyEntry<K> entry) {
- K key = entry.getKey();
- maxAgeQueue.remove(key);
- }
-
- public void removeNodeEntry(KeyEntry<K> entry) {
- if (!this.containsNodeEntry(entry)) {
- return;
+ public void remove(EntryEvictionData entryEvictionData) {
+ if (contains(entryEvictionData)) {
+ Object key = entryEvictionData.getKey();
+ EntryEvictionData data1 = lruQueue.remove(key);
+ EntryEvictionData data2 = maxAgeQueue.remove(key);
+ if (data1 == null || data2 == null) {
+ throw new RuntimeException("The queues are out of sync.");
+ }
}
- K key = entry.getKey();
- KeyEntry ne1 = lruQueue.remove(key);
- KeyEntry ne2 = maxAgeQueue.remove(key);
- if (ne1 == null || ne2 == null) {
- throw new RuntimeException("The queues are out of sync.");
- }
- this.numElements -= ne1.getNumberOfElements();
}
- public void addNodeEntry(KeyEntry<K> entry) {
- if (!this.containsNodeEntry(entry)) {
- K key = entry.getKey();
- maxAgeQueue.put(key, entry);
- lruQueue.put(key, entry);
- this.numElements += entry.getNumberOfElements();
+ public void add(EntryEvictionData entryEvictionData) {
+ if (!contains(entryEvictionData)) {
+ Object key = entryEvictionData.getKey();
+ maxAgeQueue.put(key, entryEvictionData);
+ lruQueue.put(key, entryEvictionData);
}
}
- public int getNumberOfNodes() {
+ public int size() {
return maxAgeQueue.size();
}
- public int getNumberOfElements() {
- return this.numElements;
- }
-
public void clear() {
maxAgeQueue.clear();
lruQueue.clear();
- this.numElements = 0;
}
- public void modifyElementCount(int difference) {
- this.numElements += difference;
+ public Iterator<EntryEvictionData> iterator() {
+ return lruQueue.values().iterator();
}
- public Iterator<KeyEntry<K>> iterator() {
+ public Iterator<EntryEvictionData> iterateLRUQueue() {
return lruQueue.values().iterator();
}
- protected final Iterator<KeyEntry<K>> iterateMaxAgeQueue() {
- return maxAgeQueue.values().iterator();
+ public void removeNodeEntryFromMaxAge(EntryEvictionData data) {
+ maxAgeQueue.remove(data.getKey());
}
- protected final Iterator<KeyEntry<K>> iterateLRUQueue() {
- return lruQueue.values().iterator();
+ public Iterator<EntryEvictionData> iterateMaxAgeQueue() {
+ return maxAgeQueue.values().iterator();
}
+ public void removeNodeEntryFromLRU(EntryEvictionData data) {
+ lruQueue.remove(data.getKey());
+ }
}
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionListEntry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionListEntry.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionListEntry.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,62 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction.algorithms.mru;
-
-import org.horizon.eviction.KeyEntry;
-
-/**
- * // TODO: MANIK: Document this
- *
- * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
- * @since 1.0
- */
-public class EvictionListEntry<K> {
- EvictionListEntry<K> next;
- KeyEntry<K> keyEntry;
- EvictionListEntry<K> previous;
-
- EvictionListEntry() {
- }
-
- EvictionListEntry(KeyEntry<K> keyEntry) {
- this.keyEntry = keyEntry;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof EvictionListEntry))
- return false;
- EvictionListEntry entry = (EvictionListEntry) o;
- return this.keyEntry.getKey().equals(entry.keyEntry.getKey());
- }
-
- @Override
- public int hashCode() {
- return this.keyEntry.getKey().hashCode();
- }
-
- @Override
- public String toString() {
- return "EvictionListEntry=" + keyEntry;
- }
-
-}
Deleted: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionQueueList.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionQueueList.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/EvictionQueueList.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,294 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.horizon.eviction.algorithms.mru;
-
-import org.horizon.eviction.KeyEntry;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-/**
- * @author Daniel Huang (dhuang(a)jboss.org)
- * @since 1.0
- */
-public class EvictionQueueList<K> {
- private EvictionListEntry<K> head;
- private EvictionListEntry<K> tail;
- private int modCount;
- private int size;
-
- EvictionQueueList() {
- head = null;
- tail = null;
- size = 0;
- modCount = 0;
- }
-
- void addToTop(EvictionListEntry<K> entry) {
- EvictionListEntry<K> formerHead = head;
- head = entry;
- // if there was no previous head then this list was empty.
- if (formerHead != null) {
- formerHead.previous = head;
- head.next = formerHead;
- head.previous = null;
- } else {
- tail = entry;
- }
- size++;
- modCount++;
- }
-
- void addToBottom(EvictionListEntry<K> entry) {
- EvictionListEntry<K> formerTail = tail;
- tail = entry;
- // if there was no previous head then this list was empty.
- if (formerTail != null) {
- tail.previous = formerTail;
- formerTail.next = tail;
- tail.next = null;
- } else {
- head = entry;
- }
- size++;
- modCount++;
- }
-
- void remove(EvictionListEntry<K> entry) {
- if (this.isEmpty()) {
- return;
- }
-
- if (isSingleNode(entry)) {
- head = null;
- tail = null;
- } else if (isTail(entry)) {
- tail = entry.previous;
- // unlink the last node.
- entry.previous.next = null;
- } else if (isHead(entry)) {
- head = entry.next;
- head.previous = null;
- } else {
- // node is in between two other nodes.
- entry.next.previous = entry.previous;
- entry.previous.next = entry.next;
- }
- size--;
- modCount++;
- }
-
- int size() {
- return this.size;
- }
-
- void clear() {
- head = null;
- tail = null;
- size = 0;
- modCount++;
- }
-
- EvictionListEntry<K> getFirst() {
- if (head == null) {
- throw new NoSuchElementException("List is empty");
- }
- return head;
- }
-
- EvictionListEntry getLast() {
- if (tail == null) {
- throw new NoSuchElementException("List is empty");
- }
- return tail;
- }
-
- @SuppressWarnings(value = "unchecked")
- Iterator<KeyEntry<K>> iterator() {
- return new EvictionListIterator();
- }
-
- KeyEntry[] toNodeEntryArray() {
- if (isEmpty()) {
- return null;
- }
- KeyEntry[] ret = new KeyEntry[size];
- int i = 0;
- EvictionListEntry temp = head;
-
- do {
- ret[i] = temp.keyEntry;
- temp = temp.next;
- i++;
- }
- while (temp != null);
-
- return ret;
- }
-
- EvictionListEntry[] toArray() {
- if (isEmpty()) {
- return null;
- }
- EvictionListEntry[] ret = new EvictionListEntry[size];
- int i = 0;
- EvictionListEntry temp = head;
-
- do {
- ret[i] = temp;
- temp = temp.next;
- i++;
- }
- while (temp != null);
-
- return ret;
- }
-
- void fromArray(EvictionListEntry<K>[] evictionListEntries) {
-
- for (EvictionListEntry<K> evictionListEntry : evictionListEntries) {
- this.addToBottom(evictionListEntry);
- }
- }
-
- private boolean isEmpty() {
- return head == null && tail == null;
- }
-
- private boolean isSingleNode(EvictionListEntry entry) {
- return isTail(entry) && isHead(entry);
- }
-
- private boolean isTail(EvictionListEntry entry) {
- return entry.next == null;
- }
-
- private boolean isHead(EvictionListEntry entry) {
- return entry.previous == null;
- }
-
- @Override
- public String toString() {
- return Arrays.asList(toArray()).toString();
- }
-
- static class EvictionListComparator implements Comparator<EvictionListEntry> {
- Comparator<KeyEntry> nodeEntryComparator;
-
- EvictionListComparator(Comparator<KeyEntry> nodeEntryComparator) {
- this.nodeEntryComparator = nodeEntryComparator;
- }
-
- public int compare(EvictionListEntry e1, EvictionListEntry e2) {
- return nodeEntryComparator.compare(e1.keyEntry, e2.keyEntry);
- }
- }
-
- class EvictionListIterator implements ListIterator {
- EvictionListEntry<K> next = head;
- EvictionListEntry<K> previous;
- EvictionListEntry<K> cursor;
-
- int initialModCount = EvictionQueueList.this.modCount;
-
- public boolean hasNext() {
- this.doConcurrentModCheck();
- return next != null;
- }
-
- public KeyEntry<K> next() {
- this.doConcurrentModCheck();
- this.forwardCursor();
- return cursor.keyEntry;
- }
-
- public boolean hasPrevious() {
- this.doConcurrentModCheck();
- return previous != null;
- }
-
- public KeyEntry<K> previous() {
- this.doConcurrentModCheck();
- this.rewindCursor();
- return cursor.keyEntry;
- }
-
- public int nextIndex() {
- throw new UnsupportedOperationException();
- }
-
- public int previousIndex() {
- throw new UnsupportedOperationException();
- }
-
- public void remove() {
- this.doConcurrentModCheck();
- if (cursor == null) {
- throw new IllegalStateException("Cannot remove from iterator when there is nothing at the current iteration point");
- }
- EvictionQueueList.this.remove(cursor);
- cursor = null;
- initialModCount++;
- }
-
- @SuppressWarnings(value = "unchecked")
- public void set(Object o) {
- this.doConcurrentModCheck();
- cursor.keyEntry = (KeyEntry<K>) o;
- }
-
- public void add(Object o) {
- this.doConcurrentModCheck();
- initialModCount++;
- }
-
- private void doConcurrentModCheck() {
- if (EvictionQueueList.this.modCount != initialModCount) {
- throw new ConcurrentModificationException();
- }
- }
-
- private void forwardCursor() {
- if (next == null) {
- throw new NoSuchElementException("No more objects to iterate.");
- }
- previous = cursor;
- cursor = next;
- next = cursor.next;
- }
-
- private void rewindCursor() {
- if (previous == null) {
- throw new NoSuchElementException();
- }
- next = cursor;
- cursor = previous;
- previous = cursor.previous;
- }
- }
-
-}
-
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithm.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithm.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithm.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -22,10 +22,10 @@
package org.horizon.eviction.algorithms.mru;
import org.horizon.config.EvictionAlgorithmConfig;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionEvent;
import org.horizon.eviction.EvictionException;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import org.horizon.eviction.algorithms.BaseEvictionAlgorithm;
/**
@@ -39,29 +39,36 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public class MRUAlgorithm<K> extends BaseEvictionAlgorithm<K> {
+public class MRUAlgorithm extends BaseEvictionAlgorithm {
+
+ MRUAlgorithmConfig mruAlgorithmConfig;
+
@Override
- protected EvictionQueue<K> setupEvictionQueue() throws EvictionException {
- return new MRUQueue<K>();
+ protected EvictionQueue setupEvictionQueue() throws EvictionException {
+ return new MRUQueue();
}
@Override
- protected boolean shouldEvictNode(KeyEntry ne) {
+ protected boolean shouldEvictNode(EntryEvictionData data) {
// check the minimum time to live and see if we should not evict the node. This check will
// ensure that, if configured, nodes are kept alive for at least a minimum period of time.
- if (ne.isYoungerThanMinimumTimeToLive(evictionAlgorithmConfig.getMinTimeToLive())) return false;
-
- MRUAlgorithmConfig config = (MRUAlgorithmConfig) evictionAlgorithmConfig;
- return evictionQueue.getNumberOfNodes() > config.getMaxNodes();
+ return !isYoungerThanMinimumTimeToLive(mruAlgorithmConfig.getMinTimeToLive(), data) &&
+ evictionQueue.size() > mruAlgorithmConfig.getMaxEntries();
}
@Override
- protected void processVisitedNodes(EvictionEvent<K> evictedEventNode) throws EvictionException {
+ protected void processVisitedNodes(EvictionEvent evictedEventNode) throws EvictionException {
super.processVisitedNodes(evictedEventNode);
- ((MRUQueue<K>) evictionQueue).moveToTopOfStack(evictedEventNode.getKey());
+ ((MRUQueue) evictionQueue).moveToTopOfStack(evictedEventNode.getKey());
}
public Class<? extends EvictionAlgorithmConfig> getConfigurationClass() {
return MRUAlgorithmConfig.class;
}
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ mruAlgorithmConfig = (MRUAlgorithmConfig) evictionAlgorithmConfig;
+ }
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithmConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithmConfig.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUAlgorithmConfig.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -27,7 +27,7 @@
/**
* Configuration for {@link MRUAlgorithm}.
* <p/>
- * Requires a "maxNodes" attribute otherwise a ConfigurationException is thrown.
+ * Requires a "maxEntries" attribute otherwise a ConfigurationException is thrown.
*
* @author Manik Surtani
* @since 1.0
@@ -40,13 +40,13 @@
public MRUAlgorithmConfig() {
evictionAlgorithmClassName = MRUAlgorithm.class.getName();
- // We require that maxNodes is set
- setMaxNodes(-1);
+ // We require that maxEntries is set
+ setMaxEntries(-1);
}
public MRUAlgorithmConfig(int maxNodes) {
evictionAlgorithmClassName = MRUAlgorithm.class.getName();
- setMaxNodes(maxNodes);
+ setMaxEntries(maxNodes);
}
/**
@@ -55,15 +55,15 @@
@Override
public void validate() throws ConfigurationException {
super.validate();
- if (getMaxNodes() < 0)
- throw new ConfigurationException("maxNodes not configured");
+ if (getMaxEntries() < 0)
+ throw new ConfigurationException("maxEntries not configured");
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("MRUAlgorithmConfig: ").
- append(" maxNodes =").append(getMaxNodes());
+ append(" maxEntries =").append(getMaxEntries());
return str.toString();
}
@@ -75,12 +75,12 @@
@Override
public void reset() {
super.reset();
- setMaxNodes(-1);
+ setMaxEntries(-1);
evictionAlgorithmClassName = MRUAlgorithm.class.getName();
}
@Override
- public MRUAlgorithmConfig clone() throws CloneNotSupportedException {
+ public MRUAlgorithmConfig clone() {
return (MRUAlgorithmConfig) super.clone();
}
Modified: core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUQueue.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUQueue.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/eviction/algorithms/mru/MRUQueue.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,13 +21,13 @@
*/
package org.horizon.eviction.algorithms.mru;
+import org.horizon.eviction.EntryEvictionData;
import org.horizon.eviction.EvictionQueue;
-import org.horizon.eviction.KeyEntry;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
-import java.util.NoSuchElementException;
/**
* MRU Eviction Queue implementation.
@@ -39,99 +39,63 @@
* @author Daniel Huang (dhuang(a)jboss.org)
* @since 1.0
*/
-public class MRUQueue<K> implements EvictionQueue<K> {
+public class MRUQueue implements EvictionQueue {
// we use our own Stack/Linked List implementation here because it guarantees O(n) = 1 for add, remove, get and
// we can sort it in order of MRU implicitly while still getting O(n) = 1 access time
// throughout.
- Map<K, EvictionListEntry<K>> keyMap;
- private EvictionQueueList<K> list;
- private int numElements = 0;
+ Map<Object, EntryEvictionData> keyMap;
+ private LinkedList<EntryEvictionData> list;
protected MRUQueue() {
- keyMap = new HashMap<K, EvictionListEntry<K>>();
- list = new EvictionQueueList<K>();
+ keyMap = new HashMap<Object, EntryEvictionData>();
+ list = new LinkedList<EntryEvictionData>();
}
/**
- * This call moves a NodeEntry to the top of the stack.
+ * This call moves an entry to the top of the stack.
* <p/>
- * When a node is visited this method should be called to guarantee MRU ordering.
+ * When an entry is visited this method should be called to guarantee MRU ordering.
*
- * @param key Fqn of the nodeEntry to move to the top of the stack.
+ * @param key entry key to move to the top of the stack.
*/
- protected void moveToTopOfStack(K key) {
- EvictionListEntry<K> le = keyMap.remove(key);
- if (le != null) {
- list.remove(le);
- list.addToTop(le);
- keyMap.put(le.keyEntry.getKey(), le);
+ protected void moveToTopOfStack(Object key) {
+ EntryEvictionData data = keyMap.get(key);
+ if (data != null) {
+ list.remove(data);
+ list.addFirst(data);
}
}
- /**
- * Will return the first entry in the nodeMap.
- * <p/>
- * The first entry in this nodeMap will also be the most recently used entry.
- *
- * @return The first node entry in nodeMap.
- */
- public KeyEntry<K> getFirstNodeEntry() {
- try {
- return list.getFirst().keyEntry;
- }
- catch (NoSuchElementException e) {
- //
- }
- return null;
+ public EntryEvictionData get(Object key) {
+ return keyMap.get(key);
}
- public KeyEntry<K> getNodeEntry(K key) {
- EvictionListEntry<K> le = keyMap.get(key);
- if (le != null)
- return le.keyEntry;
- return null;
+ public boolean contains(EntryEvictionData entryEvictionData) {
+ return keyMap.containsKey(entryEvictionData.getKey());
}
- public boolean containsNodeEntry(KeyEntry<K> entry) {
- return keyMap.containsKey(entry.getKey());
+ public void remove(EntryEvictionData entryEvictionData) {
+ EntryEvictionData data = keyMap.remove(entryEvictionData.getKey());
+ if (data != null) list.remove(data);
}
- public void removeNodeEntry(KeyEntry<K> entry) {
- EvictionListEntry<K> le = keyMap.remove(entry.getKey());
- if (le != null) {
- list.remove(le);
- this.numElements -= le.keyEntry.getNumberOfElements();
+ public void add(EntryEvictionData entryEvictionData) {
+ if (!keyMap.containsKey(entryEvictionData.getKey())) {
+ list.addLast(entryEvictionData);
+ keyMap.put(entryEvictionData.getKey(), entryEvictionData);
}
}
- public void addNodeEntry(KeyEntry<K> entry) {
- if (!this.containsNodeEntry(entry)) {
- EvictionListEntry<K> le = new EvictionListEntry<K>(entry);
- list.addToBottom(le);
- keyMap.put(entry.getKey(), le);
- this.numElements += entry.getNumberOfElements();
- }
- }
-
- public int getNumberOfNodes() {
+ public int size() {
return list.size();
}
- public int getNumberOfElements() {
- return this.numElements;
- }
-
- public void modifyElementCount(int difference) {
- this.numElements += difference;
- }
-
public void clear() {
keyMap.clear();
list.clear();
- this.numElements = 0;
}
- public Iterator<KeyEntry<K>> iterator() {
+ public Iterator<EntryEvictionData> iterator() {
return list.iterator();
}
Modified: core/branches/flat/src/main/java/org/horizon/factories/AbstractComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/AbstractComponentRegistry.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/AbstractComponentRegistry.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -94,7 +94,7 @@
// component and method containers
final Map<String, Component> componentLookup = new HashMap<String, Component>();
- ComponentStatus state = ComponentStatus.INSTANTIATED;
+ volatile ComponentStatus state = ComponentStatus.INSTANTIATED;
/**
* Retrieves the state of the registry
@@ -426,17 +426,17 @@
}
// now try the RuntimeConfig - a legacy "registry" of sorts.
- if (returnValue == null) {
- getter = BeanUtils.getterMethod(RuntimeConfig.class, componentClass);
- if (getter != null) {
- try {
- returnValue = (T) getter.invoke(getConfiguration().getRuntimeConfig());
- }
- catch (Exception e) {
- getLog().warn("Unable to invoke getter {0} on RuntimeConfig.class!", e, getter);
- }
- }
- }
+// if (returnValue == null) {
+// getter = BeanUtils.getterMethod(RuntimeConfig.class, componentClass);
+// if (getter != null) {
+// try {
+// returnValue = (T) getter.invoke(getConfiguration().getRuntimeConfig());
+// }
+// catch (Exception e) {
+// getLog().warn("Unable to invoke getter {0} on RuntimeConfig.class!", e, getter);
+// }
+// }
+// }
return returnValue;
}
@@ -772,7 +772,7 @@
* Configuration#getStateRetrievalTimeout()} millis, checking for a valid state.
*
* @param originLocal true if the call originates locally (i.e., from the {@link org.horizon.CacheDelegate} or false
- * if it originates remotely, i.e., from the {@link org.horizon.marshall.CommandAwareRpcDispatcher}.
+ * if it originates remotely, i.e., from the {@link org.horizon.remoting.InboundInvocationHandler}.
* @return true if invocations are allowed, false otherwise.
*/
public boolean invocationsAllowed(boolean originLocal) {
Modified: core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/BootstrapFactory.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -21,6 +21,7 @@
*/
package org.horizon.factories;
+import org.horizon.Cache;
import org.horizon.CacheException;
import org.horizon.CacheSPI;
import org.horizon.config.Configuration;
@@ -33,7 +34,7 @@
* @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
* @since 1.0
*/
-@DefaultFactoryFor(classes = {CacheSPI.class, Configuration.class, ComponentRegistry.class})
+@DefaultFactoryFor(classes = {Cache.class, CacheSPI.class, Configuration.class, ComponentRegistry.class})
@NonVolatile
public class BootstrapFactory extends AbstractNamedCacheComponentFactory {
CacheSPI cacheSPI;
Modified: core/branches/flat/src/main/java/org/horizon/factories/EvictionManagerFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/EvictionManagerFactory.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/EvictionManagerFactory.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -1,6 +1,6 @@
package org.horizon.factories;
-import org.horizon.EvictionManager;
+import org.horizon.eviction.EvictionManager;
import org.horizon.eviction.EvictionManagerImpl;
import org.horizon.factories.annotations.DefaultFactoryFor;
@@ -10,17 +10,11 @@
*/
@DefaultFactoryFor(classes = {EvictionManager.class})
public class EvictionManagerFactory extends AbstractNamedCacheComponentFactory implements AutoInstantiableFactory {
+
+ @SuppressWarnings("unchecked")
public <T> T construct(Class<T> componentType) {
- if (componentType != EvictionManager.class) {
- throw new IllegalStateException();
- }
- EvictionManagerImpl evManager = new EvictionManagerImpl();
if (configuration.getEvictionConfig() != null) {
- long wakeupInterval = configuration.getEvictionConfig().getWakeupInterval();
- // TODO: Fix me
- throw new RuntimeException("Fix me");
-// evManager.configureEvictionThread(wakeupInterval, configuration.getRuntimeConfig().getEvictionTimerThreadFactory());
-// return (T) evManager;
+ return (T) new EvictionManagerImpl();
} else return null;
}
}
Modified: core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -22,14 +22,9 @@
package org.horizon.factories;
-import org.horizon.CacheSPI;
-import org.horizon.EvictionManager;
import org.horizon.config.Configuration;
import org.horizon.config.ConfigurationException;
import org.horizon.config.CustomInterceptorConfig;
-import org.horizon.config.EvictionCacheConfig;
-import org.horizon.eviction.EvictionCacheManager;
-import org.horizon.eviction.EvictionCacheManagerImpl;
import org.horizon.factories.annotations.DefaultFactoryFor;
import org.horizon.interceptors.*;
import org.horizon.interceptors.base.CommandInterceptor;
@@ -131,23 +126,10 @@
}
}
-//
-// if (configuration.isUsingBuddyReplication())
-// {
-//
-// interceptorChain.appendIntereceptor(createInterceptor(DataGravitatorInterceptor.class));
-//
-// }
if (configuration.isUsingEviction()) {
EvictionInterceptor evictionInterceptor = (EvictionInterceptor) createInterceptor(EvictionInterceptor.class);
interceptorChain.appendIntereceptor(evictionInterceptor);
- EvictionCacheConfig ecc = configuration.getEvictionCacheConfig("bla");
- EvictionCacheManager evCacheManager = new EvictionCacheManagerImpl(componentRegistry.getComponent(CacheSPI.class));
- evCacheManager.configure(ecc);
- evictionInterceptor.setEvictionCacheManager(evCacheManager);
- EvictionManager evManager = componentRegistry.getComponent(EvictionManager.class);
- evManager.cacheCreated("bla", evCacheManager);
}
CommandInterceptor callInterceptor = createInterceptor(CallInterceptor.class);
Modified: core/branches/flat/src/main/java/org/horizon/factories/KnownComponentNames.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/KnownComponentNames.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/KnownComponentNames.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -10,4 +10,5 @@
public class KnownComponentNames {
public static final String ASYNC_SERIALIZATION_EXECUTOR = "org.horizon.executors.serialization";
public static final String ASYNC_NOTIFICATION_EXECUTOR = "org.horizon.executors.notification";
+ public static final String EVICTION_SCHEDULED_EXECUTOR = "org.horizon.executors.eviction";
}
Modified: core/branches/flat/src/main/java/org/horizon/factories/NamedExecutorsFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/NamedExecutorsFactory.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/NamedExecutorsFactory.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -2,6 +2,7 @@
import org.horizon.config.ConfigurationException;
import org.horizon.executors.ExecutorFactory;
+import org.horizon.executors.ScheduledExecutorFactory;
import org.horizon.factories.annotations.DefaultFactoryFor;
import org.horizon.util.Util;
@@ -21,15 +22,16 @@
@SuppressWarnings("unchecked")
public <T> T construct(Class<T> componentType, String componentName) {
- ExecutorFactory ef;
- Properties props;
try {
if (componentName.equals(KnownComponentNames.ASYNC_NOTIFICATION_EXECUTOR)) {
- ef = (ExecutorFactory) Util.getInstance(globalConfiguration.getAsyncListenerExecutorFactoryClass());
- props = globalConfiguration.getAsyncListenerExecutorProperties();
+ return (T) buildAndConfigureExecutorService(globalConfiguration.getAsyncListenerExecutorFactoryClass(),
+ globalConfiguration.getAsyncListenerExecutorProperties());
} else if (componentName.equals(KnownComponentNames.ASYNC_SERIALIZATION_EXECUTOR)) {
- ef = (ExecutorFactory) Util.getInstance(globalConfiguration.getAsyncSerializationExecutorFactoryClass());
- props = globalConfiguration.getAsyncSerializationExecutorProperties();
+ return (T) buildAndConfigureExecutorService(globalConfiguration.getAsyncSerializationExecutorFactoryClass(),
+ globalConfiguration.getAsyncSerializationExecutorProperties());
+ } else if (componentName.equals(KnownComponentNames.EVICTION_SCHEDULED_EXECUTOR)) {
+ return (T) buildAndConfigureScheduledExecutorService(globalConfiguration.getEvictionScheduledExecutorFactoryClass(),
+ globalConfiguration.getEvictionScheduledExecutorProperties());
} else {
throw new ConfigurationException("Unknown named executor " + componentName);
}
@@ -38,6 +40,15 @@
} catch (Exception e) {
throw new ConfigurationException("Unable to instantiate ExecutorFactory for named component " + componentName, e);
}
- return (T) ef.getExecutor(props);
}
+
+ private ExecutorService buildAndConfigureExecutorService(String factoryName, Properties props) throws Exception {
+ ExecutorFactory f = (ExecutorFactory) Util.getInstance(factoryName);
+ return f.getExecutor(props);
+ }
+
+ private ScheduledExecutorService buildAndConfigureScheduledExecutorService(String factoryName, Properties props) throws Exception {
+ ScheduledExecutorFactory f = (ScheduledExecutorFactory) Util.getInstance(factoryName);
+ return f.getScheduledExecutor(props);
+ }
}
Modified: core/branches/flat/src/main/java/org/horizon/factories/TransactionManagerFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/TransactionManagerFactory.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/factories/TransactionManagerFactory.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -38,7 +38,7 @@
public class TransactionManagerFactory extends AbstractNamedCacheComponentFactory implements AutoInstantiableFactory {
public <T> T construct(Class<T> componentType) {
// See if we had a TransactionManager injected into our config
- TransactionManager transactionManager = configuration.getRuntimeConfig().getTransactionManager();
+ TransactionManager transactionManager = null; //configuration.getRuntimeConfig().getTransactionManager();
TransactionManagerLookup lookup = null;
if (transactionManager == null) {
@@ -58,7 +58,7 @@
try {
if (lookup != null) {
transactionManager = lookup.getTransactionManager();
- configuration.getRuntimeConfig().setTransactionManager(transactionManager);
+// configuration.getRuntimeConfig().setTransactionManager(transactionManager);
}
}
catch (Exception e) {
Modified: core/branches/flat/src/main/java/org/horizon/interceptors/EvictionInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/EvictionInterceptor.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/EvictionInterceptor.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -28,9 +28,10 @@
import org.horizon.commands.write.RemoveCommand;
import org.horizon.commands.write.ReplaceCommand;
import org.horizon.context.InvocationContext;
-import org.horizon.eviction.EvictionCacheManager;
import org.horizon.eviction.EvictionEvent;
import static org.horizon.eviction.EvictionEvent.Type.*;
+import org.horizon.eviction.EvictionManager;
+import org.horizon.factories.annotations.Inject;
import org.horizon.interceptors.base.CommandInterceptor;
/**
@@ -42,23 +43,19 @@
* @since 1.0
*/
public class EvictionInterceptor extends CommandInterceptor {
- protected EvictionCacheManager evictionCacheManager;
+ protected EvictionManager evictionManager;
+ private static final Object CLEAR_CACHE_KEY_CONSTANT = new Object();
- /**
- * this method is for ease of unit testing. thus package access.
- * <p/>
- * Not to be attempted to be used anywhere else.
- */
- public void setEvictionCacheManager(EvictionCacheManager evictionCacheManager) {
- this.evictionCacheManager = evictionCacheManager;
+ @Inject
+ public void setEvictionCacheManager(EvictionManager evictionManager) {
+ this.evictionManager = evictionManager;
}
-
@Override
public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
Object retVal = invokeNextInterceptor(ctx, command);
- if (command.getKey() != null) {
- registerEvictionEvent(command.getKey(), ADD_ELEMENT_EVENT, 1);
+ if (command.isSuccessful() && command.getKey() != null) {
+ registerEvictionEvent(command.getKey(), ADD_ENTRY_EVENT);
}
return retVal;
}
@@ -69,11 +66,9 @@
if (command.getMap() == null) {
if (trace) log.trace("Putting null data.");
} else {
- int size;
- synchronized (command.getMap()) {
- size = command.getMap().size();
+ for (Object key : command.getMap().keySet()) {
+ registerEvictionEvent(key, ADD_ENTRY_EVENT);
}
- registerEvictionEvent(null, ADD_NODE_EVENT, size);
}
return retVal;
}
@@ -81,12 +76,8 @@
@Override
public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
Object retVal = invokeNextInterceptor(ctx, command);
- if (retVal == null) {
- if (trace) log.trace("No event added. Element does not exist");
- } else {
- if (command.getKey() != null) {
- registerEvictionEvent(command.getKey(), REMOVE_ELEMENT_EVENT, 1);
- }
+ if (command.isSuccessful() && command.getKey() != null) {
+ registerEvictionEvent(command.getKey(), REMOVE_ENTRY_EVENT);
}
return retVal;
}
@@ -96,29 +87,32 @@
Object retVal = invokeNextInterceptor(ctx, command);
if (retVal == null) {
if (trace) log.trace("No event added. Element does not exist");
- } else if (command.getKey() != null) {
- registerEvictionEvent(command.getKey(), VISIT_NODE_EVENT, 0);
+ } else {
+ registerEvictionEvent(command.getKey(), VISIT_ENTRY_EVENT);
}
return retVal;
}
public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
- Boolean replaced = (Boolean) invokeNextInterceptor(ctx, command);
- if (replaced) registerEvictionEvent(command.getKey(), ADD_NODE_EVENT, 1);
- else registerEvictionEvent(command.getKey(), VISIT_NODE_EVENT, 0);
- return replaced;
+ Object retval = invokeNextInterceptor(ctx, command);
+ registerEvictionEvent(command.getKey(), command.isSuccessful() ? ADD_ENTRY_EVENT : VISIT_ENTRY_EVENT);
+ return retval;
}
@Override
public Object visitClearCommand(InvocationContext ctx, ClearCommand command) throws Throwable {
Object retVal = invokeNextInterceptor(ctx, command);
- registerEvictionEvent(null, REMOVE_NODE_EVENT, 0);
+ registerEvictionEvent(CLEAR_CACHE_KEY_CONSTANT, CLEAR_CACHE_EVENT);
return retVal;
}
@SuppressWarnings(value = "unchecked")
- private void registerEvictionEvent(Object key, EvictionEvent.Type type, int elementDifference) {
- evictionCacheManager.registerEvictionEvent(key, type, elementDifference);
- if (trace) log.trace("Registering event " + type + " on node " + key);
+ private void registerEvictionEvent(Object key, EvictionEvent.Type type) {
+ if (key == null) {
+ log.debug("Cannot record a null key on eviction queue for access type {0}", type);
+ } else {
+ evictionManager.registerEvictionEvent(key, type);
+ if (trace) log.trace("Registering event {0} for entry {1}", type, key);
+ }
}
}
Modified: core/branches/flat/src/main/resources/config-samples/all.xml
===================================================================
--- core/branches/flat/src/main/resources/config-samples/all.xml 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/main/resources/config-samples/all.xml 2009-02-03 02:11:20 UTC (rev 7625)
@@ -115,7 +115,8 @@
Eviction configuration. WakeupInterval defines how often the eviction thread runs, in milliseconds. 0 means
the eviction thread will never run. A separate executor is used for eviction in each cache.
-->
- <eviction wakeUpInterval="500" algorithmClass="org.horizon.eviction.LRUAlgorithm" eventQueueSize="200000">
+ <eviction wakeUpInterval="500" algorithmClass="org.horizon.eviction.LRUAlgorithm" eventQueueSize="200000"
+ actionPolicyClass="org.horizon.eviction.DefaultEvictionAction">
<property name="maxEntries" value="5000"/>
<property name="timeToLive" value="1000"/>
</eviction>
Modified: core/branches/flat/src/test/java/org/horizon/api/batch/BatchWithTMTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/batch/BatchWithTMTest.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/test/java/org/horizon/api/batch/BatchWithTMTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -16,7 +16,7 @@
Cache<String, String> cache = null;
try {
cache = createCache();
- TransactionManager tm = getTransactionManager(cache);
+ TransactionManager tm = TestingUtil.getTransactionManager(cache);
tm.begin();
cache.put("k", "v");
cache.startBatch();
@@ -39,7 +39,7 @@
Cache<String, String> cache = null;
try {
cache = createCache();
- TransactionManager tm = getTransactionManager(cache);
+ TransactionManager tm = TestingUtil.getTransactionManager(cache);
assert tm.getTransaction() == null : "Should have no ongoing txs";
cache.startBatch();
cache.put("k", "v");
@@ -75,7 +75,6 @@
Cache<String, String> cache = null;
try {
cache = createCache();
- TransactionManager tm = getTransactionManager(cache);
cache.startBatch();
cache.put("k", "v");
cache.put("k2", "v2");
@@ -93,10 +92,6 @@
}
}
- private TransactionManager getTransactionManager(Cache<String, String> c) {
- return c.getConfiguration().getRuntimeConfig().getTransactionManager();
- }
-
private Cache<String, String> createCache() {
UnitTestCacheFactory<String, String> cf = new UnitTestCacheFactory<String, String>();
Configuration c = new Configuration();
Modified: core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -299,27 +299,29 @@
*/
private void cacheModeLocalTest(boolean transactional) throws Exception {
RPCManager rpcManager = EasyMock.createMock(RPCManager.class);
- RPCManager originalRpcManager = cache1.getConfiguration().getRuntimeConfig().getRPCManager();
+ RPCManager originalRpcManager = TestingUtil.replaceComponent(cache1.getCacheManager(), RPCManager.class, rpcManager, true);
+ try {
- // inject a mock RPC manager so that we can test whether calls made are sync or async.
- cache1.getConfiguration().getRuntimeConfig().setRPCManager(rpcManager);
+ // specify that we expectWithTx nothing will be called on the mock Rpc Manager.
+ replay(rpcManager);
- // specify that we expectWithTx nothing will be called on the mock Rpc Manager.
- replay(rpcManager);
+ // now try a simple replication. Since the RPCManager is a mock object it will not actually replicate anything.
+ if (transactional)
+ tm1.begin();
- // now try a simple replication. Since the RPCManager is a mock object it will not actually replicate anything.
- if (transactional)
- tm1.begin();
+ cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ cache1.putForExternalRead(key, value);
- cache1.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
- cache1.putForExternalRead(key, value);
+ if (transactional)
+ tm1.commit();
- if (transactional)
- tm1.commit();
-
- verify(rpcManager);
- // cleanup
- cache1.getConfiguration().getRuntimeConfig().setRPCManager(originalRpcManager);
- cache1.remove(key);
+ verify(rpcManager);
+ } finally {
+ if (originalRpcManager != null) {
+ // cleanup
+ TestingUtil.replaceComponent(cache1.getCacheManager(), RPCManager.class, originalRpcManager, true);
+ cache1.remove(key);
+ }
+ }
}
}
Modified: core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -2,6 +2,10 @@
import org.horizon.config.CacheLoaderConfig;
import org.horizon.config.Configuration;
+import org.horizon.config.ConfigurationException;
+import org.horizon.config.EvictionConfig;
+import org.horizon.eviction.DefaultEvictionAction;
+import org.horizon.eviction.algorithms.fifo.FIFOAlgorithmConfig;
import org.horizon.lock.IsolationLevel;
import org.horizon.transaction.GenericTransactionManagerLookup;
import org.testng.annotations.Test;
@@ -211,7 +215,56 @@
assert ssc.getSingletonStoreProperties().isEmpty();
}
+ public void testInsufficientEviction() throws Exception {
+ XmlConfigurationParserImpl parser = new XmlConfigurationParserImpl();
+ String xml = "<eviction wakeupInterval=\"1000\" />";
+ Element e = XmlConfigHelper.stringToElement(xml);
+
+ Configuration c = new Configuration();
+ try {
+ parser.configureEviction(e, c);
+ assert false : "Should fail";
+ } catch (ConfigurationException expected) {
+ assert true : "expected";
+ }
+ }
+
+ public void testDefaultEviction() throws Exception {
+ XmlConfigurationParserImpl parser = new XmlConfigurationParserImpl();
+ String xml = "<eviction algorithmClass=\"org.horizon.eviction.algorithms.fifo.FIFOAlgorithm\" />";
+ Element e = XmlConfigHelper.stringToElement(xml);
+
+ Configuration c = new Configuration();
+
+ parser.configureEviction(e, c);
+ EvictionConfig ec = c.getEvictionConfig();
+ assert ec != null;
+ assert ec.getActionPolicyClass().equals(DefaultEvictionAction.class.getName());
+ assert ec.getAlgorithmConfig() instanceof FIFOAlgorithmConfig;
+ assert ec.getEventQueueSize() == 200000;
+ assert ec.getWakeUpInterval() == 5000;
+ }
+
public void testEviction() throws Exception {
- // TODO: implement me
+ XmlConfigurationParserImpl parser = new XmlConfigurationParserImpl();
+ String xml = "<eviction algorithmClass=\"org.horizon.eviction.algorithms.fifo.FIFOAlgorithm\" " +
+ "actionPolicyClass=\"org.blah.Blah\" wakeUpInterval=\"750\" eventQueueSize=\"5000\">" +
+ "<property name=\"maxEntries\" value=\"7000\" />" +
+ "<property name=\"minTimeToLive\" value=\"20\" />" +
+ "</eviction>";
+ Element e = XmlConfigHelper.stringToElement(xml);
+
+ Configuration c = new Configuration();
+
+ parser.configureEviction(e, c);
+ EvictionConfig ec = c.getEvictionConfig();
+ assert ec != null;
+ assert ec.getActionPolicyClass().equals("org.blah.Blah");
+ assert ec.getAlgorithmConfig() instanceof FIFOAlgorithmConfig;
+ assert ec.getEventQueueSize() == 5000;
+ assert ec.getWakeUpInterval() == 750;
+ FIFOAlgorithmConfig ac = (FIFOAlgorithmConfig) ec.getAlgorithmConfig();
+ assert ac.getMaxEntries() == 7000;
+ assert ac.getMinTimeToLive() == 20;
}
}
Added: core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/EvictionFunctionalTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,72 @@
+package org.horizon.eviction;
+
+import org.horizon.Cache;
+import org.horizon.config.Configuration;
+import org.horizon.config.EvictionConfig;
+import org.horizon.eviction.algorithms.fifo.FIFOAlgorithmConfig;
+import org.horizon.manager.CacheManager;
+import org.horizon.manager.DefaultCacheManager;
+import org.horizon.notifications.Listener;
+import org.horizon.notifications.cachelistener.event.CacheEntryEvictedEvent;
+import org.horizon.util.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@Test(groups = "functional", sequential = true)
+public class EvictionFunctionalTest {
+ Cache cache;
+ EvictionListener el;
+
+ @BeforeMethod
+ public void setUp() {
+ try {
+ Configuration cfg = new Configuration();
+ EvictionConfig ec = new EvictionConfig();
+ cfg.setEvictionConfig(ec);
+ FIFOAlgorithmConfig fifo = new FIFOAlgorithmConfig();
+ fifo.setMaxEntries(10);
+ ec.setAlgorithmConfig(fifo);
+ ec.setWakeUpInterval(50); // 50 millis!
+ CacheManager cm = new DefaultCacheManager(cfg);
+ cache = cm.getCache();
+ el = new EvictionListener();
+ cache.addListener(el);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ TestingUtil.killCaches(cache);
+ }
+
+ public void testEviction() throws InterruptedException {
+ el.latch = new CountDownLatch(1);
+ for (int i = 0; i < 11; i++) {
+ cache.put(i, "value");
+ }
+
+ assert el.latch.await(60, TimeUnit.SECONDS);
+ for (int i = 1; i < 11; i++) {
+ assert cache.containsKey(i);
+ }
+
+ assert !cache.containsKey(0);
+ }
+
+ @Listener
+ public static class EvictionListener {
+ CountDownLatch latch;
+
+ public void handle(CacheEntryEvictedEvent event) {
+ if (event.isPre()) {
+ latch.countDown();
+ }
+ }
+ }
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/EvictionManagerTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/EvictionManagerTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/EvictionManagerTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class EvictionManagerTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoAlgorithmTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoAlgorithmTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoAlgorithmTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,13 @@
+package org.horizon.eviction.algorithms.fifo;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class FifoAlgorithmTest {
+ public void testAlgorithm() {
+ FIFOAlgorithm algo = new FIFOAlgorithm();
+ algo.initialize();
+ assert algo.getConfigurationClass().equals(FIFOAlgorithmConfig.class);
+// assert algo.process();
+ }
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoQueueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoQueueTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/fifo/FifoQueueTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.fifo;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class FifoQueueTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuAlgorithmTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuAlgorithmTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuAlgorithmTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.lfu;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class LfuAlgorithmTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuQueueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuQueueTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lfu/LfuQueueTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.lfu;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class LfuQueueTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruAlgorithmTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruAlgorithmTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruAlgorithmTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.lru;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class LruAlgorithmTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruQueueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruQueueTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/lru/LruQueueTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.lru;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class LruQueueTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruAlgorithmTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruAlgorithmTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruAlgorithmTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.mru;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class MruAlgorithmTest {
+}
Added: core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruQueueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruQueueTest.java (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/eviction/algorithms/mru/MruQueueTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -0,0 +1,7 @@
+package org.horizon.eviction.algorithms.mru;
+
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class MruQueueTest {
+}
Modified: core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -117,7 +117,7 @@
TestingUtil.blockUntilViewsReceived(10000, cache1, cache2);
// get a lock on cache 2 and hold on to it.
- TransactionManager tm = cache2.getConfiguration().getRuntimeConfig().getTransactionManager();
+ TransactionManager tm = TestingUtil.getTransactionManager(cache2);
tm.begin();
cache2.put("block", "block");
tm.suspend();
Modified: core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java 2009-02-02 14:31:03 UTC (rev 7624)
+++ core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java 2009-02-03 02:11:20 UTC (rev 7625)
@@ -102,7 +102,7 @@
public void simpleReplicationTest() throws Exception {
- TransactionManager tm = cache1.getConfiguration().getRuntimeConfig().getTransactionManager();
+ TransactionManager tm = TestingUtil.getTransactionManager(cache1);
tm.begin();
cache1.put("key", "value");
tm.commit();
@@ -113,7 +113,7 @@
public void testSyncTxReplMap() throws Exception {
Integer age;
- TransactionManager tm = cache1.getConfiguration().getRuntimeConfig().getTransactionManager();
+ TransactionManager tm = TestingUtil.getTransactionManager(cache1);
tm.begin();
Transaction tx = tm.getTransaction();
LocalListener lis = new LocalListener();
15 years, 11 months
JBoss Cache SVN: r7624 - in core/branches/flat/src: main/java/org/horizon/notifications and 4 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2009-02-02 09:31:03 -0500 (Mon, 02 Feb 2009)
New Revision: 7624
Added:
core/branches/flat/src/main/java/org/horizon/notifications/AbstractListenerImpl.java
Modified:
core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java
core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifier.java
core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java
core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifier.java
core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifierImpl.java
core/branches/flat/src/test/java/org/horizon/notifications/ConcurrentNotificationTest.java
core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java
Log:
Finished notification work
Modified: core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/main/java/org/horizon/factories/ComponentRegistry.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -108,15 +108,19 @@
if (globalComponents.getState() != ComponentStatus.STARTED || globalComponents.getState() != ComponentStatus.STARTING) {
globalComponents.start();
}
+ boolean needToNotify = state != ComponentStatus.STARTED && state != ComponentStatus.STARTING;
super.start();
- globalComponents.registerNamedComponentRegistry(this, cacheName);
- cacheManagerNotifier.notifyCacheStarted(cacheName);
+ if (needToNotify && state == ComponentStatus.STARTED) {
+ globalComponents.registerNamedComponentRegistry(this, cacheName);
+ cacheManagerNotifier.notifyCacheStarted(cacheName);
+ }
}
@Override
public void stop() {
if (state.stopAllowed()) globalComponents.unregisterNamedComponentRegistry(cacheName);
+ boolean needToNotify = state == ComponentStatus.STARTED || state == ComponentStatus.STARTING;
super.stop();
- cacheManagerNotifier.notifyCacheStopped(cacheName);
+ if (state == ComponentStatus.STOPPED && needToNotify) cacheManagerNotifier.notifyCacheStopped(cacheName);
}
}
Added: core/branches/flat/src/main/java/org/horizon/notifications/AbstractListenerImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/AbstractListenerImpl.java (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/notifications/AbstractListenerImpl.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -0,0 +1,201 @@
+package org.horizon.notifications;
+
+import org.horizon.CacheException;
+import org.horizon.factories.KnownComponentNames;
+import org.horizon.factories.annotations.ComponentName;
+import org.horizon.factories.annotations.Destroy;
+import org.horizon.factories.annotations.Inject;
+import org.horizon.factories.annotations.Start;
+import org.horizon.factories.annotations.Stop;
+import org.horizon.logging.Log;
+import org.horizon.util.ReflectionUtil;
+import org.horizon.util.concurrent.WithinThreadExecutor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Functionality common to both {@link org.horizon.notifications.cachemanagerlistener.CacheManagerNotifierImpl} and
+ * {@link org.horizon.notifications.cachelistener.CacheNotifierImpl}
+ *
+ * @author Manik Surtani
+ */
+public abstract class AbstractListenerImpl {
+
+ protected final Map<Class<? extends Annotation>, List<ListenerInvocation>> listenersMap = new HashMap<Class<? extends Annotation>, List<ListenerInvocation>>(16, 0.99f);
+
+
+ // two separate executor services, one for sync and one for async listeners
+ protected ExecutorService syncProcessor;
+ protected ExecutorService asyncProcessor;
+
+
+ @Inject
+ void injectExecutor((a)ComponentName(KnownComponentNames.ASYNC_NOTIFICATION_EXECUTOR) ExecutorService executor) {
+ this.asyncProcessor = executor;
+ }
+
+ @Destroy
+ void destroy() {
+ removeAllCacheListeners();
+ }
+
+ @Start
+ public void start() {
+ syncProcessor = new WithinThreadExecutor();
+ }
+
+ /**
+ * Removes all listeners from the notifier
+ */
+ @Stop(priority = 99)
+ public void removeAllCacheListeners() {
+ for (List<ListenerInvocation> list : listenersMap.values()) {
+ if (list != null) list.clear();
+ }
+ }
+
+ protected abstract Log getLog();
+
+ protected abstract Map<Class<? extends Annotation>, Class> getAllowedMethodAnnotations();
+
+ protected List<ListenerInvocation> getListenerCollectionForAnnotation(Class<? extends Annotation> annotation) {
+ List<ListenerInvocation> list = listenersMap.get(annotation);
+ if (list == null) throw new CacheException("Unknown listener annotation: " + annotation);
+ return list;
+ }
+
+ public void removeListener(Object listener) {
+ for (Class<? extends Annotation> annotation : getAllowedMethodAnnotations().keySet())
+ removeListenerInvocation(annotation, listener);
+ }
+
+ private void removeListenerInvocation(Class<? extends Annotation> annotation, Object listener) {
+ if (listener == null) return;
+ List<ListenerInvocation> l = getListenerCollectionForAnnotation(annotation);
+ Set<Object> markedForRemoval = new HashSet<Object>();
+ for (ListenerInvocation li : l) {
+ if (listener.equals(li.target)) markedForRemoval.add(li);
+ }
+ l.removeAll(markedForRemoval);
+ }
+
+ public void addListener(Object listener) {
+ validateAndAddListenerInvocation(listener);
+ }
+
+ public Set<Object> getListeners() {
+ Set<Object> result = new HashSet<Object>();
+ for (List<ListenerInvocation> list : listenersMap.values()) {
+ for (ListenerInvocation li : list) result.add(li.target);
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ /**
+ * Loops through all valid methods on the object passed in, and caches the relevant methods as {@link
+ * ListenerInvocation} for invocation by reflection.
+ *
+ * @param listener object to be considered as a listener.
+ */
+ @SuppressWarnings("unchecked")
+ private void validateAndAddListenerInvocation(Object listener) {
+ boolean sync = testListenerClassValidity(listener.getClass());
+ boolean foundMethods = false;
+ Map<Class<? extends Annotation>, Class> allowedListeners = getAllowedMethodAnnotations();
+ // now try all methods on the listener for anything that we like. Note that only PUBLIC methods are scanned.
+ for (Method m : listener.getClass().getMethods()) {
+ // loop through all valid method annotations
+ for (Class<? extends Annotation> annotation : allowedListeners.keySet()) {
+ if (m.isAnnotationPresent(annotation)) {
+ testListenerMethodValidity(m, allowedListeners.get(annotation), annotation.getName());
+ addListenerInvocation(annotation, new ListenerInvocation(listener, m, sync));
+ foundMethods = true;
+ }
+ }
+ }
+
+ if (!foundMethods && getLog().isWarnEnabled())
+ getLog().warn("Attempted to register listener of class " + listener.getClass() + ", but no valid, public methods annotated with method-level event annotations found! Ignoring listener.");
+ }
+
+ private void addListenerInvocation(Class annotation, ListenerInvocation li) {
+ List<ListenerInvocation> result = getListenerCollectionForAnnotation(annotation);
+ result.add(li);
+ }
+
+ /**
+ * Tests if a class is properly annotated as a CacheListener and returns whether callbacks on this class should be
+ * invoked synchronously or asynchronously.
+ *
+ * @param listenerClass class to inspect
+ * @return true if callbacks on this class should use the syncProcessor; false if it should use the asyncProcessor.
+ */
+ protected boolean testListenerClassValidity(Class<?> listenerClass) {
+ Listener l = ReflectionUtil.getAnnotation(listenerClass, Listener.class);
+ if (l == null)
+ throw new IncorrectListenerException("Cache listener class MUST be annotated with org.horizon.notifications.annotation.Listener");
+ if (!Modifier.isPublic(listenerClass.getModifiers()))
+ throw new IncorrectListenerException("Cache listener class MUST be public!");
+ return l.sync();
+ }
+
+ protected void testListenerMethodValidity(Method m, Class allowedParameter, String annotationName) {
+ if (m.getParameterTypes().length != 1 || !m.getParameterTypes()[0].isAssignableFrom(allowedParameter))
+ throw new IncorrectListenerException("Methods annotated with " + annotationName + " must accept exactly one parameter, of assignable from type " + allowedParameter.getName());
+ if (!m.getReturnType().equals(void.class))
+ throw new IncorrectListenerException("Methods annotated with " + annotationName + " should have a return type of void.");
+ }
+
+ /**
+ * Class that encapsulates a valid invocation for a given registered listener - containing a reference to the method
+ * to be invoked as well as the target object.
+ */
+ protected class ListenerInvocation {
+ public final Object target;
+ public final Method method;
+ public final boolean sync;
+
+ public ListenerInvocation(Object target, Method method, boolean sync) {
+ this.target = target;
+ this.method = method;
+ this.sync = sync;
+ }
+
+ public void invoke(final Object event) {
+ Runnable r = new Runnable() {
+
+ public void run() {
+ try {
+ method.invoke(target, event);
+ }
+ catch (InvocationTargetException exception) {
+ Throwable cause = exception.getCause();
+ if (cause != null)
+ throw new CacheException("Caught exception invoking method " + method + " on listener instance " + target, cause);
+ else
+ throw new CacheException("Caught exception invoking method " + method + " on listener instance " + target, exception);
+ }
+ catch (IllegalAccessException exception) {
+ getLog().warn("Unable to invoke method " + method + " on Object instance " + target + " - removing this target object from list of listeners!", exception);
+ removeListener(target);
+ }
+ }
+ };
+
+ if (sync)
+ syncProcessor.execute(r);
+ else
+ asyncProcessor.execute(r);
+ }
+ }
+}
Modified: core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifier.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifier.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifier.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -22,6 +22,9 @@
package org.horizon.notifications.cachelistener;
import org.horizon.context.InvocationContext;
+import org.horizon.factories.annotations.NonVolatile;
+import org.horizon.factories.scopes.Scope;
+import org.horizon.factories.scopes.Scopes;
import org.horizon.notifications.Listenable;
import javax.transaction.Transaction;
@@ -32,6 +35,8 @@
* @author Mircea.Markus(a)jboss.com
* @since 1.0
*/
+@NonVolatile
+(a)Scope(Scopes.NAMED_CACHE)
public interface CacheNotifier extends Listenable {
/**
* Notifies all registered listeners of a CacheEntryCreated event.
Modified: core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/main/java/org/horizon/notifications/cachelistener/CacheNotifierImpl.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -22,41 +22,22 @@
package org.horizon.notifications.cachelistener;
import org.horizon.Cache;
-import org.horizon.CacheException;
import org.horizon.CacheSPI;
import org.horizon.context.InvocationContext;
-import org.horizon.factories.KnownComponentNames;
-import org.horizon.factories.annotations.ComponentName;
-import org.horizon.factories.annotations.Destroy;
import org.horizon.factories.annotations.Inject;
-import org.horizon.factories.annotations.NonVolatile;
-import org.horizon.factories.annotations.Start;
-import org.horizon.factories.annotations.Stop;
-import org.horizon.factories.scopes.Scope;
-import org.horizon.factories.scopes.Scopes;
import org.horizon.logging.Log;
import org.horizon.logging.LogFactory;
-import org.horizon.notifications.IncorrectListenerException;
-import org.horizon.notifications.Listener;
+import org.horizon.notifications.AbstractListenerImpl;
import org.horizon.notifications.cachelistener.annotation.*;
import org.horizon.notifications.cachelistener.event.*;
import static org.horizon.notifications.cachelistener.event.Event.Type.*;
-import org.horizon.util.ReflectionUtil;
-import org.horizon.util.concurrent.WithinThreadExecutor;
import javax.transaction.Transaction;
import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutorService;
/**
* Helper class that handles all notifications to registered listeners.
@@ -64,25 +45,26 @@
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik(a)jboss.org)</a>
* @since 1.0
*/
-@NonVolatile
-(a)Scope(Scopes.NAMED_CACHE)
-public class CacheNotifierImpl implements CacheNotifier {
+public class CacheNotifierImpl extends AbstractListenerImpl implements CacheNotifier {
private static final Log log = LogFactory.getLog(CacheNotifierImpl.class);
- private static final Class[] allowedMethodAnnotations =
- {
- CacheEntryCreated.class, CacheEntryRemoved.class, CacheEntryVisited.class, CacheEntryModified.class,
- CacheEntryActivated.class, CacheEntryPassivated.class, CacheEntryLoaded.class, CacheEntryEvicted.class, TransactionRegistered.class, TransactionCompleted.class,
- CacheEntryInvalidated.class
- };
- private static final Class[] parameterTypes =
- {
- CacheEntryCreatedEvent.class, CacheEntryRemovedEvent.class, CacheEntryVisitedEvent.class, CacheEntryModifiedEvent.class,
- CacheEntryActivatedEvent.class, CacheEntryPassivatedEvent.class, CacheEntryLoadedEvent.class, CacheEntryEvictedEvent.class, TransactionRegisteredEvent.class, TransactionCompletedEvent.class,
- CacheEntryInvalidatedEvent.class
- };
+ private static final Map<Class<? extends Annotation>, Class> allowedListeners = new HashMap<Class<? extends Annotation>, Class>();
- final Map<Class<? extends Annotation>, List<ListenerInvocation>> listenersMap = new HashMap<Class<? extends Annotation>, List<ListenerInvocation>>(16, 0.99f);
+ static {
+ allowedListeners.put(CacheEntryCreated.class, CacheEntryCreatedEvent.class);
+ allowedListeners.put(CacheEntryRemoved.class, CacheEntryRemovedEvent.class);
+ allowedListeners.put(CacheEntryVisited.class, CacheEntryVisitedEvent.class);
+ allowedListeners.put(CacheEntryModified.class, CacheEntryModifiedEvent.class);
+ allowedListeners.put(CacheEntryActivated.class, CacheEntryActivatedEvent.class);
+ allowedListeners.put(CacheEntryPassivated.class, CacheEntryPassivatedEvent.class);
+ allowedListeners.put(CacheEntryLoaded.class, CacheEntryLoadedEvent.class);
+ allowedListeners.put(CacheEntryEvicted.class, CacheEntryEvictedEvent.class);
+ allowedListeners.put(TransactionRegistered.class, TransactionRegisteredEvent.class);
+ allowedListeners.put(TransactionCompleted.class, TransactionCompletedEvent.class);
+ allowedListeners.put(CacheEntryInvalidated.class, CacheEntryInvalidatedEvent.class);
+
+ }
+
final List<ListenerInvocation> cacheEntryCreatedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
final List<ListenerInvocation> cacheEntryRemovedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
final List<ListenerInvocation> cacheEntryVisitedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
@@ -96,11 +78,9 @@
final List<ListenerInvocation> transactionCompletedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
private Cache cache;
- // two separate executor services, one for sync and one for async listeners
- private ExecutorService syncProcessor;
- private ExecutorService asyncProcessor;
public CacheNotifierImpl() {
+
listenersMap.put(CacheEntryCreated.class, cacheEntryCreatedListeners);
listenersMap.put(CacheEntryRemoved.class, cacheEntryRemovedListeners);
listenersMap.put(CacheEntryVisited.class, cacheEntryVisitedListeners);
@@ -115,126 +95,18 @@
}
@Inject
- void injectDependencies(CacheSPI cache,
- @ComponentName(KnownComponentNames.ASYNC_NOTIFICATION_EXECUTOR) ExecutorService executor) {
+ void injectDependencies(CacheSPI cache) {
this.cache = cache;
- this.asyncProcessor = executor;
}
- @Stop
- void stop() {
- syncProcessor.shutdownNow();
- asyncProcessor.shutdownNow();
+ protected Log getLog() {
+ return log;
}
- @Destroy
- void destroy() {
- removeAllCacheListeners();
+ protected Map<Class<? extends Annotation>, Class> getAllowedMethodAnnotations() {
+ return allowedListeners;
}
- @Start
- void start() {
- syncProcessor = new WithinThreadExecutor();
- }
-
- /**
- * Loops through all valid methods on the object passed in, and caches the relevant methods as {@link
- * CacheNotifierImpl.ListenerInvocation} for invocation by reflection.
- *
- * @param listener object to be considered as a listener.
- */
- @SuppressWarnings("unchecked")
- private void validateAndAddListenerInvocation(Object listener) {
- boolean sync = testListenerClassValidity(listener.getClass());
-
- boolean foundMethods = false;
- // now try all methods on the listener for anything that we like. Note that only PUBLIC methods are scanned.
- for (Method m : listener.getClass().getMethods()) {
- // loop through all valid method annotations
- for (int i = 0; i < allowedMethodAnnotations.length; i++) {
- if (m.isAnnotationPresent(allowedMethodAnnotations[i])) {
- testListenerMethodValidity(m, parameterTypes[i], allowedMethodAnnotations[i].getName());
- addListenerInvocation(allowedMethodAnnotations[i], new ListenerInvocation(listener, m, sync));
- foundMethods = true;
- }
- }
- }
-
- if (!foundMethods && log.isWarnEnabled())
- log.warn("Attempted to register listener of class " + listener.getClass() + ", but no valid, public methods annotated with method-level event annotations found! Ignoring listener.");
- }
-
- /**
- * Tests if a class is properly annotated as a CacheListener and returns whether callbacks on this class should be
- * invoked synchronously or asynchronously.
- *
- * @param listenerClass class to inspect
- * @return true if callbacks on this class should use the syncProcessor; false if it should use the asyncProcessor.
- */
- private static boolean testListenerClassValidity(Class<?> listenerClass) {
- Listener l = ReflectionUtil.getAnnotation(listenerClass, Listener.class);
- if (l == null)
- throw new IncorrectListenerException("Cache listener class MUST be annotated with org.horizon.notifications.annotation.Listener");
- if (!Modifier.isPublic(listenerClass.getModifiers()))
- throw new IncorrectListenerException("Cache listener class MUST be public!");
- return l.sync();
- }
-
- private static void testListenerMethodValidity(Method m, Class allowedParameter, String annotationName) {
- if (m.getParameterTypes().length != 1 || !m.getParameterTypes()[0].isAssignableFrom(allowedParameter))
- throw new IncorrectListenerException("Methods annotated with " + annotationName + " must accept exactly one parameter, of assignable from type " + allowedParameter.getName());
- if (!m.getReturnType().equals(void.class))
- throw new IncorrectListenerException("Methods annotated with " + annotationName + " should have a return type of void.");
- }
-
- private void addListenerInvocation(Class annotation, ListenerInvocation li) {
- List<ListenerInvocation> result = getListenerCollectionForAnnotation(annotation);
- result.add(li);
- }
-
- public void addListener(Object listener) {
- validateAndAddListenerInvocation(listener);
- }
-
- public void removeListener(Object listener) {
- for (Class annotation : allowedMethodAnnotations) removeListenerInvocation(annotation, listener);
- }
-
- private void removeListenerInvocation(Class annotation, Object listener) {
- if (listener == null) return;
- List<ListenerInvocation> l = getListenerCollectionForAnnotation(annotation);
- Set<Object> markedForRemoval = new HashSet<Object>();
- for (ListenerInvocation li : l) {
- if (listener.equals(li.target)) markedForRemoval.add(li);
- }
- l.removeAll(markedForRemoval);
- }
-
- /**
- * Removes all listeners from the notifier, including the evictionPolicyListener.
- */
- @Stop(priority = 99)
- public void removeAllCacheListeners() {
- cacheEntryCreatedListeners.clear();
- cacheEntryRemovedListeners.clear();
- cacheEntryVisitedListeners.clear();
- cacheEntryModifiedListeners.clear();
- cacheEntryActivatedListeners.clear();
- cacheEntryPassivatedListeners.clear();
- cacheEntryLoadedListeners.clear();
- cacheEntryEvictedListeners.clear();
- transactionRegisteredListeners.clear();
- transactionCompletedListeners.clear();
- }
-
- public Set<Object> getListeners() {
- Set<Object> result = new HashSet<Object>();
- for (List<ListenerInvocation> list : listenersMap.values()) {
- for (ListenerInvocation li : list) result.add(li.target);
- }
- return Collections.unmodifiableSet(result);
- }
-
public void notifyCacheEntryCreated(Object key, boolean pre, InvocationContext ctx) {
if (!cacheEntryCreatedListeners.isEmpty()) {
boolean originLocal = ctx.isOriginLocal();
@@ -437,53 +309,4 @@
newContext.putLookedUpEntries(ctx.getLookedUpEntries());
return ctx;
}
-
- /**
- * Class that encapsulates a valid invocation for a given registered listener - containing a reference to the method
- * to be invoked as well as the target object.
- */
- class ListenerInvocation {
- private final Object target;
- private final Method method;
- private final boolean sync;
-
- public ListenerInvocation(Object target, Method method, boolean sync) {
- this.target = target;
- this.method = method;
- this.sync = sync;
- }
-
- public void invoke(final Event e) {
- Runnable r = new Runnable() {
-
- public void run() {
- try {
- method.invoke(target, e);
- }
- catch (InvocationTargetException exception) {
- Throwable cause = exception.getCause();
- if (cause != null)
- throw new CacheException("Caught exception invoking method " + method + " on listener instance " + target, cause);
- else
- throw new CacheException("Caught exception invoking method " + method + " on listener instance " + target, exception);
- }
- catch (IllegalAccessException exception) {
- log.warn("Unable to invoke method " + method + " on Object instance " + target + " - removing this target object from list of listeners!", exception);
- removeListener(target);
- }
- }
- };
-
- if (sync)
- syncProcessor.execute(r);
- else
- asyncProcessor.execute(r);
- }
- }
-
- private List<ListenerInvocation> getListenerCollectionForAnnotation(Class<? extends Annotation> annotation) {
- List<ListenerInvocation> list = listenersMap.get(annotation);
- if (list == null) throw new CacheException("Unknown listener annotation: " + annotation);
- return list;
- }
}
Modified: core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifier.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifier.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifier.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -1,5 +1,8 @@
package org.horizon.notifications.cachemanagerlistener;
+import org.horizon.factories.annotations.NonVolatile;
+import org.horizon.factories.scopes.Scope;
+import org.horizon.factories.scopes.Scopes;
import org.horizon.notifications.Listenable;
import org.horizon.remoting.transport.Address;
@@ -11,6 +14,8 @@
* @author Manik Surtani
* @since 1.0
*/
+@NonVolatile
+(a)Scope(Scopes.GLOBAL)
public interface CacheManagerNotifier extends Listenable {
/**
* Notifies all registered listeners of a viewChange event. Note that viewChange notifications are ALWAYS sent
Modified: core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifierImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifierImpl.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/main/java/org/horizon/notifications/cachemanagerlistener/CacheManagerNotifierImpl.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -1,56 +1,102 @@
package org.horizon.notifications.cachemanagerlistener;
-import org.horizon.factories.annotations.NonVolatile;
-import org.horizon.factories.annotations.Start;
import org.horizon.factories.annotations.Stop;
-import org.horizon.factories.scopes.Scope;
-import org.horizon.factories.scopes.Scopes;
+import org.horizon.logging.Log;
+import org.horizon.logging.LogFactory;
+import org.horizon.manager.CacheManager;
+import org.horizon.notifications.AbstractListenerImpl;
+import org.horizon.notifications.cachemanagerlistener.annotation.CacheStarted;
+import org.horizon.notifications.cachemanagerlistener.annotation.CacheStopped;
+import org.horizon.notifications.cachemanagerlistener.annotation.ViewChanged;
+import org.horizon.notifications.cachemanagerlistener.event.CacheStartedEvent;
+import org.horizon.notifications.cachemanagerlistener.event.CacheStoppedEvent;
+import org.horizon.notifications.cachemanagerlistener.event.Event;
+import org.horizon.notifications.cachemanagerlistener.event.EventImpl;
+import org.horizon.notifications.cachemanagerlistener.event.ViewChangedEvent;
import org.horizon.remoting.transport.Address;
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
- * Global, shared notifications. Typically on the CacheManager. See
+ * Global, shared notifications on the cache manager.
*
* @author Manik Surtani
* @since 1.0
*/
-@NonVolatile
-(a)Scope(Scopes.GLOBAL)
-public class CacheManagerNotifierImpl implements CacheManagerNotifier {
+public class CacheManagerNotifierImpl extends AbstractListenerImpl implements CacheManagerNotifier {
- public void notifyViewChange(List<Address> members, Address myAddress) {
- // TODO: Manik: Customise this generated block
- }
+ private static final Log log = LogFactory.getLog(CacheManagerNotifierImpl.class);
- public void notifyCacheStarted(String cacheName) {
- // TODO: Manik: Customise this generated block
+ private static final Map<Class<? extends Annotation>, Class> allowedListeners = new HashMap<Class<? extends Annotation>, Class>();
+
+ static {
+ allowedListeners.put(CacheStarted.class, CacheStartedEvent.class);
+ allowedListeners.put(CacheStopped.class, CacheStoppedEvent.class);
+ allowedListeners.put(ViewChanged.class, ViewChangedEvent.class);
}
- public void notifyCacheStopped(String cacheName) {
- // TODO: Manik: Customise this generated block
+ final List<ListenerInvocation> cacheStartedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ final List<ListenerInvocation> cacheStoppedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+ final List<ListenerInvocation> viewChangedListeners = new CopyOnWriteArrayList<ListenerInvocation>();
+
+ private CacheManager cacheManager;
+
+ public CacheManagerNotifierImpl() {
+ listenersMap.put(CacheStarted.class, cacheStartedListeners);
+ listenersMap.put(CacheStopped.class, cacheStoppedListeners);
+ listenersMap.put(ViewChanged.class, viewChangedListeners);
}
- public void addListener(Object listener) {
- // TODO: Manik: Customise this generated block
+ public void injectCacheManager(CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
}
- public void removeListener(Object listener) {
- // TODO: Manik: Customise this generated block
+ public void notifyViewChange(List<Address> members, Address myAddress) {
+ if (!viewChangedListeners.isEmpty()) {
+ EventImpl e = new EventImpl();
+ e.setLocalAddress(myAddress);
+ e.setNewMemberList(members);
+ e.setCacheManager(cacheManager);
+ e.setType(Event.Type.VIEW_CHANGED);
+ for (ListenerInvocation listener : viewChangedListeners) listener.invoke(e);
+ }
}
- public Set<Object> getListeners() {
- return null; // TODO: Manik: Customise this generated block
+ public void notifyCacheStarted(String cacheName) {
+ if (!cacheStartedListeners.isEmpty()) {
+ EventImpl e = new EventImpl();
+ e.setCacheName(cacheName);
+ e.setCacheManager(cacheManager);
+ e.setType(Event.Type.CACHE_STARTED);
+ for (ListenerInvocation listener : cacheStartedListeners) listener.invoke(e);
+ }
}
- @Start
- public void start() {
- // TODO: Manik: Customise this generated block
+ public void notifyCacheStopped(String cacheName) {
+ if (!cacheStoppedListeners.isEmpty()) {
+ EventImpl e = new EventImpl();
+ e.setCacheName(cacheName);
+ e.setCacheManager(cacheManager);
+ e.setType(Event.Type.CACHE_STOPPED);
+ for (ListenerInvocation listener : cacheStoppedListeners) listener.invoke(e);
+ }
}
@Stop
- public void stop() {
+ void stop() {
+ if (syncProcessor != null) syncProcessor.shutdownNow();
+ if (asyncProcessor != null) asyncProcessor.shutdownNow();
+ }
+ protected Log getLog() {
+ return log;
}
+
+ protected Map<Class<? extends Annotation>, Class> getAllowedMethodAnnotations() {
+ return allowedListeners;
+ }
}
Modified: core/branches/flat/src/test/java/org/horizon/notifications/ConcurrentNotificationTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/notifications/ConcurrentNotificationTest.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/test/java/org/horizon/notifications/ConcurrentNotificationTest.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -20,7 +20,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
-@Test(groups = {"functional"}, sequential = true, testName = "notifications.ConcurrentNotificationTest")
+@Test(groups = "functional", sequential = true, testName = "notifications.ConcurrentNotificationTest")
public class ConcurrentNotificationTest {
Cache<String, String> cache;
CacheManager cm;
Modified: core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java 2009-02-02 13:07:49 UTC (rev 7623)
+++ core/branches/flat/src/test/java/org/horizon/notifications/cachelistener/CacheNotifierImplTest.java 2009-02-02 14:31:03 UTC (rev 7624)
@@ -29,7 +29,7 @@
mockCache = createNiceMock(CacheSPI.class);
EasyMock.expect(mockCache.getInvocationContext()).andReturn(new InvocationContextImpl()).anyTimes();
EasyMock.replay(mockCache);
- n.injectDependencies(mockCache, null);
+ n.injectDependencies(mockCache);
cl = new CacheListener();
n.start();
n.addListener(cl);
15 years, 11 months
JBoss Cache SVN: r7623 - core/trunk/src/test/java/org/jboss/cache/loader.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2009-02-02 08:07:49 -0500 (Mon, 02 Feb 2009)
New Revision: 7623
Modified:
core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java
Log:
made more stable
Modified: core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java 2009-01-31 10:39:31 UTC (rev 7622)
+++ core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java 2009-02-02 13:07:49 UTC (rev 7623)
@@ -21,7 +21,7 @@
import org.jboss.cache.factories.UnitTestConfigurationFactory;
import org.jboss.cache.util.TestingUtil;
-@Test(groups = "functional", sequential = true, testName = "loader.AsyncFileCacheLoaderTest")
+@Test(groups = "functional", testName = "loader.AsyncFileCacheLoaderTest")
public class AsyncFileCacheLoaderTest
{
private CacheSPI<Object, Object> cache;
@@ -112,7 +112,13 @@
{
cache.put(fqn, "key" + i, "value1");
}
- Thread.sleep(1000);
+ //this happens async, so expect this will happen at a further point in time
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < 50000)
+ {
+ if (loader.get(fqn) != null && loader.get(fqn).size() == 50) break;
+ Thread.sleep(100);
+ }
assertEquals(50, loader.get(fqn).size());
loader.remove(fqn);
}
@@ -168,7 +174,13 @@
{
cache.put(fqn, "key" + i, "value1");
}
- Thread.sleep(1000);
+ //this happens async, so expect this will happen at a further point in time
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < 50000)
+ {
+ if (loader.get(fqn) != null && loader.get(fqn).size() == 50) break;
+ Thread.sleep(100);
+ }
assertEquals(50, loader.get(fqn).size());
loader.remove(fqn);
}
15 years, 11 months