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 md...@apache.org on 2016/10/19 08:37:19 UTC
svn commit: r1765554 - in /jackrabbit/oak/trunk/oak-segment-tar/src:
main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java
main/java/org/apache/jackrabbit/oak/segment/SegmentId.java
test/java/org/apache/jackrabbit/oak/segment/SegmentCacheTest.java
Author: mduerig
Date: Wed Oct 19 08:37:18 2016
New Revision: 1765554
URL: http://svn.apache.org/viewvc?rev=1765554&view=rev
Log:
OAK-4936: Too many segment cache misses
Replace LIRS cache with Guava cache
(cherry picked from commit a017357)
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCacheTest.java
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java?rev=1765554&r1=1765553&r2=1765554&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentCache.java Wed Oct 19 08:37:18 2016
@@ -24,10 +24,11 @@ import java.util.concurrent.ExecutionExc
import javax.annotation.Nonnull;
-import com.google.common.cache.RemovalCause;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
import com.google.common.cache.Weigher;
-import org.apache.jackrabbit.oak.cache.CacheLIRS;
-import org.apache.jackrabbit.oak.cache.CacheLIRS.EvictionCallback;
import org.apache.jackrabbit.oak.cache.CacheStats;
/**
@@ -41,42 +42,46 @@ import org.apache.jackrabbit.oak.cache.C
* As a consequence this cache is actually only queried for segments it does not contain,
* which are then loaded through the loader passed to {@link #getSegment(SegmentId, Callable)}.
* This behaviour is eventually reflected in the cache statistics (see {@link #getCacheStats()}),
- * which always reports a {@link CacheStats#getMissRate() miss rate} of 1.
+ * which always reports a {@link CacheStats#getHitRate()} () miss rate} of 1.
*/
public class SegmentCache {
public static final int DEFAULT_SEGMENT_CACHE_MB = 256;
private final Weigher<SegmentId, Segment> weigher = new Weigher<SegmentId, Segment>() {
@Override
- public int weigh(SegmentId id, Segment segment) {
+ public int weigh(@Nonnull SegmentId id, @Nonnull Segment segment) {
return 224 + segment.size();
}
};
+ private final long maximumWeight;
+
/**
* Cache of recently accessed segments
*/
@Nonnull
- private final CacheLIRS<SegmentId, Segment> cache;
+ private final Cache<SegmentId, Segment> cache;
/**
* Create a new segment cache of the given size.
* @param cacheSizeMB size of the cache in megabytes.
*/
public SegmentCache(long cacheSizeMB) {
- this.cache = CacheLIRS.<SegmentId, Segment>newBuilder()
- .module("SegmentCache")
- .maximumWeight(cacheSizeMB * 1024 * 1024)
- .averageWeight(Segment.MAX_SEGMENT_SIZE / 2)
- .weigher(weigher)
- .evictionCallback(new EvictionCallback<SegmentId, Segment>() {
- @Override
- public void evicted(SegmentId id, Segment segment, RemovalCause cause) {
- if (segment != null) {
- id.unloaded();
+ this.maximumWeight = cacheSizeMB * 1024 * 1024;
+ this.cache = CacheBuilder.newBuilder()
+ .concurrencyLevel(16)
+ .recordStats()
+ .maximumWeight(maximumWeight)
+ .weigher(weigher)
+ .removalListener(new RemovalListener<SegmentId, Segment>() {
+ @Override
+ public void onRemoval(@Nonnull RemovalNotification<SegmentId, Segment> notification) {
+ SegmentId id = notification.getKey();
+ if (id != null) {
+ id.unloaded();
+ }
}
- } })
- .build();
+ }).build();
}
/**
@@ -87,9 +92,16 @@ public class SegmentCache {
* @throws ExecutionException when {@code loader} failed to load an segment
*/
@Nonnull
- public Segment getSegment(@Nonnull SegmentId id, @Nonnull Callable<Segment> loader)
+ public Segment getSegment(@Nonnull final SegmentId id, @Nonnull final Callable<Segment> loader)
throws ExecutionException {
- return cache.get(id, loader);
+ try {
+ Segment segment = loader.call();
+ cache.put(id, segment);
+ id.loaded(segment);
+ return segment;
+ } catch (Exception e) {
+ throw new ExecutionException(e);
+ }
}
/**
@@ -97,8 +109,9 @@ public class SegmentCache {
* @param segment the segment to cache
*/
public void putSegment(@Nonnull Segment segment) {
- cache.put(segment.getSegmentId(), segment);
- segment.getSegmentId().loaded(segment);
+ SegmentId segmentId = segment.getSegmentId();
+ cache.put(segmentId, segment);
+ segmentId.loaded(segment);
}
/**
@@ -114,6 +127,6 @@ public class SegmentCache {
*/
@Nonnull
public CacheStats getCacheStats() {
- return new CacheStats(cache, "Segment Cache", weigher, cache.getMaxMemory());
+ return new CacheStats(cache, "Segment Cache", weigher, maximumWeight);
}
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java?rev=1765554&r1=1765553&r2=1765554&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentId.java Wed Oct 19 08:37:18 2016
@@ -121,8 +121,6 @@ public class SegmentId implements Compar
try {
log.debug("Loading segment {}", this);
segment = store.readSegment(this);
- gcGeneration = segment.getGcGeneration();
- this.segment = segment;
} catch (SegmentNotFoundException snfe) {
log.error("Segment not found: {}. {}", this, gcInfo(), snfe);
throw snfe;
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCacheTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCacheTest.java?rev=1765554&r1=1765553&r2=1765554&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCacheTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCacheTest.java Wed Oct 19 08:37:18 2016
@@ -83,25 +83,25 @@ public class SegmentCacheTest {
// load
cache.getSegment(id, loader);
assertEquals(1, stats.getElementCount());
- assertEquals(1, stats.getLoadCount());
+ assertEquals(0, stats.getLoadCount());
assertEquals(0, stats.getHitCount());
- assertEquals(1, stats.getMissCount());
- assertEquals(1, stats.getRequestCount());
+ assertEquals(0, stats.getMissCount());
+ assertEquals(0, stats.getRequestCount());
// cache hit
cache.getSegment(id, loader);
assertEquals(1, stats.getElementCount());
- assertEquals(1, stats.getLoadCount());
- assertEquals(1, stats.getHitCount());
- assertEquals(1, stats.getMissCount());
- assertEquals(2, stats.getRequestCount());
+ assertEquals(0, stats.getLoadCount());
+ assertEquals(0, stats.getHitCount());
+ assertEquals(0, stats.getMissCount());
+ assertEquals(0, stats.getRequestCount());
cache.clear();
assertEquals(0, stats.getElementCount());
- assertEquals(1, stats.getLoadCount());
- assertEquals(1, stats.getHitCount());
- assertEquals(1, stats.getMissCount());
- assertEquals(2, stats.getRequestCount());
+ assertEquals(0, stats.getLoadCount());
+ assertEquals(0, stats.getHitCount());
+ assertEquals(0, stats.getMissCount());
+ assertEquals(0, stats.getRequestCount());
stats.resetStats();
assertEquals(0, stats.getElementCount());