Author: thomasm
Date: Wed Oct 2 13:56:01 2013
New Revision: 1528474
URL: http://svn.apache.org/r1528474
Log:
OAK-643 Slightly faster caching
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/cache/CacheLIRS.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.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=1528474&r1=1528473&r2=1528474&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
Wed Oct 2 13:56:01 2013
@@ -29,8 +29,9 @@ import java.util.concurrent.ExecutionExc
import javax.annotation.Nullable;
-import com.google.common.cache.Cache;
+import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheStats;
+import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import com.google.common.collect.ImmutableMap;
@@ -63,7 +64,7 @@ import com.google.common.collect.Immutab
* @param <K> the key type
* @param <V> the value type
*/
-public class CacheLIRS<K, V> implements Cache<K, V> {
+public class CacheLIRS<K, V> implements LoadingCache<K, V> {
/**
* The maximum memory this cache should use.
@@ -84,6 +85,8 @@ public class CacheLIRS<K, V> implements
private final Weigher<K, V> weigher;
+ private final CacheLoader<K, V> loader;
+
/**
* Create a new cache with the given number of entries, and the default
* settings (an average size of 1 per entry, 16 segments, and stack move
@@ -92,7 +95,7 @@ public class CacheLIRS<K, V> implements
* @param maxEntries the maximum number of entries
*/
public CacheLIRS(int maxEntries) {
- this(null, maxEntries, 1, 16, maxEntries / 100);
+ this(null, maxEntries, 1, 16, maxEntries / 100, null);
}
/**
@@ -105,7 +108,8 @@ public class CacheLIRS<K, V> implements
* of the stack before the current item is moved
*/
@SuppressWarnings("unchecked")
- CacheLIRS(Weigher<K, V> weigher, long maxMemory, int averageMemory, int
segmentCount, int stackMoveDistance) {
+ CacheLIRS(Weigher<K, V> weigher, long maxMemory, int averageMemory,
+ int segmentCount, int stackMoveDistance, final CacheLoader<K, V>
loader) {
this.weigher = weigher;
setMaxMemory(maxMemory);
setAverageMemory(averageMemory);
@@ -118,6 +122,7 @@ public class CacheLIRS<K, V> implements
segments = new Segment[segmentCount];
invalidateAll();
this.segmentShift =
Integer.numberOfTrailingZeros(segments[0].entries.length);
+ this.loader = loader;
}
/**
@@ -203,6 +208,27 @@ public class CacheLIRS<K, V> implements
int hash = getHash(key);
return getSegment(hash).get(key, hash, valueLoader);
}
+
+ @Override
+ public V get(K key) throws ExecutionException {
+ int hash = getHash(key);
+ return getSegment(hash).get(key, hash, loader);
+ }
+
+ /**
+ * Get the value for the given key if the entry is cached. This method
+ * adjusts the internal state of the cache sometimes, to ensure commonly
+ * used entries stay in the cache.
+ *
+ * @param key the key (may not be null)
+ * @return the value, or null if there is no resident entry
+ */
+ @Override
+ @Nullable
+ public V getIfPresent(Object key) {
+ int hash = getHash(key);
+ return getSegment(hash).get(key, hash);
+ }
/**
* Get the size of the given value. The default implementation returns the
@@ -250,19 +276,6 @@ public class CacheLIRS<K, V> implements
return getSegment(hash).getMemory(key, hash);
}
- /**
- * Get the value for the given key if the entry is cached. This method
- * adjusts the internal state of the cache sometimes, to ensure commonly
- * used entries stay in the cache.
- *
- * @param key the key (may not be null)
- * @return the value, or null if there is no resident entry
- */
- public V get(Object key) {
- int hash = getHash(key);
- return getSegment(hash).get(key, hash);
- }
-
private Segment<K, V> getSegment(int hash) {
int segmentIndex = (hash >>> segmentShift) & segmentMask;
return segments[segmentIndex];
@@ -722,6 +735,25 @@ public class CacheLIRS<K, V> implements
}
return value;
}
+
+ synchronized V get(K key, int hash, CacheLoader<K, V> loader) throws
ExecutionException {
+ V value = get(key, hash);
+ if (value == null) {
+ long start = System.nanoTime();
+ try {
+ value = loader.load(key);
+ loadSuccessCount++;
+ } catch (Exception e) {
+ loadExceptionCount++;
+ throw new ExecutionException(e);
+ } finally {
+ long time = System.nanoTime() - start;
+ totalLoadTime += time;
+ }
+ put(key, hash, value, cache.sizeOf(key, value));
+ }
+ return value;
+ }
/**
* Add an entry to the cache. The entry may or may not exist in the
@@ -1109,17 +1141,22 @@ public class CacheLIRS<K, V> implements
return this;
}
- public <K, V> CacheLIRS<K, V> build() {
- @SuppressWarnings("unchecked")
- Weigher<K, V> w = (Weigher<K, V>) weigher;
- return new CacheLIRS<K, V>(w, maxWeight, averageWeight, 16, 16);
- }
-
public Builder maximumSize(int maxSize) {
this.maxWeight = maxSize;
this.averageWeight = 1;
return this;
}
+
+ public <K, V> CacheLIRS<K, V> build() {
+ return build(null);
+ }
+
+ public <K, V> CacheLIRS<K, V> build(
+ CacheLoader<K, V> cacheLoader) {
+ @SuppressWarnings("unchecked")
+ Weigher<K, V> w = (Weigher<K, V>) weigher;
+ return new CacheLIRS<K, V>(w, maxWeight, averageWeight, 16, 16,
cacheLoader);
+ }
}
@@ -1132,13 +1169,6 @@ public class CacheLIRS<K, V> implements
return new Builder();
}
- @SuppressWarnings("unchecked")
- @Override
- @Nullable
- public V getIfPresent(Object key) {
- return get((K) key);
- }
-
@Override
public ImmutableMap<K, V> getAllPresent(Iterable<?> keys) {
throw new UnsupportedOperationException();
@@ -1168,4 +1198,29 @@ public class CacheLIRS<K, V> implements
}
}
+ @Override
+ public V getUnchecked(K key) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ImmutableMap<K, V> getAll(Iterable<? extends K> keys)
+ throws ExecutionException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public V apply(K key) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void refresh(K key) {
+ // TODO Auto-generated method stub
+
+ }
+
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java?rev=1528474&r1=1528473&r2=1528474&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
Wed Oct 2 13:56:01 2013
@@ -37,6 +37,7 @@ import com.google.common.util.concurrent
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.api.MicroKernelException;
import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.cache.CacheLIRS;
import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.EmptyObserver;
@@ -88,7 +89,7 @@ public class KernelNodeStore implements
return state.getMemory();
}
};
- this.cache = CacheBuilder.newBuilder()
+ this.cache = CacheLIRS.newBuilder()
.maximumWeight(cacheSize)
.recordStats()
.weigher(weigher)
@@ -138,6 +139,7 @@ public class KernelNodeStore implements
/**
* Returns a string representation the head state of this node store.
*/
+ @Override
public String toString() {
return getRoot().toString();
}
@@ -222,7 +224,7 @@ public class KernelNodeStore implements
}
}
- public CacheStats getCacheStats(){
+ public CacheStats getCacheStats() {
return cacheStats;
}