Author: mduerig
Date: Wed Jul 27 08:52:43 2016
New Revision: 1754228
URL: http://svn.apache.org/viewvc?rev=1754228&view=rev
Log:
OAK-4277: Finalise de-duplication caches
CacheStats MBean for node deduplication cache
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/NodeCache.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/WriterCacheManager.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCompactionIT.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/NodeCache.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/NodeCache.java?rev=1754228&r1=1754227&r2=1754228&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/NodeCache.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/NodeCache.java
Wed Jul 27 08:52:43 2016
@@ -32,20 +32,37 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import com.google.common.base.Supplier;
+import com.google.common.cache.CacheStats;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// FIXME OAK-4277: Finalise de-duplication caches
-// implement configuration, monitoring and management
+// implement configuration
// add unit tests
// document, nullability
public abstract class NodeCache {
+ private long hitCount;
+ private long missCount;
+ private long loadCount;
+ private long evictionCount;
public abstract void put(String key, RecordId value, int depth);
@CheckForNull
public abstract RecordId get(String key);
+ /**
+ * @return number of mappings
+ */
+ public abstract long size();
+
+ /**
+ * @return access statistics for this cache
+ */
+ public CacheStats getStats() {
+ return new CacheStats(hitCount, missCount, loadCount, 0, 0,
evictionCount);
+ }
+
@Nonnull
public static NodeCache newNodeCache(int capacity, int maxDepth) {
if (capacity <= 0) {
@@ -78,14 +95,22 @@ public abstract class NodeCache {
public synchronized void put(String key, RecordId value, int depth) { }
@Override
- public synchronized RecordId get(String key) { return null; }
+ public synchronized RecordId get(String key) {
+ super.missCount++;
+ return null;
+ }
+
+ @Override
+ public long size() {
+ return 0;
+ }
}
private static class Default extends NodeCache {
private static final Logger LOG =
LoggerFactory.getLogger(Default.class);
private final int capacity;
- private final List<Map<String, RecordId>> nodes;
+ private final List<Map<String, RecordId>> caches;
private int size;
@@ -104,54 +129,61 @@ public abstract class NodeCache {
checkArgument(capacity > 0);
checkArgument(maxDepth > 0);
this.capacity = capacity;
- this.nodes = newArrayList();
+ this.caches = newArrayList();
for (int k = 0; k < maxDepth; k++) {
- nodes.add(new HashMap<String, RecordId>());
+ caches.add(new HashMap<String, RecordId>());
}
}
@Override
public synchronized void put(String key, RecordId value, int depth) {
- // FIXME OAK-4277: Finalise de-duplication caches
- // Validate and optimise the eviction strategy.
- // Nodes with many children should probably get a boost to
- // protecting them from preemptive eviction. Also it might be
- // necessary to implement pinning (e.g. for checkpoints).
while (size >= capacity) {
- int d = nodes.size() - 1;
- int removed = nodes.remove(d).size();
+ int d = caches.size() - 1;
+ int removed = caches.remove(d).size();
size -= removed;
+ super.evictionCount -= removed;
if (removed > 0) {
LOG.info("Evicted cache at depth {} as size {} reached
capacity {}. " +
"New size is {}", d, size + removed, capacity,
size);
}
}
- if (depth < nodes.size()) {
- if (nodes.get(depth).put(key, value) == null) {
+ if (depth < caches.size()) {
+ if (caches.get(depth).put(key, value) == null) {
+ super.loadCount++;
size++;
}
} else {
if (muteDepths.add(depth)) {
LOG.info("Not caching {} -> {} as depth {} reaches or
exceeds the maximum of {}",
- key, value, depth, nodes.size());
+ key, value, depth, caches.size());
}
}
}
@Override
public synchronized RecordId get(String key) {
- for (Map<String, RecordId> map : nodes) {
- if (!map.isEmpty()) {
- RecordId recordId = map.get(key);
+ for (Map<String, RecordId> cache : caches) {
+ if (!cache.isEmpty()) {
+ RecordId recordId = cache.get(key);
if (recordId != null) {
+ super.hitCount++;
return recordId;
}
}
}
+ super.missCount++;
return null;
}
+ @Override
+ public synchronized long size() {
+ long size = 0;
+ for (Map<String, RecordId> cache : caches) {
+ size += cache.size();
+ }
+ return size;
+ }
}
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java?rev=1754228&r1=1754227&r2=1754228&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreService.java
Wed Jul 27 08:52:43 2016
@@ -418,8 +418,7 @@ public class SegmentNodeStoreService ext
whiteboard,
CacheStatsMBean.class,
stringDeduplicationCacheStats,CacheStats.TYPE,
- stringDeduplicationCacheStats.getName()
- ));
+ stringDeduplicationCacheStats.getName()));
}
CacheStatsMBean templateDeduplicationCacheStats =
store.getTemplateDeduplicationCacheStats();
@@ -428,8 +427,16 @@ public class SegmentNodeStoreService ext
whiteboard,
CacheStatsMBean.class,
templateDeduplicationCacheStats,CacheStats.TYPE,
- templateDeduplicationCacheStats.getName()
- ));
+ templateDeduplicationCacheStats.getName()));
+ }
+
+ CacheStatsMBean nodeDeduplicationCacheStats =
store.getNodeDeduplicationCacheStats();
+ if (nodeDeduplicationCacheStats != null) {
+ registrations.add(registerMBean(
+ whiteboard,
+ CacheStatsMBean.class,
+ nodeDeduplicationCacheStats,CacheStats.TYPE,
+ nodeDeduplicationCacheStats.getName()));
}
// Listen for Executor services on the whiteboard
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java?rev=1754228&r1=1754227&r2=1754228&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
Wed Jul 27 08:52:43 2016
@@ -149,6 +149,14 @@ public class SegmentWriter {
}
/**
+ * @return Statistics for the node deduplication cache or {@code null} if
not available.
+ */
+ @CheckForNull
+ public CacheStatsMBean getNodeCacheStats() {
+ return cacheManager.getNodeCacheStats();
+ }
+
+ /**
* Write a map record.
* @param base base map relative to which the {@code changes} are
applied ot
* {@code null} for the empty map.
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/WriterCacheManager.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/WriterCacheManager.java?rev=1754228&r1=1754227&r2=1754228&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/WriterCacheManager.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/WriterCacheManager.java
Wed Jul 27 08:52:43 2016
@@ -40,7 +40,7 @@ import com.google.common.cache.CacheStat
import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
// FIXME OAK-4277: Finalise de-duplication caches
-// implement configuration, monitoring and management
+// implement configuration
/**
* Instances of this class manage the deduplication caches used
* by the {@link SegmentWriter} to avoid writing multiple copies
@@ -102,6 +102,14 @@ public abstract class WriterCacheManager
}
/**
+ * @return statistics for the node cache or {@code null} if not available.
+ */
+ @CheckForNull
+ public CacheStatsMBean getNodeCacheStats() {
+ return null;
+ }
+
+ /**
* This implementation of {@link WriterCacheManager} returns empty caches
* of size 0.
* @see #INSTANCE
@@ -255,18 +263,19 @@ public abstract class WriterCacheManager
@Override
public CacheStatsMBean getStringCacheStats() {
return new RecordCacheStats("String deduplication cache stats",
- accumulateStats(stringCaches),
accumulateSizes(stringCaches));
+ accumulateRecordCacheStats(stringCaches),
accumulateRecordCacheSizes(stringCaches));
}
@CheckForNull
@Override
public CacheStatsMBean getTemplateCacheStats() {
return new RecordCacheStats("Template deduplication cache stats",
- accumulateStats(templateCaches),
accumulateSizes(templateCaches));
+ accumulateRecordCacheStats(templateCaches),
accumulateRecordCacheSizes(templateCaches));
}
@Nonnull
- private static <T> Supplier<CacheStats> accumulateStats(final
Iterable<RecordCache<T>> caches) {
+ private static <T> Supplier<CacheStats> accumulateRecordCacheStats(
+ final Iterable<RecordCache<T>> caches) {
return new Supplier<CacheStats>() {
@Override
public CacheStats get() {
@@ -280,7 +289,8 @@ public abstract class WriterCacheManager
}
@Nonnull
- public static <T> Supplier<Long> accumulateSizes(final
Generations<RecordCache<T>> caches) {
+ public static <T> Supplier<Long> accumulateRecordCacheSizes(
+ final Iterable<RecordCache<T>> caches) {
return new Supplier<Long>() {
@Override
public Long get() {
@@ -289,6 +299,43 @@ public abstract class WriterCacheManager
size += cache.size();
}
return size;
+ }
+ };
+ }
+
+ @CheckForNull
+ @Override
+ public CacheStatsMBean getNodeCacheStats() {
+ return new RecordCacheStats("Node deduplication cache stats",
+ accumulateNodeCacheStats(nodeCaches),
accumulateNodeCacheSizes(nodeCaches));
+ }
+
+ @Nonnull
+ private static <T> Supplier<CacheStats> accumulateNodeCacheStats(
+ final Iterable<NodeCache> caches) {
+ return new Supplier<CacheStats>() {
+ @Override
+ public CacheStats get() {
+ CacheStats stats = new CacheStats(0, 0, 0, 0, 0, 0);
+ for (NodeCache cache : caches) {
+ stats = stats.plus(cache.getStats());
+ }
+ return stats;
+ }
+ };
+ }
+
+ @Nonnull
+ public static <T> Supplier<Long> accumulateNodeCacheSizes(
+ final Iterable<NodeCache> caches) {
+ return new Supplier<Long>() {
+ @Override
+ public Long get() {
+ long size = 0;
+ for (NodeCache cache : caches) {
+ size += cache.size();
+ }
+ return size;
}
};
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1754228&r1=1754227&r2=1754228&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
Wed Jul 27 08:52:43 2016
@@ -424,6 +424,11 @@ public class FileStore implements Segmen
return segmentWriter.getTemplateCacheStats();
}
+ @CheckForNull
+ public CacheStatsMBean getNodeDeduplicationCacheStats() {
+ return segmentWriter.getNodeCacheStats();
+ }
+
public void maybeCompact(boolean cleanup) throws IOException {
gcListener.info("TarMK GC #{}: started", GC_COUNT.incrementAndGet());
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCompactionIT.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCompactionIT.java?rev=1754228&r1=1754227&r2=1754228&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCompactionIT.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentCompactionIT.java
Wed Jul 27 08:52:43 2016
@@ -260,6 +260,10 @@ public class SegmentCompactionIT {
assertNotNull(templateDeduplicationCacheStats);
registrations.add(registerMBean(templateDeduplicationCacheStats,
new ObjectName("IT:TYPE=" +
templateDeduplicationCacheStats.getName())));
+ CacheStatsMBean nodeDeduplicationCacheStats =
fileStore.getNodeDeduplicationCacheStats();
+ assertNotNull(nodeDeduplicationCacheStats);
+ registrations.add(registerMBean(nodeDeduplicationCacheStats,
+ new ObjectName("IT:TYPE=" +
nodeDeduplicationCacheStats.getName())));
mBeanRegistration = new CompositeRegistration(registrations);
}