Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java (revision 8793e58a8be25038660596feb0b5dcef1739e954) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java (revision e647f13a9b4c1db6cc1f2553ac348c67ce5ca747) @@ -16,18 +16,17 @@ */ 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 java.security.SecureRandom; -import java.util.LinkedList; import java.util.Queue; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; +import org.apache.jackrabbit.oak.cache.CacheLIRS; import org.apache.jackrabbit.oak.plugins.blob.ReferenceCollector; import org.apache.jackrabbit.oak.plugins.segment.compaction.CompactionStrategy; import org.slf4j.Logger; @@ -88,12 +87,12 @@ */ private final SegmentIdTable[] tables = new SegmentIdTable[32]; - private final LinkedList segments = newLinkedList(); - private long currentSize; private final StringCache stringCache; + private final CacheLIRS segmentCache; + public SegmentTracker(SegmentStore store, int cacheSizeMB, SegmentVersion version) { for (int i = 0; i < tables.length; i++) { @@ -106,6 +105,10 @@ this.compactionMap = new AtomicReference( CompactionMap.EMPTY); stringCache = new StringCache((int) Math.min(Integer.MAX_VALUE, cacheSize)); + segmentCache = new CacheLIRS.Builder() + .maximumSize((int) Math.min(Integer.MAX_VALUE, cacheSize)) + .averageWeight(Segment.MAX_SEGMENT_SIZE/2) + .build(); } public SegmentTracker(SegmentStore store, SegmentVersion version) { @@ -128,7 +131,7 @@ * Clear the segment cache */ public synchronized void clearCache() { - segments.clear(); + segmentCache.invalidateAll(); stringCache.clear(); currentSize = 0; } @@ -154,34 +157,9 @@ // 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); - } - } + Segment previous = segmentCache.put(id, segment, segment.size()); + if (previous != null) { + previous.getSegmentId().setSegment(null); } }