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 2017/06/26 15:56:59 UTC

svn commit: r1799937 - in /jackrabbit/oak/trunk/oak-segment-tar/src: main/java/org/apache/jackrabbit/oak/segment/ main/java/org/apache/jackrabbit/oak/segment/file/ test/java/org/apache/jackrabbit/oak/segment/

Author: mduerig
Date: Mon Jun 26 15:56:59 2017
New Revision: 1799937

URL: http://svn.apache.org/viewvc?rev=1799937&view=rev
Log:
OAK-6395: Refactor monitoring of deduplication caches
Rewire setup of AccessTrackingCache from the outside

Added:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CacheAccessTracker.java
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CacheAccessTrackerTest.java
Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/DefaultSegmentWriter.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/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/WriteCacheManagerTest.java

Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CacheAccessTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CacheAccessTracker.java?rev=1799937&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CacheAccessTracker.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/CacheAccessTracker.java Mon Jun 26 15:56:59 2017
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jackrabbit.oak.segment;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.stats.CounterStats;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.stats.StatsOptions;
+
+/**
+ * {@code Cache} wrapper exposing the number of read accesses and the
+ * number of misses ot the underlying cache via the {@link StatisticsProvider}.
+ */
+public class CacheAccessTracker<K, V> implements Cache<K,V> {
+    private final Cache<K, V> delegate;
+    private final CounterStats accessCount;
+    private final CounterStats missCount;
+
+    /**
+     * Create a new wrapper exposing the access statistics under the given
+     * {@code name} to the passed {@code statisticsProvider}.
+     * @param name                 name under which to expose the access statistics
+     * @param statisticsProvider   statistics provider where the access statistics is recorded to
+     * @param delegate             the underlying, wrapped cache.
+     */
+    public CacheAccessTracker(
+            @Nonnull String name,
+            @Nonnull StatisticsProvider statisticsProvider,
+            @Nonnull Cache<K, V> delegate) {
+        this.delegate = delegate;
+        this.accessCount = statisticsProvider.getCounterStats(
+                name + ".access-count", StatsOptions.DEFAULT);
+        this.missCount = statisticsProvider.getCounterStats(
+                name + ".miss-count", StatsOptions.DEFAULT);
+    }
+
+    @Override
+    public void put(@Nonnull K key, @Nonnull V value) {
+        delegate.put(key, value);
+    }
+
+    @Override
+    public void put(@Nonnull K key, @Nonnull V value, byte cost) {
+        delegate.put(key, value, cost);
+    }
+
+    @CheckForNull
+    @Override
+    public V get(@Nonnull K key) {
+        V v = delegate.get(key);
+        accessCount.inc();
+        if (v == null) {
+            missCount.inc();
+        }
+        return v;
+    }
+}

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/DefaultSegmentWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/DefaultSegmentWriter.java?rev=1799937&r1=1799936&r2=1799937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/DefaultSegmentWriter.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/DefaultSegmentWriter.java Mon Jun 26 15:56:59 2017
@@ -46,7 +46,6 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.segment.MapEntry.newModifiedMapEntry;
 import static org.apache.jackrabbit.oak.segment.MapRecord.BUCKETS_PER_LEVEL;
 import static org.apache.jackrabbit.oak.segment.RecordWriters.newNodeStateWriter;
