Author: mreutegg
Date: Tue Feb 16 09:38:57 2016
New Revision: 1730645
URL: http://svn.apache.org/viewvc?rev=1730645&view=rev
Log:
OAK-3997: Include eviction cause to the LIRS removal callback
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
jackrabbit/oak/trunk/oak-parent/pom.xml
jackrabbit/oak/trunk/oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java?rev=1730645&r1=1730644&r2=1730645&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
Tue Feb 16 09:38:57 2016
@@ -35,6 +35,7 @@ import javax.annotation.Nullable;
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;
@@ -98,8 +99,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);
}
private final int cacheId = NEXT_CACHE_ID.getAndIncrement();
@@ -208,17 +210,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);
}
}
@@ -390,7 +392,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);
}
/**
@@ -624,7 +626,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();
}
@@ -781,19 +783,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);
}
}
@@ -1063,7 +1065,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;
@@ -1072,7 +1074,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;
}
@@ -1132,7 +1134,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;
@@ -1161,7 +1163,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;
@@ -1201,7 +1203,7 @@ public class CacheLIRS<K, V> implements
removeFromQueue(e);
}
pruneStack();
- cache.evicted(e);
+ cache.evicted(e, cause);
}
/**
@@ -1229,7 +1231,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);
@@ -1237,7 +1239,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/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java?rev=1730645&r1=1730644&r2=1730645&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/cache/CacheTest.java
Tue Feb 16 09:38:57 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 {
Modified: jackrabbit/oak/trunk/oak-parent/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-parent/pom.xml?rev=1730645&r1=1730644&r2=1730645&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-parent/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-parent/pom.xml Tue Feb 16 09:38:57 2016
@@ -147,6 +147,7 @@
<failOnError>true</failOnError>
<filters>
<!-- Disable baseline for explicitly NOT managed packages.
See OAK-3842 -->
+ <filter>!org.apache.jackrabbit.oak.cache</filter>
<filter>!org.apache.jackrabbit.oak.commons</filter>
<filter>!org.apache.jackrabbit.oak.commons.benchmark</filter>
<filter>!org.apache.jackrabbit.oak.commons.cache</filter>
Modified:
jackrabbit/oak/trunk/oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java?rev=1730645&r1=1730644&r2=1730645&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
(original)
+++
jackrabbit/oak/trunk/oak-segment/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
Tue Feb 16 09:38:57 2016
@@ -39,6 +39,8 @@ import org.apache.jackrabbit.oak.plugins
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.cache.RemovalCause;
+
/**
* Tracker of references to segment identifiers and segment instances
* that are currently kept in memory.
@@ -143,7 +145,7 @@ public class SegmentTracker {
.averageWeight(Segment.MAX_SEGMENT_SIZE/2)
.evictionCallback(new EvictionCallback<SegmentId, Segment>() {
@Override
- public void evicted(SegmentId segmentId, Segment segment) {
+ public void evicted(SegmentId segmentId, Segment segment,
RemovalCause cause) {
if (segment != null) {
segmentId.setSegment(null);
}