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 ch...@apache.org on 2017/10/12 07:48:09 UTC

svn commit: r1811918 - in /jackrabbit/oak/trunk/oak-store-document/src: main/java/org/apache/jackrabbit/oak/plugins/document/ main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/ test/java/org/apache/jackrabbit/oak/plugins/document/ te...

Author: chetanm
Date: Thu Oct 12 07:48:09 2017
New Revision: 1811918

URL: http://svn.apache.org/viewvc?rev=1811918&view=rev
Log:
OAK-6803 - Provide a way to for persistent cache to determine which all nodes can be cached

Modified:
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
    jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
    jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1811918&r1=1811917&r2=1811918&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java Thu Oct 12 07:48:09 2017
@@ -40,6 +40,8 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.sql.DataSource;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.base.Supplier;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
@@ -606,6 +608,7 @@ public class DocumentMK {
         private long maxRevisionAgeMillis = DEFAULT_JOURNAL_GC_MAX_AGE_MILLIS;
         private GCMonitor gcMonitor = new LoggingGCMonitor(
                 LoggerFactory.getLogger(VersionGarbageCollector.class));
+        private Predicate<String> nodeCachePredicate = Predicates.alwaysTrue();
 
         public Builder() {
         }
@@ -1252,6 +1255,15 @@ public class DocumentMK {
             return new NodeDocumentCache(nodeDocumentsCache, nodeDocumentsCacheStats, prevDocumentsCache, prevDocumentsCacheStats, locks);
         }
 
+        public Builder setNodeCachePredicate(Predicate<String> p){
+            this.nodeCachePredicate = p;
+            return this;
+        }
+
+        public Predicate<String> getNodeCachePredicate() {
+            return nodeCachePredicate;
+        }
+
         @SuppressWarnings("unchecked")
         private <K extends CacheValue, V extends CacheValue> Cache<K, V> buildCache(
                 CacheType cacheType,

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1811918&r1=1811917&r2=1811918&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Thu Oct 12 07:48:09 2017
@@ -510,7 +510,10 @@ public final class DocumentNodeStore
      */
     private final Set<Revision> inDoubtTrunkCommits = Sets.newConcurrentHashSet();
 
+    private final Predicate<String> nodeCachePredicate;
+
     public DocumentNodeStore(DocumentMK.Builder builder) {
+        this.nodeCachePredicate = builder.getNodeCachePredicate();
         this.updateLimit = builder.getUpdateLimit();
         this.commitValueResolver = new CommitValueResolver(builder.getCommitValueCacheSize(),
                 new Supplier<RevisionVector>() {
@@ -1048,6 +1051,10 @@ public final class DocumentNodeStore
         return nodeChildrenCache;
     }
 
+    public Predicate<String> getNodeCachePredicate() {
+        return nodeCachePredicate;
+    }
+
     /**
      * Returns the journal entry that will be stored in the journal with the
      * next background updated.

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1811918&r1=1811917&r2=1811918&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java Thu Oct 12 07:48:09 2017
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.plugin
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.emptyList;
 import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
 import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toBoolean;
 import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toInteger;
@@ -39,17 +40,22 @@ import static org.apache.jackrabbit.oak.
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
 import javax.sql.DataSource;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.base.Strings;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
@@ -86,6 +92,7 @@ import org.apache.jackrabbit.oak.spi.blo
 import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
 import org.apache.jackrabbit.oak.spi.blob.stats.BlobStoreStatsMBean;
 import org.apache.jackrabbit.oak.spi.commit.BackgroundObserverMBean;
+import org.apache.jackrabbit.oak.spi.filter.PathFilter;
 import org.apache.jackrabbit.oak.spi.gc.DelegatingGCMonitor;
 import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
 import org.apache.jackrabbit.oak.spi.gc.GCMonitorTracker;
@@ -361,6 +368,11 @@ public class DocumentNodeStoreService {
                 description = "Number of content updates that need to happen before " +
                         "the updates are automatically purged to the private branch.")
         int updateLimit();
+
+        @AttributeDefinition(
+                name = "Persistent Cache Includes",
+                description = "Paths which should be cached in persistent cache")
+        String[] persistentCacheIncludes() default {"/"};
     }
     
     // property name constants - values can come from framework properties or OSGi config
@@ -435,9 +447,12 @@ public class DocumentNodeStoreService {
 
     private BlobStore defaultBlobStore;
 
+    private volatile Configuration config;
+
     @Activate
     protected void activate(ComponentContext context, Configuration config) throws Exception {
         closer = Closer.create();
+        this.config = config;
         this.context = context;
         whiteboard = new OsgiWhiteboard(context.getBundleContext());
         executor = new WhiteboardExecutor();
@@ -522,7 +537,8 @@ public class DocumentNodeStoreService {
                 }).
                 setPrefetchExternalChanges(prefetchExternalChanges).
                 setUpdateLimit(updateLimit).
-                setJournalGCMaxAge(journalGCMaxAge);
+                setJournalGCMaxAge(journalGCMaxAge).
+                setNodeCachePredicate(createCachePredicate());
 
         if (!Strings.isNullOrEmpty(persistentCache)) {
             mkBuilder.setPersistentCache(persistentCache);
@@ -696,6 +712,26 @@ public class DocumentNodeStoreService {
             nodeStore, props);
     }
 
+    private Predicate<String> createCachePredicate() {
+        if (config.persistentCacheIncludes().length == 0) {
+            return Predicates.alwaysTrue();
+        }
+        if (Arrays.equals(config.persistentCacheIncludes(), new String[]{"/"})) {
+            return Predicates.alwaysTrue();
+        }
+
+        Set<String> paths = new HashSet<>();
+        for (String p : config.persistentCacheIncludes()) {
+            p = p != null ? Strings.emptyToNull(p.trim()) : null;
+            if (p != null) {
+                paths.add(p);
+            }
+        }
+        PathFilter pf = new PathFilter(paths, emptyList());
+        log.info("Configuring persistent cache to only cache nodes under paths {}", paths);
+        return path -> path != null && pf.filter(path) == PathFilter.Result.INCLUDE;
+    }
+
     private boolean isNodeStoreProvider() {
         return prop(PROP_ROLE) != null;
     }

Modified: jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java?rev=1811918&r1=1811917&r2=1811918&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheType.java Thu Oct 12 07:48:09 2017
@@ -53,7 +53,11 @@ public enum CacheType {
         }
         @Override
         public <K> boolean shouldCache(DocumentNodeStore store, K key) {
-            return !store.getNodeStateCache().isCached(((PathRev)key).getPath());
+            String path = ((PathRev) key).getPath();
+            if (!store.getNodeCachePredicate().apply(path)){
+                return false;
+            }
+            return !store.getNodeStateCache().isCached(path);
         }
     },
     
@@ -84,7 +88,11 @@ public enum CacheType {
 
         @Override
         public <K> boolean shouldCache(DocumentNodeStore store, K key) {
-            return !store.getNodeStateCache().isCached(((PathRev)key).getPath());
+            String path = ((PathRev) key).getPath();
+            if (!store.getNodeCachePredicate().apply(path)){
+                return false;
+            }
+            return !store.getNodeStateCache().isCached(path);
         }
     }, 
     

Modified: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java?rev=1811918&r1=1811917&r2=1811918&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreServiceTest.java Thu Oct 12 07:48:09 2017
@@ -189,6 +189,19 @@ public class DocumentNodeStoreServiceTes
         assertNotNull(((Supplier) rgcJob).get());
     }
 
+    @Test
+    public void persistentCacheExclude() throws Exception{
+        Map<String, Object> config = newConfig(repoHome);
+        config.put("persistentCacheIncludes", new String[] {"/a/b", "/c/d ", null});
+        MockOsgi.activate(service, context.bundleContext(), config);
+
+        DocumentNodeStore dns = context.getService(DocumentNodeStore.class);
+        assertTrue(dns.getNodeCachePredicate().apply("/a/b/c"));
+        assertTrue(dns.getNodeCachePredicate().apply("/c/d/e"));
+
+        assertFalse(dns.getNodeCachePredicate().apply("/x"));
+    }
+
     private static MongoDocumentStore getMongoDocumentStore(DocumentNodeStore s) {
         try {
             Field f = s.getClass().getDeclaredField("nonLeaseCheckingStore");

Modified: jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java?rev=1811918&r1=1811917&r2=1811918&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java (original)
+++ jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/NodeCacheTest.java Thu Oct 12 07:48:09 2017
@@ -23,7 +23,9 @@ import java.io.File;
 import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Consumer;
 
+import com.google.common.base.Predicate;
 import com.google.common.cache.RemovalCause;
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
@@ -37,6 +39,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.filter.PathFilter;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.stats.Counting;
 import org.apache.jackrabbit.oak.stats.DefaultStatisticsProvider;
@@ -46,6 +49,8 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -118,7 +123,32 @@ public class NodeCacheTest {
         assertNotContains(nodeChildren, "/c");
     }
 
+    @Test
+    public void cachePredicateSync() throws Exception{
+        PathFilter pf = new PathFilter(asList("/a"), emptyList());
+        Predicate<String> p = path -> pf.filter(path) == PathFilter.Result.INCLUDE;
+        initializeNodeStore(false, b -> b.setNodeCachePredicate(p));
+
+        NodeBuilder builder = ns.getRoot().builder();
+        builder.child("a").child("c1");
+        builder.child("b").child("c2");
+        ns.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        //Do a read again
+        ns.getRoot().getChildNode("a").getChildNode("c1");
+        ns.getRoot().getChildNode("b").getChildNode("c2");
+
+        assertNotContains(nodeCache, "/b");
+        assertNotContains(nodeCache, "/b/c2");
+        assertContains(nodeCache, "/a");
+        assertContains(nodeCache, "/a/c1");
+    }
+
     private void initializeNodeStore(boolean asyncCache) {
+        initializeNodeStore(asyncCache, b -> {});
+    }
+
+    private void initializeNodeStore(boolean asyncCache, Consumer<DocumentMK.Builder> processor) {
         DocumentMK.Builder builder = builderProvider.newBuilder()
                 .setAsyncDelay(0)
                 .setStatisticsProvider(statsProvider);
@@ -128,6 +158,9 @@ public class NodeCacheTest {
         }else {
             builder.setPersistentCache("target/persistentCache,time,-async");
         }
+
+        processor.accept(builder);
+
         ns = builder.getNodeStore();
         nodeCache = (NodeCache<PathRev, DocumentNodeState>) ns.getNodeCache();
         nodeChildren = (NodeCache<PathRev, DocumentNodeState.Children>) ns.getNodeChildrenCache();