-import static org.apache.jackrabbit.oak.segment.WriterCacheManager.Operation.COMPACT;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -264,7 +263,7 @@ public class DefaultSegmentWriter implem
                 @Nonnull
                 @Override
                 public RecordId execute(@Nonnull SegmentBufferWriter writer) throws IOException {
-                    return with(writer, true).writeNode(state);
+                    return with(writer).writeNode(state);
                 }
             });
         } catch (SegmentWriteOperation.CancelledWriteException ignore) {
@@ -315,21 +314,16 @@ public class DefaultSegmentWriter implem
         public abstract RecordId execute(@Nonnull SegmentBufferWriter writer) throws IOException;
 
         @Nonnull
-        SegmentWriteOperation with(@Nonnull SegmentBufferWriter writer, boolean compacting) {
+        SegmentWriteOperation with(@Nonnull SegmentBufferWriter writer) {
             checkState(this.writer == null);
             this.writer = writer;
             int generation = writer.getGeneration();
-            this.stringCache = cacheManager.getStringCache(generation, COMPACT);
-            this.templateCache = cacheManager.getTemplateCache(generation, COMPACT);
-            this.nodeCache = cacheManager.getNodeCache(generation, COMPACT);
+            this.stringCache = cacheManager.getStringCache(generation);
+            this.templateCache = cacheManager.getTemplateCache(generation);
+            this.nodeCache = cacheManager.getNodeCache(generation);
             return this;
         }
 
-        @Nonnull
-        SegmentWriteOperation with(@Nonnull SegmentBufferWriter writer) {
-            return with(writer, false);
-        }
-
         private RecordId writeMap(@Nullable MapRecord base,
                 @Nonnull Map<String, RecordId> changes
         )

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=1799937&r1=1799936&r2=1799937&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 Mon Jun 26 15:56:59 2017
@@ -39,9 +39,7 @@ import com.google.common.base.Supplier;
 import com.google.common.cache.CacheStats;
 import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
 import org.apache.jackrabbit.oak.segment.file.PriorityCache;
-import org.apache.jackrabbit.oak.stats.CounterStats;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
-import org.apache.jackrabbit.oak.stats.StatsOptions;
 
 /**
  * Instances of this class manage the deduplication caches used by the {@link
@@ -50,16 +48,6 @@ import org.apache.jackrabbit.oak.stats.S
  * avoids records old generations being reused.
  */
 public abstract class WriterCacheManager {
-    /**
-     * The type of operation a cache acquired through this manager is used for.
-     * This type is used to determine against which monitoring endpoint to report
-     * access statistics.
-     *
-     * @see #getStringCache(int, Operation)
-     * @see #getTemplateCache(int, Operation)
-     * @see #getNodeCache(int, Operation)
-     */
-    public enum Operation {WRITE, COMPACT}
 
     /**
      * Default size of the string cache, used as default for OSGi config.
@@ -68,7 +56,7 @@ public abstract class WriterCacheManager
 
     /**
      * Default size of the string cache.
-     * @see #getStringCache(int, Operation)
+     * @see #getStringCache(int)
      */
     public static final int DEFAULT_STRING_CACHE_SIZE = getInteger(
             "oak.tar.stringsCacheSize", DEFAULT_STRING_CACHE_SIZE_OSGi);
@@ -80,7 +68,7 @@ public abstract class WriterCacheManager
 
     /**
      * Default size of the template cache.
-     * @see #getTemplateCache(int, Operation)
+     * @see #getTemplateCache(int)
      */
     public static final int DEFAULT_TEMPLATE_CACHE_SIZE = getInteger(
             "oak.tar.templatesCacheSize", DEFAULT_TEMPLATE_CACHE_SIZE_OSGi);
@@ -93,7 +81,7 @@ public abstract class WriterCacheManager
 
     /**
      * Default size of the node deduplication cache.
-     * @see #getNodeCache(int, Operation)
+     * @see #getNodeCache(int)
      */
     public static final int DEFAULT_NODE_CACHE_SIZE = getInteger(
             "oak.tar.nodeCacheSize", DEFAULT_NODE_CACHE_SIZE_OSGi);
@@ -102,20 +90,35 @@ public abstract class WriterCacheManager
      * @return  cache for string records of the given {@code generation} and {@code operation}.
      */
     @Nonnull
-    public abstract Cache<String, RecordId> getStringCache(int generation, Operation operation);
+    public abstract Cache<String, RecordId> getStringCache(int generation);
 
     /**
      * @param generation
      * @return  cache for template records of the given {@code generation} and {@code operation}.
      */
     @Nonnull
-    public abstract Cache<Template, RecordId> getTemplateCache(int generation, Operation operation);
+    public abstract Cache<Template, RecordId> getTemplateCache(int generation);
 
     /**
      * @return  cache for node records of the given {@code generation} and {@code operation}.
      */
     @Nonnull
-    public abstract Cache<String, RecordId> getNodeCache(int generation, Operation operation);
+    public abstract Cache<String, RecordId> getNodeCache(int generation);
+
+    /**
+     * Enable access statistics for this cache. The instance returned by from
+     * this method delegates back to this instance and adds access statistics
+     * via the passed {@code statisticsProvider}.
+     * @param name
+     * @param statisticsProvider
+     * @return  an instance of this cache with access statistics enabled.
+     */
+    @Nonnull
+    public WriterCacheManager withAccessTracking(
+            @Nonnull String name,
+            @Nonnull StatisticsProvider statisticsProvider) {
+        return new AccessTrackingCacheManager(checkNotNull(name), checkNotNull(statisticsProvider), this);
+    }
 
     /**
      * @return  statistics for the string cache or {@code null} if not available.
@@ -171,7 +174,7 @@ public abstract class WriterCacheManager
          */
         @Nonnull
         @Override
-        public RecordCache<String> getStringCache(int generation, Operation operation) {
+        public RecordCache<String> getStringCache(int generation) {
             return stringCache;
         }
 
@@ -180,7 +183,7 @@ public abstract class WriterCacheManager
          */
         @Nonnull
         @Override
-        public RecordCache<Template> getTemplateCache(int generation, Operation operation) {
+        public RecordCache<Template> getTemplateCache(int generation) {
             return templateCache;
         }
 
@@ -189,7 +192,7 @@ public abstract class WriterCacheManager
          */
         @Nonnull
         @Override
-        public Cache<String, RecordId> getNodeCache(int generation, Operation operation) {
+        public Cache<String, RecordId> getNodeCache(int generation) {
             return new Cache<String, RecordId>() {
                 @Override
                 public void put(@Nonnull String stableId, @Nonnull RecordId recordId, byte cost) { }
@@ -231,13 +234,6 @@ public abstract class WriterCacheManager
         private final Supplier<PriorityCache<String, RecordId>> nodeCache;
 
         /**
-         * The {@code StatisticsProvider} instance used to expose statistics of
-         * the caches managed by this instance.
-         */
-        @Nonnull
-        private final StatisticsProvider statisticsProvider;
-
-        /**
          * New instance using the passed factories for creating cache instances.
          * The factories will be invoked exactly once when a generation of a
          * cache is requested that has not been requested before.
@@ -245,18 +241,14 @@ public abstract class WriterCacheManager
          * @param stringCacheFactory       factory for the string cache
          * @param templateCacheFactory     factory for the template cache
          * @param nodeCacheFactory         factory for the node cache
-         * @param statisticsProvider       The {@code StatisticsProvider} instance to expose
-         *                                 statistics of the caches managed by this instance.
          */
         public Default(
                 @Nonnull Supplier<RecordCache<String>> stringCacheFactory,
                 @Nonnull Supplier<RecordCache<Template>> templateCacheFactory,
-                @Nonnull Supplier<PriorityCache<String, RecordId>> nodeCacheFactory,
-                @Nonnull StatisticsProvider statisticsProvider) {
+                @Nonnull Supplier<PriorityCache<String, RecordId>> nodeCacheFactory) {
             this.stringCaches = new Generations<>(stringCacheFactory);
             this.templateCaches = new Generations<>(templateCacheFactory);
             this.nodeCache = memoize(nodeCacheFactory);
-            this.statisticsProvider = checkNotNull(statisticsProvider);
         }
 
         /**
@@ -268,8 +260,7 @@ public abstract class WriterCacheManager
         public Default() {
             this(RecordCache.<String>factory(DEFAULT_STRING_CACHE_SIZE),
                  RecordCache.<Template>factory(DEFAULT_TEMPLATE_CACHE_SIZE),
-                 PriorityCache.<String, RecordId>factory(DEFAULT_NODE_CACHE_SIZE),
-                 StatisticsProvider.NOOP);
+                 PriorityCache.<String, RecordId>factory(DEFAULT_NODE_CACHE_SIZE));
         }
 
         private static class Generations<T> implements Iterable<T> {
@@ -311,16 +302,14 @@ public abstract class WriterCacheManager
 
         @Nonnull
         @Override
-        public Cache<String, RecordId> getStringCache(int generation, Operation operation) {
-            return new AccessTrackingCache<>("oak.segment.string-deduplication-cache-" + operation,
-                    stringCaches.getGeneration(generation));
+        public Cache<String, RecordId> getStringCache(int generation) {
+            return stringCaches.getGeneration(generation);
         }
 
         @Nonnull
         @Override
-        public Cache<Template, RecordId> getTemplateCache(int generation, Operation operation) {
-            return new AccessTrackingCache<>("oak.segment.template-deduplication-cache-" + operation,
-                    templateCaches.getGeneration(generation));
+        public Cache<Template, RecordId> getTemplateCache(int generation) {
+            return templateCaches.getGeneration(generation);
         }
 
         private PriorityCache<String, RecordId> nodeCache() {
@@ -329,9 +318,8 @@ public abstract class WriterCacheManager
 
         @Override
         @Nonnull
-        public Cache<String, RecordId> getNodeCache(final int generation, Operation operation) {
-            return new AccessTrackingCache<>("oak.segment.node-deduplication-cache-" + operation,
-                    new Cache<String, RecordId>() {
+        public Cache<String, RecordId> getNodeCache(final int generation) {
+            return new Cache<String, RecordId>() {
                 @Override
                 public void put(@Nonnull String stableId, @Nonnull RecordId recordId, byte cost) {
                     nodeCache().put(stableId, recordId, generation, cost);
@@ -347,7 +335,7 @@ public abstract class WriterCacheManager
                 public RecordId get(@Nonnull String stableId) {
                     return nodeCache().get(stableId, generation);
                 }
-            });
+            };
         }
 
         @CheckForNull
@@ -447,44 +435,82 @@ public abstract class WriterCacheManager
             nodeCache().purgeGenerations(generations);
         }
 
-        /**
-         * {@code Cache} wrapper exposing the number of read accesses and the
-         * number of misses ot the underlying cache via the {@link #statisticsProvider}.
-         */
-        private class AccessTrackingCache<K, V> implements Cache<K,V> {
-            private final Cache<K, V> delegate;
-            private final CounterStats accessCount;
-            private final CounterStats missCount;
-
-            private AccessTrackingCache(@Nonnull String name, @Nonnull Cache<K, V> delegate) {
-                this.delegate = delegate;
-                this.accessCount = statisticsProvider.getCounterStats(
-                        name + ".access-count", StatsOptions.DEFAULT);
-                this.missCount = statisticsProvider.getCounterStats(
-                        name + ".miss-count", StatsOptions.DEFAULT);
-            }
+    }
 
-            @Override
-            public void put(@Nonnull K key, @Nonnull V value) {
-                delegate.put(key, value);
-            }
+    /**
+     * Wrapper wrapping all caches returned by a {@link WriterCacheManager}
+     * into a {@link CacheAccessTracker}.
+     */
+    private static class AccessTrackingCacheManager extends WriterCacheManager {
+        @Nonnull
+        private final String name;
 
-            @Override
-            public void put(@Nonnull K key, @Nonnull V value, byte cost) {
-                delegate.put(key, value, cost);
-            }
+        @Nonnull
+        private final StatisticsProvider statisticsProvider;
 
-            @CheckForNull
-            @Override
-            public V get(@Nonnull K key) {
-                V v = delegate.get(key);
-                accessCount.inc();
-                if (v == null) {
-                    missCount.inc();
-                }
-                return v;
-            }
+        @Nonnull
+        private final WriterCacheManager delegate;
+
+        /**
+         * Create a new instance. The {@code name} passed is used to prepend to the
+         * names used to expose the access statistics.
+         * @param name                 name under which to expose the access statistics
+         * @param statisticsProvider   statistics provider where the access statistics is recorded to
+         * @param delegate             the underlying, wrapped cache manager
+         *
+         * @see #getStringCache(int)
+         * @see #getTemplateCache(int)
+         * @see #getNodeCache(int)
+         */
+        public AccessTrackingCacheManager(
+                @Nonnull String name,
+                @Nonnull StatisticsProvider statisticsProvider,
+                @Nonnull WriterCacheManager delegate) {
+            this.name = name;
+            this.statisticsProvider = statisticsProvider;
+            this.delegate = delegate;
         }
 
+        /**
+         * @return the wrapped cache returned by the delegate's method of
+         * the same name exposing access statistics under
+         * {@code "oak.segment.string-deduplication-cache-" + name}
+         */
+        @Nonnull
+        @Override
+        public Cache<String, RecordId> getStringCache(int generation) {
+            return new CacheAccessTracker<>(
+                    "oak.segment.string-deduplication-cache-" + name,
+                    statisticsProvider, delegate.getStringCache(generation)
+            );
+        }
+
+        /**
+         * @return the wrapped cache returned by the delegate's method of
+         * the same name exposing access statistics under
+         * {@code "oak.segment.template-deduplication-cache-" + name}
+         */
+        @Nonnull
+        @Override
+        public Cache<Template, RecordId> getTemplateCache(int generation) {
+            return new CacheAccessTracker<>(
+                    "oak.segment.template-deduplication-cache-" + name,
+                    statisticsProvider, delegate.getTemplateCache(generation)
+            );
+        }
+
+        /**
+         * @return the wrapped cache returned by the delegate's method of
+         * the same name exposing access statistics under
+         * {@code "oak.segment.node-deduplication-cache-" + name}
+         */
+        @Nonnull
+        @Override
+        public Cache<String, RecordId> getNodeCache(int generation) {
+            return new CacheAccessTracker<>(
+                    "oak.segment.node-deduplication-cache-" + name,
+                    statisticsProvider, delegate.getNodeCache(generation)
+            );
+        }
     }
 }

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=1799937&r1=1799936&r2=1799937&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 Mon Jun 26 15:56:59 2017
@@ -79,6 +79,7 @@ import org.apache.jackrabbit.oak.segment
 import org.apache.jackrabbit.oak.segment.file.TarFiles.CleanupResult;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -187,10 +188,15 @@ public class FileStore extends AbstractF
                     }
                 })
                 .withWriterPool()
-                .with(builder.getCacheManager())
+                .with(builder.getCacheManager()
+                        .withAccessTracking("WRITE", builder.getStatsProvider()))
                 .build(this);
         this.garbageCollector = new GarbageCollector(
-                builder.getGcOptions(), builder.getGcListener(), new GCJournal(directory), builder.getCacheManager());
+                builder.getGcOptions(),
+                builder.getGcListener(),
+                new GCJournal(directory),
+                builder.getCacheManager(),
+                builder.getStatsProvider());
 
         Manifest manifest = Manifest.empty();
 
@@ -548,6 +554,9 @@ public class FileStore extends AbstractF
         @Nonnull
         private final GCNodeWriteMonitor compactionMonitor;
 
+        @Nonnull
+        private final StatisticsProvider statisticsProvider;
+
         private volatile boolean cancelled;
 
         /** Timestamp of the last time {@link #gc()} was successfully invoked. 0 if never. */
@@ -557,12 +566,14 @@ public class FileStore extends AbstractF
                 @Nonnull SegmentGCOptions gcOptions,
                 @Nonnull GCListener gcListener,
                 @Nonnull GCJournal gcJournal,
-                @Nonnull WriterCacheManager cacheManager) {
+                @Nonnull WriterCacheManager cacheManager,
+                @Nonnull StatisticsProvider statisticsProvider) {
             this.gcOptions = gcOptions;
             this.gcListener = gcListener;
             this.gcJournal = gcJournal;
             this.cacheManager = cacheManager;
             this.compactionMonitor = gcOptions.getGCNodeWriteMonitor();
+            this.statisticsProvider = statisticsProvider;
         }
 
         synchronized void run() throws IOException {
@@ -668,7 +679,8 @@ public class FileStore extends AbstractF
                 SegmentNodeState before = getHead();
                 CancelCompactionSupplier cancel = new CancelCompactionSupplier(FileStore.this);
                 SegmentWriter writer = defaultSegmentWriterBuilder("c")
-                        .with(cacheManager)
+                        .with(cacheManager
+                                .withAccessTracking("COMPACT", statisticsProvider))
                         .withGeneration(newGeneration)
                         .withoutWriterPool()
                         .withCompactionMonitor(compactionMonitor)

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java?rev=1799937&r1=1799936&r2=1799937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStoreBuilder.java Mon Jun 26 15:56:59 2017
@@ -432,7 +432,7 @@ public class FileStoreBuilder {
     public WriterCacheManager getCacheManager() {
         if (cacheManager == null) {
             cacheManager = new EvictingWriteCacheManager(stringDeduplicationCacheSize,
-                    templateDeduplicationCacheSize, nodeDeduplicationCacheSize, statsProvider);
+                    templateDeduplicationCacheSize, nodeDeduplicationCacheSize);
         }
         return cacheManager;
     }
@@ -463,12 +463,10 @@ public class FileStoreBuilder {
         public EvictingWriteCacheManager(
                 int stringCacheSize,
                 int templateCacheSize,
-                int nodeCacheSize,
-                @Nonnull StatisticsProvider statisticsProvider) {
+                int nodeCacheSize) {
             super(RecordCache.factory(stringCacheSize, new StringCacheWeigher()),
                 RecordCache.factory(templateCacheSize, new TemplateCacheWeigher()),
-                PriorityCache.factory(nodeCacheSize, new NodeCacheWeigher()),
-                statisticsProvider);
+                PriorityCache.factory(nodeCacheSize, new NodeCacheWeigher()));
         }
 
         void evictOldGeneration(final int newGeneration) {

Added: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CacheAccessTrackerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CacheAccessTrackerTest.java?rev=1799937&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CacheAccessTrackerTest.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/CacheAccessTrackerTest.java Mon Jun 26 15:56:59 2017
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.jackrabbit.oak.segment;
+
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static org.apache.jackrabbit.oak.segment.RecordCache.newRecordCache;
+import static org.junit.Assert.assertEquals;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
+import org.apache.jackrabbit.oak.stats.DefaultStatisticsProvider;
+import org.apache.jackrabbit.oak.stats.MeterStats;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.stats.StatsOptions;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CacheAccessTrackerTest {
+    private CacheAccessTracker<String, RecordId> cache;
+    private Closeable closer;
+
+    private MeterStats accessStats;
+    private MeterStats missStats;
+
+    @Before
+    public void setup() {
+        ScheduledExecutorService scheduler = newScheduledThreadPool(1);
+        StatisticsProvider statistics = new DefaultStatisticsProvider(scheduler);
+        cache = new CacheAccessTracker<String, RecordId>("foo", statistics, newRecordCache(100));
+        closer = new ExecutorCloser(scheduler);
+
+        accessStats = statistics.getMeter("foo.access-count", StatsOptions.DEFAULT);
+        missStats = statistics.getMeter("foo.miss-count", StatsOptions.DEFAULT);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        closer.close();
+    }
+
+    @Test
+    public void testNoAccess() {
+        assertEquals(0, accessStats.getCount());
+        assertEquals(0, missStats.getCount());
+    }
+
+    @Test
+    public void testMissOnEmpty() {
+        cache.get("non existing");
+
+        assertEquals(1, accessStats.getCount());
+        assertEquals(1, missStats.getCount());
+    }
+
+    @Test
+    public void testHit() {
+        cache.put("one", RecordId.NULL);
+        cache.get("one");
+
+        assertEquals(1, accessStats.getCount());
+        assertEquals(0, missStats.getCount());
+    }
+
+    @Test
+    public void testMissOnNonEmpty() {
+        cache.put("one", RecordId.NULL);
+        cache.get("non existing");
+
+        assertEquals(1, accessStats.getCount());
+        assertEquals(1, missStats.getCount());
+    }
+
+    @Test
+    public void testHitMiss() {
+        cache.put("one", RecordId.NULL);
+        cache.get("one");
+        cache.get("non existing");
+
+        assertEquals(2, accessStats.getCount());
+        assertEquals(1, missStats.getCount());
+    }
+}

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java?rev=1799937&r1=1799936&r2=1799937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/NodeRecordTest.java Mon Jun 26 15:56:59 2017
@@ -169,20 +169,20 @@ public class NodeRecordTest {
 
             @Nonnull
             @Override
-            public Cache<String, RecordId> getStringCache(int generation, Operation operation) {
-                return Empty.INSTANCE.getStringCache(generation, operation);
+            public Cache<String, RecordId> getStringCache(int generation) {
+                return Empty.INSTANCE.getStringCache(generation);
             }
 
             @Nonnull
             @Override
-            public Cache<Template, RecordId> getTemplateCache(int generation, Operation operation) {
-                return Empty.INSTANCE.getTemplateCache(generation, operation);
+            public Cache<Template, RecordId> getTemplateCache(int generation) {
+                return Empty.INSTANCE.getTemplateCache(generation);
             }
 
             @Nonnull
             @Override
-            public Cache<String, RecordId> getNodeCache(int generation, Operation operation) {
-                return defaultCache.getNodeCache(generation, operation);
+            public Cache<String, RecordId> getNodeCache(int generation) {
+                return defaultCache.getNodeCache(generation);
             }
         };
     }

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/WriteCacheManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/WriteCacheManagerTest.java?rev=1799937&r1=1799936&r2=1799937&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/WriteCacheManagerTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/WriteCacheManagerTest.java Mon Jun 26 15:56:59 2017
@@ -19,7 +19,6 @@
 
 package org.apache.jackrabbit.oak.segment;
 
-import static org.apache.jackrabbit.oak.segment.WriterCacheManager.Operation.WRITE;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 
@@ -33,22 +32,22 @@ public class WriteCacheManagerTest {
     public void emptyGenerations() {
         WriterCacheManager cache = Empty.INSTANCE;
         assertEquals(
-                cache.getTemplateCache(0, WRITE),
-                cache.getTemplateCache(1, WRITE));
+                cache.getTemplateCache(0),
+                cache.getTemplateCache(1));
         assertEquals(
-                cache.getStringCache(0, WRITE),
-                cache.getStringCache(1, WRITE));
+                cache.getStringCache(0),
+                cache.getStringCache(1));
     }
 
     @Test
     public void nonEmptyGenerations() {
         WriterCacheManager cache = new Default();
         assertNotEquals(
-                cache.getTemplateCache(0, WRITE),
-                cache.getTemplateCache(1, WRITE));
+                cache.getTemplateCache(0),
+                cache.getTemplateCache(1));
         assertNotEquals(
-                cache.getStringCache(0, WRITE),
-                cache.getStringCache(1, WRITE));
+                cache.getStringCache(0),
+                cache.getStringCache(1));
     }
 
 }