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 2015/07/15 15:59:00 UTC
svn commit: r1691219 -
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
Author: mduerig
Date: Wed Jul 15 13:59:00 2015
New Revision: 1691219
URL: http://svn.apache.org/r1691219
Log:
OAK-3055: Improve segment cache in SegmentTracker
Replace ad-hoc segment cache with LIRS cache
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java?rev=1691219&r1=1691218&r2=1691219&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java Wed Jul 15 13:59:00 2015
@@ -16,13 +16,11 @@
*/
package org.apache.jackrabbit.oak.plugins.segment;
-import static com.google.common.collect.Lists.newLinkedList;
import static com.google.common.collect.Queues.newArrayDeque;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.Boolean.getBoolean;
import java.security.SecureRandom;
-import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@@ -30,6 +28,8 @@ import java.util.concurrent.atomic.Atomi
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import org.apache.jackrabbit.oak.cache.CacheLIRS;
+import org.apache.jackrabbit.oak.cache.CacheLIRS.EvictionCallback;
import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.plugins.blob.ReferenceCollector;
import org.apache.jackrabbit.oak.plugins.segment.compaction.CompactionStrategy;
@@ -84,8 +84,6 @@ public class SegmentTracker {
*/
private final AtomicReference<CompactionMap> compactionMap;
- private final long cacheSize;
-
/**
* Hash table of weak references to segment identifiers that are
* currently being accessed. The size of the table is always a power
@@ -97,15 +95,16 @@ public class SegmentTracker {
*/
private final SegmentIdTable[] tables = new SegmentIdTable[32];
- private final LinkedList<Segment> segments = newLinkedList();
-
- private long currentSize;
-
/**
* Cache for string records
*/
private final StringCache stringCache;
+ /**
+ * Cache of recently accessed segments
+ */
+ private final CacheLIRS<SegmentId, Segment> segmentCache;
+
public SegmentTracker(SegmentStore store, int cacheSizeMB,
SegmentVersion version) {
for (int i = 0; i < tables.length; i++) {
@@ -114,17 +113,26 @@ public class SegmentTracker {
this.store = store;
this.writer = new SegmentWriter(store, this, version);
- this.cacheSize = cacheSizeMB * MB;
this.compactionMap = new AtomicReference<CompactionMap>(
CompactionMap.EMPTY);
StringCache c;
if (DISABLE_STRING_CACHE) {
c = null;
} else {
- int stringCacheSize = (int) Math.min(Integer.MAX_VALUE, cacheSize);
+ int stringCacheSize = (int) Math.min(Integer.MAX_VALUE, (long) (cacheSizeMB * MB));
c = new StringCache(stringCacheSize);
}
stringCache = c;
+ segmentCache = CacheLIRS.<SegmentId, Segment>newBuilder()
+ .maximumSize((int) Math.min(Integer.MAX_VALUE, (long) (cacheSizeMB * MB)))
+ .averageWeight(Segment.MAX_SEGMENT_SIZE/2)
+ .evictionCallback(new EvictionCallback<SegmentId, Segment>() {
+ @Override
+ public void evicted(SegmentId segmentId, Segment segment) {
+ segmentId.setSegment(null);
+ }
+ })
+ .build();
}
public SegmentTracker(SegmentStore store, SegmentVersion version) {
@@ -154,11 +162,10 @@ public class SegmentTracker {
* Clear the caches
*/
public synchronized void clearCache() {
- segments.clear();
+ segmentCache.invalidateAll();
if (stringCache != null) {
stringCache.clear();
}
- currentSize = 0;
}
/**
@@ -184,38 +191,8 @@ public class SegmentTracker {
}
void setSegment(SegmentId id, Segment segment) {
- // done before synchronization to allow concurrent segment access
- // while we update the cache below
id.setSegment(segment);
-
- synchronized (this) {
- long size = segment.getCacheSize();
-
- segments.addFirst(segment);
- currentSize += size;
-
- log.debug("Added segment {} to tracker cache ({} bytes)",
- id, size);
-
- // TODO possibly this cache could be improved
- while (currentSize > cacheSize && segments.size() > 1) {
- Segment last = segments.removeLast();
- SegmentId lastId = last.getSegmentId();
- if (last.accessed()) {
- segments.addFirst(last);
- log.debug("Segment {} was recently used, keeping in cache",
- lastId);
- } else {
- long lastSize = last.getCacheSize();
-
- lastId.setSegment(null);
- currentSize -= lastSize;
-
- log.debug("Removed segment {} from tracker cache ({} bytes)",
- lastId, lastSize);
- }
- }
- }
+ segmentCache.put(id, segment, segment.size());
}
public void setCompactionMap(PartialCompactionMap map) {