Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

  • Loading branch information...
commit 90793a556b1176d85f3d0a41d4ebb7519a329938 1 parent 7bad8e4
Galder Zamarreño authored March 11, 2013 Mircea Markus committed March 12, 2013
22  core/src/main/java/org/infinispan/atomic/AtomicHashMap.java
@@ -30,6 +30,8 @@
30 30
 import org.infinispan.marshall.Ids;
31 31
 import org.infinispan.util.FastCopyHashMap;
32 32
 import org.infinispan.util.Util;
  33
+import org.infinispan.util.logging.Log;
  34
+import org.infinispan.util.logging.LogFactory;
33 35
 
34 36
 import java.io.IOException;
35 37
 import java.io.ObjectInput;
@@ -61,6 +63,9 @@
61 63
 @NotThreadSafe
62 64
 public final class AtomicHashMap<K, V> implements AtomicMap<K, V>, DeltaAware, Cloneable {
63 65
 
  66
+   private static final Log log = LogFactory.getLog(AtomicHashMap.class);
  67
+   private static final boolean trace = log.isTraceEnabled();
  68
+
64 69
    protected final FastCopyHashMap<K, V> delegate;
65 70
    private AtomicHashMapDelta delta = null;
66 71
    private volatile AtomicHashMapProxy<K, V> proxy;
@@ -125,7 +130,11 @@ public boolean containsValue(Object value) {
125 130
 
126 131
    @Override
127 132
    public V get(Object key) {
128  
-      return delegate.get(key);
  133
+      V v = delegate.get(key);
  134
+      if (trace)
  135
+         log.tracef("Atomic hash map get(key=%s) returns %s", key, v);
  136
+
  137
+      return v;
129 138
    }
130 139
 
131 140
    @Override
@@ -214,8 +223,12 @@ public Delta delta() {
214 223
 
215 224
    @Override
216 225
    public String toString() {
217  
-      //Avoid iterating on the delegate as that might lead to exceptions from concurrent iterators:
218  
-      //not nice to have during a toString!
  226
+      // Sanne: Avoid iterating on the delegate as that might lead to
  227
+      // exceptions from concurrent iterators: not nice to have during a toString!
  228
+      //
  229
+      // Galder: Sure, but we need a way to track the contents of the atomic
  230
+      // hash map somehow, so, we need to log each operation that affects its
  231
+      // contents, and when its state is restored.
219 232
       return "AtomicHashMap";
220 233
    }
221 234
 
@@ -241,6 +254,9 @@ public void writeObject(ObjectOutput output, AtomicHashMap map) throws IOExcepti
241 254
       @SuppressWarnings("unchecked")
242 255
       public AtomicHashMap readObject(ObjectInput input) throws IOException, ClassNotFoundException {
243 256
          FastCopyHashMap<?, ?> delegate = (FastCopyHashMap<?, ?>) input.readObject();
  257
+         if (trace)
  258
+            log.tracef("Restore atomic hash map from %s", delegate);
  259
+
244 260
          return new AtomicHashMap(delegate);
245 261
       }
246 262
 
5  core/src/main/java/org/infinispan/atomic/AtomicHashMapDelta.java
@@ -34,7 +34,6 @@
34 34
 import java.util.Collection;
35 35
 import java.util.LinkedList;
36 36
 import java.util.List;
37  
-import java.util.Map;
38 37
 import java.util.Set;
39 38
 
40 39
 /**
@@ -71,6 +70,10 @@ public void addOperation(Operation<?, ?> o) {
71 70
       if(o instanceof ClearOperation) {
72 71
          hasClearOperation = true;
73 72
       }
  73
+
  74
+      if (trace)
  75
+         log.tracef("Add operation %s to delta", o);
  76
+
74 77
       changeLog.add((Operation<Object, Object>) o);
75 78
    }
76 79
    
7  core/src/main/java/org/infinispan/commands/write/EvictCommand.java
@@ -27,6 +27,8 @@
27 27
 import org.infinispan.context.Flag;
28 28
 import org.infinispan.context.InvocationContext;
29 29
 import org.infinispan.notifications.cachelistener.CacheNotifier;
  30
+import org.infinispan.util.logging.Log;
  31
+import org.infinispan.util.logging.LogFactory;
30 32
 
31 33
 import java.util.Set;
32 34
 
@@ -36,6 +38,8 @@
36 38
  */
37 39
 public class EvictCommand extends RemoveCommand implements LocalCommand {
38 40
 
  41
+   private static final Log log = LogFactory.getLog(EvictCommand.class);
  42
+
39 43
    public EvictCommand(Object key, CacheNotifier notifier, Set<Flag> flags) {
40 44
       super(key, null, notifier, flags);
41 45
    }
@@ -57,6 +61,9 @@ public Object perform(InvocationContext ctx) throws Throwable {
57 61
    @Override
58 62
    public void notify(InvocationContext ctx, Object value, boolean isPre) {
59 63
       if (!isPre) {
  64
+         if (log.isTraceEnabled())
  65
+            log.tracef("Notify eviction listeners for key=%", key);
  66
+
60 67
          notifier.notifyCacheEntryEvicted(key, value, ctx);
61 68
       }
62 69
    }
3  core/src/main/java/org/infinispan/eviction/ActivationManagerImpl.java
@@ -83,6 +83,9 @@ public void start() {
83 83
    public void activate(Object key) {
84 84
       if (enabled) {
85 85
          try {
  86
+            if (trace)
  87
+               log.tracef("Try to activate key=%s removing it from the store", key);
  88
+
86 89
             if (store.remove(key) && statisticsEnabled) {
87 90
                activations.incrementAndGet();
88 91
             }
5  core/src/main/java/org/infinispan/interceptors/ActivationInterceptor.java
@@ -37,6 +37,8 @@
37 37
 import org.infinispan.util.logging.Log;
38 38
 import org.infinispan.util.logging.LogFactory;
39 39
 
  40
+import java.util.Arrays;
  41
+
40 42
 public class ActivationInterceptor extends CacheLoaderInterceptor {
41 43
 
42 44
    private static final Log log = LogFactory.getLog(ActivationInterceptor.class);
@@ -113,6 +115,9 @@ protected void sendNotification(Object key, Object value, boolean pre, Invocatio
113 115
 
114 116
    private void removeFromStoreIfNeeded(Object... keys) {
115 117
       if (enabled && isManualEviction) {
  118
+         if (log.isTraceEnabled())
  119
+            log.tracef("Remove from store keys=%s, if needed", Arrays.toString(keys));
  120
+
116 121
          for (Object key: keys)
117 122
             activationManager.activate(key);
118 123
       }
10  core/src/main/java/org/infinispan/util/FastCopyHashMap.java
@@ -22,6 +22,9 @@
22 22
  */
23 23
 package org.infinispan.util;
24 24
 
  25
+import org.infinispan.util.logging.Log;
  26
+import org.infinispan.util.logging.LogFactory;
  27
+
25 28
 import java.io.IOException;
26 29
 import java.io.Serializable;
27 30
 import java.util.AbstractCollection;
@@ -42,6 +45,10 @@
42 45
  * @since 4.0
43 46
  */
44 47
 public class FastCopyHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {
  48
+
  49
+   private static final Log log = LogFactory.getLog(FastCopyHashMap.class);
  50
+   private static final boolean trace = log.isTraceEnabled();
  51
+
45 52
    /**
46 53
     * Serialization ID
47 54
     */
@@ -597,6 +604,9 @@ public V setValue(V value) {
597 604
       @Override
598 605
       public Map.Entry<K, V> next() {
599 606
          Entry<K, V> e = nextEntry();
  607
+         if (trace)
  608
+            log.tracef("Next entry: key=%s, value=%s", e.key, e.value);
  609
+
600 610
          return new WriteThroughEntry(e.key, e.value);
601 611
       }
602 612
    }
20  core/src/main/java/org/infinispan/util/concurrent/BoundedConcurrentHashMap.java
@@ -31,8 +31,12 @@
31 31
  */
32 32
 
33 33
 package org.infinispan.util.concurrent;
  34
+import org.infinispan.container.entries.CacheEntry;
34 35
 import org.infinispan.util.InfinispanCollections;
35 36
 import org.infinispan.util.Util;
  37
+import org.infinispan.util.logging.Log;
  38
+import org.infinispan.util.logging.LogFactory;
  39
+
36 40
 import java.io.IOException;
37 41
 import java.io.Serializable;
38 42
 import java.util.*;
@@ -107,6 +111,10 @@
107 111
  */
108 112
 public class BoundedConcurrentHashMap<K, V> extends AbstractMap<K, V>
109 113
         implements ConcurrentMap<K, V>, Serializable {
  114
+
  115
+   private static final Log log = LogFactory.getLog(BoundedConcurrentHashMap.class);
  116
+   private static final boolean trace = log.isTraceEnabled();
  117
+
110 118
    private static final long serialVersionUID = 7249069246763182397L;
111 119
 
112 120
    /*
@@ -1699,7 +1707,7 @@ V remove(Object key, int hash, Object value, boolean isEvict) {
1699 1707
             V oldValue = null;
1700 1708
             if (e != null) {
1701 1709
                V v = e.value;
1702  
-               if (isEvict) {
  1710
+               if (isEvictionRemoval(isEvict, oldValue)) {
1703 1711
                   // If evicting, entry has to be passivated if enabled and
1704 1712
                   // hence its cost is limited to this use case.
1705 1713
                   // Required to guarantee passivation/activation correctness.
@@ -1730,7 +1738,10 @@ V remove(Object key, int hash, Object value, boolean isEvict) {
1730 1738
                }
1731 1739
             }
1732 1740
 
1733  
-            if (!isEvict) {
  1741
+            if (!isEvictionRemoval(isEvict, oldValue)) {
  1742
+               if (trace)
  1743
+                  log.tracef("Entry removed (not evicting), so remove from cache store too");
  1744
+
1734 1745
                // If removing (and not evicting), remove from cache store too
1735 1746
                evictionListener.onEntryRemoved(key);
1736 1747
             }
@@ -1741,6 +1752,11 @@ V remove(Object key, int hash, Object value, boolean isEvict) {
1741 1752
          }
1742 1753
       }
1743 1754
 
  1755
+      private boolean isEvictionRemoval(boolean isEvict, V oldValue) {
  1756
+         return isEvict ||
  1757
+               ((oldValue instanceof CacheEntry) && ((CacheEntry) oldValue).isEvicted());
  1758
+      }
  1759
+
1744 1760
       void clear() {
1745 1761
          if (count != 0) {
1746 1762
             lock();
9  core/src/test/java/org/infinispan/atomic/ClusteredAtomicMapPassivationTest.java
@@ -48,8 +48,9 @@
48 48
    protected void createCacheManagers() throws Throwable {
49 49
       ConfigurationBuilder builder = getDefaultClusteredCacheConfig(
50 50
             CacheMode.REPL_SYNC, true);
51  
-      builder.loaders().passivation(true)
52  
-                  .addStore().cacheStore(new DummyInMemoryCacheStore());
  51
+      builder.eviction().maxEntries(1024)
  52
+            .loaders().passivation(true)
  53
+            .addStore().cacheStore(new DummyInMemoryCacheStore());
53 54
       createClusteredCaches(2, "atomic", builder);
54 55
    }
55 56
 
@@ -77,8 +78,8 @@ public Void call() throws Exception {
77 78
          @Override
78 79
          public Void call() throws Exception {
79 80
             // Modify atomic map from first node
80  
-            AtomicMap<String, String> map = AtomicMapLookup.getAtomicMap(
81  
-                  cache1, "map");
  81
+            AtomicMap<String, String> map = AtomicMapLookup
  82
+                  .getAtomicMap(cache1, "map");
82 83
             map.put("key1", "new_value1");
83 84
             assertTrue(map.containsKey("key2"));
84 85
             assertEquals("value2", map.get("key2"));

0 notes on commit 90793a5

Please sign in to comment.
Something went wrong with that request. Please try again.