You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2016/08/08 10:35:40 UTC
svn commit: r1755491 - in /jackrabbit/oak/branches/1.2/oak-core/src:
main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
Author: tomekr
Date: Mon Aug 8 10:35:39 2016
New Revision: 1755491
URL: http://svn.apache.org/viewvc?rev=1755491&view=rev
Log:
OAK-3997: Include eviction cause to the LIRS removal callback
Modified:
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java?rev=1755491&r1=1755490&r2=1755491&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java Mon Aug 8 10:35:39 2016
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheStats;
import com.google.common.cache.LoadingCache;
+import com.google.common.cache.RemovalCause;
import com.google.common.cache.Weigher;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListenableFuture;
@@ -96,8 +97,9 @@ public class CacheLIRS<K, V> implements
*
* @param key the evicted item's key
* @param value the evicted item's value or {@code null} if non-resident
+ * @param cause the cause of the eviction
*/
- void evicted(@Nonnull K key, @Nullable V value);
+ void evicted(@Nonnull K key, @Nullable V value, @Nonnull RemovalCause cause);
}
/**
@@ -202,17 +204,17 @@ public class CacheLIRS<K, V> implements
Segment<K, V> old = segments[index];
segments[index] = s;
if (evicted != null && old != null && old != s) {
- old.evictedAll();
+ old.evictedAll(RemovalCause.EXPLICIT);
}
}
- void evicted(Entry<K, V> entry) {
+ void evicted(Entry<K, V> entry, RemovalCause cause) {
if (evicted == null) {
return;
}
K key = entry.key;
if (key != null) {
- evicted.evicted(key, entry.value);
+ evicted.evicted(key, entry.value, cause);
}
}
@@ -384,7 +386,7 @@ public class CacheLIRS<K, V> implements
@Override
public void invalidate(Object key) {
int hash = getHash(key);
- getSegment(hash).invalidate(key, hash);
+ getSegment(hash).invalidate(key, hash, RemovalCause.EXPLICIT);
}
/**
@@ -618,7 +620,7 @@ public class CacheLIRS<K, V> implements
for (Segment<K, V> s : segments) {
synchronized (s) {
if (evicted != null) {
- s.evictedAll();
+ s.evictedAll(RemovalCause.EXPLICIT);
}
s.clear();
}
@@ -775,19 +777,19 @@ public class CacheLIRS<K, V> implements
clear();
}
- public void evictedAll() {
+ public void evictedAll(RemovalCause cause) {
for (Entry<K, V> e = stack.stackNext; e != stack; e = e.stackNext) {
if (e.value != null) {
- cache.evicted(e);
+ cache.evicted(e, cause);
}
}
for (Entry<K, V> e = queue.queueNext; e != queue; e = e.queueNext) {
if (e.stackNext == null) {
- cache.evicted(e);
+ cache.evicted(e, cause);
}
}
for (Entry<K, V> e = queue2.queueNext; e != queue2; e = e.queueNext) {
- cache.evicted(e);
+ cache.evicted(e, cause);
}
}
@@ -1043,7 +1045,7 @@ public class CacheLIRS<K, V> implements
synchronized boolean remove(Object key, int hash, Object value) {
V old = get(key, hash);
if (old != null && old.equals(value)) {
- invalidate(key, hash);
+ invalidate(key, hash, RemovalCause.EXPLICIT);
return true;
}
return false;
@@ -1052,7 +1054,7 @@ public class CacheLIRS<K, V> implements
synchronized V remove(Object key, int hash) {
V old = get(key, hash);
// even if old is null, there might still be a cold entry
- invalidate(key, hash);
+ invalidate(key, hash, RemovalCause.EXPLICIT);
return old;
}
@@ -1112,7 +1114,7 @@ public class CacheLIRS<K, V> implements
old = null;
} else {
old = e.value;
- invalidate(key, hash);
+ invalidate(key, hash, RemovalCause.REPLACED);
}
e = new Entry<K, V>();
e.key = key;
@@ -1141,7 +1143,7 @@ public class CacheLIRS<K, V> implements
* @param key the key (may not be null)
* @param hash the hash
*/
- synchronized void invalidate(Object key, int hash) {
+ synchronized void invalidate(Object key, int hash, RemovalCause cause) {
Entry<K, V>[] array = entries;
int mask = array.length - 1;
int index = hash & mask;
@@ -1181,7 +1183,7 @@ public class CacheLIRS<K, V> implements
removeFromQueue(e);
}
pruneStack();
- cache.evicted(e);
+ cache.evicted(e, cause);
}
/**
@@ -1209,7 +1211,7 @@ public class CacheLIRS<K, V> implements
usedMemory -= e.memory;
evictionCount++;
removeFromQueue(e);
- cache.evicted(e);
+ cache.evicted(e, RemovalCause.SIZE);
e.value = null;
e.memory = 0;
addToQueue(queue2, e);
@@ -1217,7 +1219,7 @@ public class CacheLIRS<K, V> implements
while (queue2Size + queue2Size > stackSize) {
e = queue2.queuePrev;
int hash = getHash(e.key);
- invalidate(e.key, hash);
+ invalidate(e.key, hash, RemovalCause.SIZE);
}
}
}
Modified: jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java?rev=1755491&r1=1755490&r2=1755491&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java Mon Aug 8 10:35:39 2016
@@ -26,9 +26,11 @@ import static org.junit.Assert.assertNul
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
@@ -40,6 +42,7 @@ import org.apache.jackrabbit.oak.cache.C
import org.junit.Test;
import com.google.common.cache.CacheLoader;
+import com.google.common.cache.RemovalCause;
import com.google.common.cache.Weigher;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
@@ -693,12 +696,13 @@ public class CacheTest {
.maximumSize(100)
.evictionCallback(new EvictionCallback<String, Integer>() {
@Override
- public void evicted(String key, Integer value) {
+ public void evicted(String key, Integer value, RemovalCause cause) {
evictedKeys.add(key);
if (value != null) {
assertEquals(key, valueOf(value));
evictedValues.add(value);
}
+ assertTrue(cause == RemovalCause.SIZE || cause == RemovalCause.EXPLICIT);
}
})
.build();
@@ -718,6 +722,69 @@ public class CacheTest {
}
@Test
+ public void evictionCallbackCause() {
+ final Map<String, RemovalCause> causes = new HashMap<String, RemovalCause>();
+
+ CacheLIRS<String, Integer> cache = CacheLIRS.<String, Integer> newBuilder().maximumSize(100)
+ .evictionCallback(new EvictionCallback<String, Integer>() {
+ @Override
+ public void evicted(String key, Integer value, RemovalCause cause) {
+ if (key.startsWith("ignore-")) {
+ return;
+ }
+ causes.put(key, cause);
+ }
+ }).build();
+
+ cache.put("k1", 1);
+ cache.remove("k1");
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k1"));
+
+ cache.put("k6", 1);
+ cache.remove("k6", 1);
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k6"));
+
+ cache.put("k2", 1);
+ cache.invalidate("k2");
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k2"));
+
+ cache.put("k3", 1);
+ cache.invalidateAll();
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k3"));
+
+ cache.put("k4", 1);
+ cache.put("k5", 1);
+ cache.invalidateAll(Arrays.asList("k4", "k5"));
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k4"));
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k5"));
+
+ cache.put("k7", 1);
+ cache.clear();
+ assertEquals(RemovalCause.EXPLICIT, causes.remove("k7"));
+
+ cache.put("k8", 1);
+ cache.put("k8", 2);
+ assertEquals(RemovalCause.REPLACED, causes.remove("k8"));
+
+ for (int i = 0; i < 50; i++) {
+ cache.put("kk" + i, 1);
+ }
+ for (int i = 0; i < 200; i++) {
+ cache.put("ignore-" + i, Integer.MAX_VALUE);
+ }
+
+ int checkedCount = 0;
+ for (int i = 0; i < 50; i++) {
+ String key = "kk" + i;
+ if (!cache.containsKey(key)) {
+ assertEquals("Callback hasn't been called for " + key, RemovalCause.SIZE, causes.get(key));
+ checkedCount++;
+ }
+ }
+ assertTrue(checkedCount > 10);
+ }
+
+ @Test
public void evictionCallbackRandomized() throws ExecutionException {
final HashMap<Integer, Integer> evictedMap = new HashMap<Integer, Integer>();
final HashSet<Integer> evictedNonResidentSet = new HashSet<Integer>();
@@ -725,7 +792,7 @@ public class CacheTest {
.maximumSize(10)
.evictionCallback(new EvictionCallback<Integer, Integer>() {
@Override
- public void evicted(Integer key, Integer value) {
+ public void evicted(Integer key, Integer value, RemovalCause cause) {
if (value == null) {
assertTrue(evictedNonResidentSet.add(key));
} else {