diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/MultiGenerationMap.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/MultiGenerationMap.java index ef32eca..bf4af08 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/MultiGenerationMap.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/MultiGenerationMap.java @@ -55,15 +55,22 @@ public class MultiGenerationMap implements Map { @SuppressWarnings("unchecked") @Override public V get(Object key) { + ValueWithGenerationInfo value = readValue(key); + if (value == null) { + return null; + } else if (!value.isCurrentGeneration()) { + put((K) key, value.value); + } + return value.getValue(); + } + + ValueWithGenerationInfo readValue(Object key) { for (int generation : read.descendingKeySet()) { CacheMap m = read.get(generation); if (m != null) { V value = m.get(key); if (value != null) { - if (m != write) { - put((K) key, value); - } - return value; + return new ValueWithGenerationInfo(value, m == write); } } } @@ -128,4 +135,23 @@ public class MultiGenerationMap implements Map { throw new UnsupportedOperationException(); } + static class ValueWithGenerationInfo { + + private final V value; + + private final boolean isCurrentGeneration; + + private ValueWithGenerationInfo(V value, boolean isCurrentGeneration) { + this.value = value; + this.isCurrentGeneration = isCurrentGeneration; + } + + V getValue() { + return value; + } + + boolean isCurrentGeneration() { + return isCurrentGeneration; + } + } } diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCache.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCache.java index 6814b3c..615edca 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCache.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCache.java @@ -34,8 +34,6 @@ import java.util.concurrent.ExecutionException; import javax.annotation.Nullable; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore; import org.apache.jackrabbit.oak.plugins.document.DocumentStore; import org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCache.GenerationCache; @@ -129,13 +127,40 @@ class NodeCache implements Cache, GenerationCache, EvictionListener< } private V readIfPresent(K key) { + return async ? asyncReadIfPresent(key) : syncReadIfPresent(key); + } + + private V syncReadIfPresent(K key) { cache.switchGenerationIfNeeded(); TimerStats.Context ctx = stats.startReadTimer(); V v = map.get(key); ctx.stop(); + if (v != null) { + memCacheMetadata.putFromPersistenceAndIncrement(key); + } return v; } + private V asyncReadIfPresent(K key) { + TimerStats.Context ctx = stats.startReadTimer(); + try { + MultiGenerationMap.ValueWithGenerationInfo v = map.readValue(key); + if (v == null) { + return null; + } + if (v.isCurrentGeneration() && !cache.needSwitch()) { + // don't persist again on eviction + memCacheMetadata.putFromPersistenceAndIncrement(key); + } else { + // persist again during eviction + memCacheMetadata.increment(key); + } + return v.getValue(); + } finally { + ctx.stop(); + } + } + private void broadcast(final K key, final V value) { cache.broadcast(type, new Function() { @Override @@ -184,9 +209,9 @@ class NodeCache implements Cache, GenerationCache, EvictionListener< } stats.markRequest(); + // it takes care of updating memCacheMetadata value = readIfPresent((K) key); if (value != null) { - memCacheMetadata.putFromPersistenceAndIncrement((K) key); memCache.put((K) key, value); stats.markHit(); } diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/PersistentCache.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/PersistentCache.java index 9b04dea..3289b2a 100644 --- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/PersistentCache.java +++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/PersistentCache.java @@ -493,7 +493,7 @@ public class PersistentCache implements Broadcaster.Listener { } } - private boolean needSwitch() { + boolean needSwitch() { long size = writeStore.getFileSize(); if (size / 1024 / 1024 <= maxSizeMB) { return false;