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();