[jboss-cvs] JBossAS SVN: r71192 - in projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache: spi/impl and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Mar 24 01:22:09 EDT 2008
Author: bstansberry at jboss.com
Date: 2008-03-24 01:22:09 -0400 (Mon, 24 Mar 2008)
New Revision: 71192
Modified:
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractPassivatingIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java
Log:
[EJBTHREE-1026] Push more passivation/activation work into abstract superclass
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java 2008-03-24 05:19:41 UTC (rev 71191)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java 2008-03-24 05:22:09 UTC (rev 71192)
@@ -22,10 +22,10 @@
package org.jboss.ejb3.cache.impl.backing;
-import java.util.HashMap;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.jboss.ejb3.annotation.CacheConfig;
@@ -35,7 +35,6 @@
import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
import org.jboss.ejb3.cache.spi.impl.AbstractPassivatingIntegratedObjectStore;
import org.jboss.ejb3.cache.spi.impl.CacheableTimestamp;
-import org.jboss.logging.Logger;
/**
* A {@link PassivatingIntegratedObjectStore} that stores in a simple
@@ -46,10 +45,8 @@
* @version $Revision$
*/
public class SimplePassivatingIntegratedObjectStore<C extends CacheItem, T extends PassivatingBackingCacheEntry<C>>
- extends AbstractPassivatingIntegratedObjectStore<C, T>
+ extends AbstractPassivatingIntegratedObjectStore<C, T, Object>
{
- private static final Logger log = Logger.getLogger(SimplePassivatingIntegratedObjectStore.class);
-
private final ObjectStore<T> store;
private Map<Object, T> cache;
private Map<Object, Long> passivatedEntries;
@@ -68,10 +65,7 @@
this.store = store;
this.cache = new ConcurrentHashMap<Object, T>();
- if (!forGroups)
- {
- this.passivatedEntries = new HashMap<Object, Long>();
- }
+ this.passivatedEntries = new ConcurrentHashMap<Object, Long>();
}
public boolean isClustered()
@@ -88,10 +82,7 @@
if(entry != null)
{
cache.put(key, entry);
- if (!isForGroups())
- {
- passivatedEntries.remove(key);
- }
+ passivatedEntries.remove(key);
}
}
return entry;
@@ -100,8 +91,7 @@
public void insert(T entry)
{
Object key = entry.getId();
- if (cache.containsKey(key)
- || (!isForGroups() && passivatedEntries.containsKey(key)))
+ if (cache.containsKey(key) || passivatedEntries.containsKey(key))
{
throw new IllegalStateException(key + " is already in store");
}
@@ -111,8 +101,7 @@
public void update(T entry, boolean modified)
{
Object key = entry.getId();
- if (!cache.containsKey(key) &&
- (isForGroups() || !passivatedEntries.containsKey(key)))
+ if (!cache.containsKey(key) && !passivatedEntries.containsKey(key))
{
throw new IllegalStateException(key + " is not managed by this store");
}
@@ -126,10 +115,7 @@
{
Object key = entry.getId();
store.store(entry);
- if (!isForGroups())
- {
- passivatedEntries.put(key, new Long(entry.getLastUsed()));
- }
+ passivatedEntries.put(key, new Long(entry.getLastUsed()));
cache.remove(key);
}
}
@@ -161,99 +147,73 @@
// ------------------------------- AbstractPassivatingIntegratedObjectStore
@Override
- protected void runExpiration()
+ public int getInMemoryCount()
{
- if (!isForGroups() && getExpirationTimeSeconds() > 0)
- {
- long now = System.currentTimeMillis();
- long minRemovalUse = now - (getExpirationTimeSeconds() * 1000);
- for (CacheableTimestamp ts : getAllEntries())
- {
- try
- {
- if (minRemovalUse >= ts.getLastUsed())
- {
- remove(ts.getId());
- }
- }
- catch (IllegalStateException ise)
- {
- // Not so great; we're assuming it's 'cause item's in use
- log.trace("skipping in-use entry " + ts.getId(), ise);
- }
- }
- }
+ return cache.size();
}
-
+
@Override
- protected void runPassivation()
+ public int getPassivatedCount()
{
- if (!isForGroups()
- && (getMaxSize() > 0 || getIdleTimeSeconds() > 0))
+ return passivatedEntries.size();
+ }
+
+ @Override
+ protected void processPassivation(Object key)
+ {
+ // If we are for groups we shouldn't be getting a processPassivation
+ // call at all, but just to be safe we'll ignore it
+ if (!isForGroups())
{
- long now = System.currentTimeMillis();
- long minPassUse = (getIdleTimeSeconds() > 0 ? now - (getIdleTimeSeconds() * 1000) : 0);
-
- SortedSet<CacheableTimestamp> timestamps = getInMemoryEntries();
- int overCount = (getMaxSize() > 0 ? timestamps.size() - getMaxSize() : 0);
- for (CacheableTimestamp ts : timestamps)
- {
- try
- {
- if (overCount > 0 || minPassUse >= ts.getLastUsed())
- {
- log.trace("attempting to passivate " + ts.getId());
- getPassivatingCache().passivate(ts.getId());
- overCount--;
- }
- else
- {
- break;
- }
- }
- catch (IllegalStateException ise)
- {
- // Not so great; we're assuming it's 'cause item's in use
- log.trace("skipping in-use entry " + ts.getId(), ise);
- }
- }
- }
+ getPassivatingCache().passivate(key);
+ }
}
+
+ @Override
+ protected void processExpiration(Object key)
+ {
+ getPassivatingCache().remove(key);
+ }
- private SortedSet<CacheableTimestamp> getInMemoryEntries()
- {
- SortedSet<CacheableTimestamp> set = new TreeSet<CacheableTimestamp>();
+ @Override
+ @SuppressWarnings("unchecked")
+ protected CacheableTimestamp<Object>[] getInMemoryEntries()
+ {
+ Set<CacheableTimestamp<Object>> set = new HashSet<CacheableTimestamp<Object>>();
for (Map.Entry<Object, T> entry : cache.entrySet())
{
- set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().getLastUsed()));
+ set.add(new CacheableTimestamp<Object>(entry.getKey(), entry.getValue().getLastUsed()));
}
- return set;
+ CacheableTimestamp<Object>[] array = new CacheableTimestamp[set.size()];
+ array = set.toArray(array);
+ Arrays.sort(array);
+ return array;
}
- private SortedSet<CacheableTimestamp> getPassivatedEntries()
- {
- SortedSet<CacheableTimestamp> set = new TreeSet<CacheableTimestamp>();
- if (!isForGroups())
+ @Override
+ @SuppressWarnings("unchecked")
+ protected CacheableTimestamp<Object>[] getAllEntries()
+ {
+ Set<CacheableTimestamp<Object>> set = new HashSet<CacheableTimestamp<Object>>();
+ for (Map.Entry<Object, T> entry : cache.entrySet())
{
- for (Map.Entry<Object, Long> entry : passivatedEntries.entrySet())
- {
- set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().longValue()));
- }
+ set.add(new CacheableTimestamp<Object>(entry.getKey(), entry.getValue().getLastUsed()));
}
- return set;
- }
-
- private SortedSet<CacheableTimestamp> getAllEntries()
- {
- SortedSet<CacheableTimestamp> set = getInMemoryEntries();
- if (!isForGroups())
+ CacheableTimestamp<Object>[] inMemory = new CacheableTimestamp[set.size()];
+ inMemory = set.toArray(inMemory);
+
+ set = new HashSet<CacheableTimestamp<Object>>();
+ for (Map.Entry<Object, Long> entry : passivatedEntries.entrySet())
{
- for (Map.Entry<Object, Long> entry : passivatedEntries.entrySet())
- {
- set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().longValue()));
- }
+ set.add(new CacheableTimestamp<Object>(entry.getKey(), entry.getValue()));
}
- return set;
- }
+ CacheableTimestamp<Object>[] passivated = new CacheableTimestamp[set.size()];
+ passivated = set.toArray(passivated);
+ CacheableTimestamp<Object>[] all = new CacheableTimestamp[passivated.length + inMemory.length];
+ System.arraycopy(passivated, 0, all, 0, passivated.length);
+ System.arraycopy(inMemory, 0, all, passivated.length, inMemory.length);
+ Arrays.sort(all);
+ return all;
+ }
}
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractPassivatingIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractPassivatingIntegratedObjectStore.java 2008-03-24 05:19:41 UTC (rev 71191)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractPassivatingIntegratedObjectStore.java 2008-03-24 05:22:09 UTC (rev 71192)
@@ -36,7 +36,7 @@
* @author Brian Stansberry
* @version $Revision$
*/
-public abstract class AbstractPassivatingIntegratedObjectStore<C extends CacheItem, T extends PassivatingBackingCacheEntry<C>>
+public abstract class AbstractPassivatingIntegratedObjectStore<C extends CacheItem, T extends PassivatingBackingCacheEntry<C>, K>
implements PassivatingIntegratedObjectStore<C, T>
{
private static final Logger log = Logger.getLogger(AbstractPassivatingIntegratedObjectStore.class);
@@ -74,9 +74,46 @@
// ---------------------------------------------------------------- Abstract
- protected abstract void runExpiration();
+ /**
+ * Invoked by {@link #processPassivationExpiration()} to indicate the
+ * item associated with the given key needs to be passivated.
+ */
+ protected abstract void processPassivation(K key);
+ /**
+ * Invoked by {@link #processPassivationExpiration()} to indicate the
+ * item associated with the given key needs to be expired.
+ */
+ protected abstract void processExpiration(K key);
- protected abstract void runPassivation();
+ /**
+ * Get a set of {@link CacheableTimestamp} representing the items currently
+ * in memory.
+ *
+ * @return array of {@link CacheableTimestamp}, sorted by
+ * {@link CacheableTimestamp#getLastUsed() last use}, with least
+ * recently used items first.
+ */
+ protected abstract CacheableTimestamp<K>[] getInMemoryEntries();
+
+ /**
+ * Get a set of {@link CacheableTimestamp} representing all items, both
+ * those in memory and those passivated.
+ *
+ * @return array of {@link CacheableTimestamp}, sorted by
+ * {@link CacheableTimestamp#getLastUsed() last use}, with least
+ * recently used items first.
+ */
+ protected abstract CacheableTimestamp<K>[] getAllEntries();
+
+ /**
+ * Get the number of items in memory.
+ */
+ public abstract int getInMemoryCount();
+
+ /**
+ * Get the number of passivated items.
+ */
+ public abstract int getPassivatedCount();
// -------------------------------------------------- IntegratedObjectStore
@@ -215,6 +252,71 @@
this.maxSize = maxSize;
}
+ // -------------------------------------------------------------- Protected
+
+
+ // ---------------------------------------------------------------- Private
+ private void runExpiration()
+ {
+ if (!isForGroups() && getExpirationTimeSeconds() > 0)
+ {
+ long now = System.currentTimeMillis();
+ long minRemovalUse = now - (getExpirationTimeSeconds() * 1000);
+ for (CacheableTimestamp<K> ts : getAllEntries())
+ {
+ try
+ {
+ if (minRemovalUse >= ts.getLastUsed())
+ {
+ processExpiration(ts.getId());
+ }
+ else
+ {
+ break;
+ }
+ }
+ catch (IllegalStateException ise)
+ {
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + ts.getId(), ise);
+ }
+ }
+ }
+ }
+
+ private void runPassivation()
+ {
+ if (!isForGroups()
+ && (getMaxSize() > 0 || getIdleTimeSeconds() > 0))
+ {
+ long now = System.currentTimeMillis();
+ long minPassUse = (getIdleTimeSeconds() > 0 ? now - (getIdleTimeSeconds() * 1000) : 0);
+
+ CacheableTimestamp<K>[] timestamps = getInMemoryEntries();
+ int overCount = (getMaxSize() > 0 ? timestamps.length - getMaxSize() : 0);
+ for (CacheableTimestamp<K> ts : timestamps)
+ {
+ try
+ {
+ if (overCount > 0 || minPassUse >= ts.getLastUsed())
+ {
+ log.trace("attempting to passivate " + ts.getId());
+ processPassivation(ts.getId());
+ overCount--;
+ }
+ else
+ {
+ break;
+ }
+ }
+ catch (IllegalStateException ise)
+ {
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + ts.getId(), ise);
+ }
+ }
+ }
+ }
}
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java 2008-03-24 05:19:41 UTC (rev 71191)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java 2008-03-24 05:22:09 UTC (rev 71192)
@@ -41,13 +41,13 @@
* @author Brian Stansberry
* @version $Revision$
*/
-public class CacheableTimestamp
- implements Identifiable, Comparable<CacheableTimestamp>
+public class CacheableTimestamp<K>
+ implements Identifiable, Comparable<CacheableTimestamp<K>>
{
- private Object id;
+ private K id;
private long lastUsed;
- public CacheableTimestamp(Object id, long lastUsed)
+ public CacheableTimestamp(K id, long lastUsed)
{
assert id != null : "id cannot be null";
assert lastUsed > 0 : "lastUsed must be positive";
@@ -56,7 +56,7 @@
this.lastUsed = lastUsed;
}
- public Object getId()
+ public K getId()
{
return id;
}
@@ -70,16 +70,17 @@
* Compares based on {@link #getLastUsed() last used}, returning
* -1 for earlier timestamps.
*/
- public int compareTo(CacheableTimestamp o)
- {
+ public int compareTo(CacheableTimestamp<K> o)
+ {
if (this.lastUsed < o.lastUsed)
return -1;
else if (this.lastUsed > o.lastUsed)
return 1;
- return 0;
+ return 0;
}
@Override
+ @SuppressWarnings("unchecked")
public boolean equals(Object obj)
{
if (this == obj)
@@ -87,7 +88,7 @@
if (obj instanceof CacheableTimestamp)
{
- return this.id.equals(((CacheableTimestamp) obj).id);
+ return this.id.equals(((CacheableTimestamp<K>) obj).id);
}
return false;
}
More information about the jboss-cvs-commits
mailing list