Permalink
Browse files

ISPN-2903 Manual evictions should not lead to cache store removals

  • Loading branch information...
1 parent 7bad8e4 commit 90793a556b1176d85f3d0a41d4ebb7519a329938 @galderz galderz committed with Mircea Markus Mar 11, 2013
View
22 core/src/main/java/org/infinispan/atomic/AtomicHashMap.java
@@ -30,6 +30,8 @@
import org.infinispan.marshall.Ids;
import org.infinispan.util.FastCopyHashMap;
import org.infinispan.util.Util;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
import java.io.IOException;
import java.io.ObjectInput;
@@ -61,6 +63,9 @@
@NotThreadSafe
public final class AtomicHashMap<K, V> implements AtomicMap<K, V>, DeltaAware, Cloneable {
+ private static final Log log = LogFactory.getLog(AtomicHashMap.class);
+ private static final boolean trace = log.isTraceEnabled();
+
protected final FastCopyHashMap<K, V> delegate;
private AtomicHashMapDelta delta = null;
private volatile AtomicHashMapProxy<K, V> proxy;
@@ -125,7 +130,11 @@ public boolean containsValue(Object value) {
@Override
public V get(Object key) {
- return delegate.get(key);
+ V v = delegate.get(key);
+ if (trace)
+ log.tracef("Atomic hash map get(key=%s) returns %s", key, v);
+
+ return v;
}
@Override
@@ -214,8 +223,12 @@ public Delta delta() {
@Override
public String toString() {
- //Avoid iterating on the delegate as that might lead to exceptions from concurrent iterators:
- //not nice to have during a toString!
+ // Sanne: Avoid iterating on the delegate as that might lead to
+ // exceptions from concurrent iterators: not nice to have during a toString!
+ //
+ // Galder: Sure, but we need a way to track the contents of the atomic
+ // hash map somehow, so, we need to log each operation that affects its
+ // contents, and when its state is restored.
return "AtomicHashMap";
}
@@ -241,6 +254,9 @@ public void writeObject(ObjectOutput output, AtomicHashMap map) throws IOExcepti
@SuppressWarnings("unchecked")
public AtomicHashMap readObject(ObjectInput input) throws IOException, ClassNotFoundException {
FastCopyHashMap<?, ?> delegate = (FastCopyHashMap<?, ?>) input.readObject();
+ if (trace)
+ log.tracef("Restore atomic hash map from %s", delegate);
+
return new AtomicHashMap(delegate);
}
View
5 core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java
@@ -34,7 +34,6 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
@@ -71,6 +70,10 @@ public void addOperation(Operation<?, ?> o) {
if(o instanceof ClearOperation) {
hasClearOperation = true;
}
+
+ if (trace)
+ log.tracef("Add operation %s to delta", o);
+
changeLog.add((Operation<Object, Object>) o);
}
View
7 core/src/main/java/org/infinispan/commands/write/EvictCommand.java
@@ -27,6 +27,8 @@
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
import org.infinispan.notifications.cachelistener.CacheNotifier;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
import java.util.Set;
@@ -36,6 +38,8 @@
*/
public class EvictCommand extends RemoveCommand implements LocalCommand {
+ private static final Log log = LogFactory.getLog(EvictCommand.class);
+
public EvictCommand(Object key, CacheNotifier notifier, Set<Flag> flags) {
super(key, null, notifier, flags);
}
@@ -57,6 +61,9 @@ public Object perform(InvocationContext ctx) throws Throwable {
@Override
public void notify(InvocationContext ctx, Object value, boolean isPre) {
if (!isPre) {
+ if (log.isTraceEnabled())
+ log.tracef("Notify eviction listeners for key=%", key);
+
notifier.notifyCacheEntryEvicted(key, value, ctx);
}
}
View
3 core/src/main/java/org/infinispan/eviction/ActivationManagerImpl.java
@@ -83,6 +83,9 @@ public void start() {
public void activate(Object key) {
if (enabled) {
try {
+ if (trace)
+ log.tracef("Try to activate key=%s removing it from the store", key);
+
if (store.remove(key) && statisticsEnabled) {
activations.incrementAndGet();
}
View
5 core/src/main/java/org/infinispan/interceptors/ActivationInterceptor.java
@@ -37,6 +37,8 @@
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
+import java.util.Arrays;
+
public class ActivationInterceptor extends CacheLoaderInterceptor {
private static final Log log = LogFactory.getLog(ActivationInterceptor.class);
@@ -113,6 +115,9 @@ protected void sendNotification(Object key, Object value, boolean pre, Invocatio
private void removeFromStoreIfNeeded(Object... keys) {
if (enabled && isManualEviction) {
+ if (log.isTraceEnabled())
+ log.tracef("Remove from store keys=%s, if needed", Arrays.toString(keys));
+
for (Object key: keys)
activationManager.activate(key);
}
View
10 core/src/main/java/org/infinispan/util/FastCopyHashMap.java
@@ -22,6 +22,9 @@
*/
package org.infinispan.util;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
import java.io.IOException;
import java.io.Serializable;
import java.util.AbstractCollection;
@@ -42,6 +45,10 @@
* @since 4.0
*/
public class FastCopyHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
+
+ private static final Log log = LogFactory.getLog(FastCopyHashMap.class);
+ private static final boolean trace = log.isTraceEnabled();
+
/**
* Serialization ID
*/
@@ -597,6 +604,9 @@ public V setValue(V value) {
@Override
public Map.Entry<K, V> next() {
Entry<K, V> e = nextEntry();
+ if (trace)
+ log.tracef("Next entry: key=%s, value=%s", e.key, e.value);
+
return new WriteThroughEntry(e.key, e.value);
}
}
View
20 core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java
@@ -31,8 +31,12 @@
*/
package org.infinispan.util.concurrent;
+import org.infinispan.container.entries.CacheEntry;
import org.infinispan.util.InfinispanCollections;
import org.infinispan.util.Util;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
@@ -107,6 +111,10 @@
*/
public class BoundedConcurrentHashMap<K, V> extends AbstractMap<K, V>
implements ConcurrentMap<K, V>, Serializable {
+
+ private static final Log log = LogFactory.getLog(BoundedConcurrentHashMap.class);
+ private static final boolean trace = log.isTraceEnabled();
+
private static final long serialVersionUID = 7249069246763182397L;
/*
@@ -1699,7 +1707,7 @@ V remove(Object key, int hash, Object value, boolean isEvict) {
V oldValue = null;
if (e != null) {
V v = e.value;
- if (isEvict) {
+ if (isEvictionRemoval(isEvict, oldValue)) {
// If evicting, entry has to be passivated if enabled and
// hence its cost is limited to this use case.
// Required to guarantee passivation/activation correctness.
@@ -1730,7 +1738,10 @@ V remove(Object key, int hash, Object value, boolean isEvict) {
}
}
- if (!isEvict) {
+ if (!isEvictionRemoval(isEvict, oldValue)) {
+ if (trace)
+ log.tracef("Entry removed (not evicting), so remove from cache store too");
+
// If removing (and not evicting), remove from cache store too
evictionListener.onEntryRemoved(key);
}
@@ -1741,6 +1752,11 @@ V remove(Object key, int hash, Object value, boolean isEvict) {
}
}
+ private boolean isEvictionRemoval(boolean isEvict, V oldValue) {
+ return isEvict ||
+ ((oldValue instanceof CacheEntry) && ((CacheEntry) oldValue).isEvicted());
+ }
+
void clear() {
if (count != 0) {
lock();
View
9 core/src/test/java/org/infinispan/atomic/ClusteredAtomicMapPassivationTest.java
@@ -48,8 +48,9 @@
protected void createCacheManagers() throws Throwable {
ConfigurationBuilder builder = getDefaultClusteredCacheConfig(
CacheMode.REPL_SYNC, true);
- builder.loaders().passivation(true)
- .addStore().cacheStore(new DummyInMemoryCacheStore());
+ builder.eviction().maxEntries(1024)
+ .loaders().passivation(true)
+ .addStore().cacheStore(new DummyInMemoryCacheStore());
createClusteredCaches(2, "atomic", builder);
}
@@ -77,8 +78,8 @@ public Void call() throws Exception {
@Override
public Void call() throws Exception {
// Modify atomic map from first node
- AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(
- cache1, "map");
+ AtomicMap<String, String> map = AtomicMapLookup
+ .getAtomicMap(cache1, "map");
map.put("key1", "new_value1");
assertTrue(map.containsKey("key2"));
assertEquals("value2", map.get("key2"));

0 comments on commit 90793a5

Please sign in to comment.