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 2016/06/21 06:17:44 UTC
svn commit: r1749425 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document:
DocumentNodeState.java DocumentNodeStateCache.java DocumentNodeStore.java
DocumentNodeStoreService.java
Author: chetanm
Date: Tue Jun 21 06:17:44 2016
New Revision: 1749425
URL: http://svn.apache.org/viewvc?rev=1749425&view=rev
Log:
OAK-4180 - Use another NodeStore as a local cache for a remote Document store
Refactor to introduce a DocumentNodeStateCache interface. This encapsulates logic related to caching of AbstractDocumentNodeState
DocumentNodeStoreService keeps a track of the DocumentNodeStateCache service (optional). Once detected it registers it with DocumentNodeStore
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateCache.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java?rev=1749425&r1=1749424&r2=1749425&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java Tue Jun 21 06:17:44 2016
@@ -223,7 +223,7 @@ public class DocumentNodeState extends A
return false;
} else {
String p = PathUtils.concat(getPath(), name);
- return store.getNode(p, lastRevision) != null;
+ return store.getNode(p, rootRevision, lastRevision) != null;
}
}
@@ -235,7 +235,7 @@ public class DocumentNodeState extends A
return EmptyNodeState.MISSING_NODE;
}
String p = PathUtils.concat(getPath(), name);
- DocumentNodeState child = store.getNode(p, lastRevision);
+ AbstractDocumentNodeState child = store.getNode(p, rootRevision, lastRevision);
if (child == null) {
checkValidName(name);
return EmptyNodeState.MISSING_NODE;
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateCache.java?rev=1749425&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateCache.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateCache.java Tue Jun 21 06:17:44 2016
@@ -0,0 +1,86 @@
+/*
+ * 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.plugins.document;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public interface DocumentNodeStateCache {
+ DocumentNodeStateCache NOOP = new DocumentNodeStateCache() {
+ @Nonnull
+ @Override
+ public NodeStateCacheEntry getDocumentNodeState(String path, @Nullable RevisionVector rootRevision,
+ RevisionVector parentLastRev) {
+ return UNKNOWN;
+ }
+ };
+
+ NodeStateCacheEntry MISSING = new NodeStateCacheEntry(NodeStateCacheEntry.EntryType.MISSING);
+
+ NodeStateCacheEntry UNKNOWN = new NodeStateCacheEntry(NodeStateCacheEntry.EntryType.UNKNOWN);
+
+ /**
+ * Get the node for the given path and revision.
+ *
+ * @param path the path of the node.
+ * @param rootRevision
+ * @param readRevision the read revision.
+ * @return the node or {@link MISSING} if no state is there for given path and revision or {@link UNKNOWN} if
+ * cache does not have any knowledge of nodeState for given parameters
+ */
+ @Nonnull
+ NodeStateCacheEntry getDocumentNodeState(String path, RevisionVector rootRevision,
+ RevisionVector parentLastRev);
+
+ class NodeStateCacheEntry {
+ private enum EntryType {FOUND, MISSING, UNKNOWN}
+ private final AbstractDocumentNodeState state;
+ private final EntryType entryType;
+
+ public NodeStateCacheEntry(AbstractDocumentNodeState state) {
+ this.state = state;
+ this.entryType = EntryType.FOUND;
+ }
+
+ private NodeStateCacheEntry(EntryType entryType) {
+ this.state = null;
+ this.entryType = entryType;
+ }
+
+ public AbstractDocumentNodeState getState(){
+ checkState(entryType == EntryType.FOUND, "Cannot read state from an entry of type [%s]", entryType);
+ return state;
+ }
+
+ public boolean isUnknown(){
+ return entryType == EntryType.UNKNOWN;
+ }
+
+ public boolean isMissing(){
+ return entryType == EntryType.MISSING;
+ }
+
+ public boolean isFound(){
+ return entryType == EntryType.FOUND;
+ }
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateCache.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1749425&r1=1749424&r2=1749425&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Tue Jun 21 06:17:44 2016
@@ -87,6 +87,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.blob.MarkSweepGarbageCollector;
import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
import org.apache.jackrabbit.oak.plugins.document.Branch.BranchCommit;
+import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStateCache.NodeStateCacheEntry;
import org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCache;
import org.apache.jackrabbit.oak.plugins.document.persistentCache.broadcast.DynamicBroadcastConfig;
import org.apache.jackrabbit.oak.plugins.document.util.ReadOnlyDocumentStoreWrapperFactory;
@@ -412,6 +413,8 @@ public final class DocumentNodeStore
private final boolean readOnlyMode;
+ private DocumentNodeStateCache nodeStateCache = DocumentNodeStateCache.NOOP;
+
private final DocumentNodeStoreStatsCollector nodeStoreStatsCollector;
private final StatisticsProvider statisticsProvider;
@@ -868,6 +871,26 @@ public final class DocumentNodeStore
}
}
+ @CheckForNull
+ AbstractDocumentNodeState getNode(@Nonnull final String path,
+ @Nonnull final RevisionVector rootRevision,
+ @Nonnull final RevisionVector rev) {
+ AbstractDocumentNodeState result = nodeCache.getIfPresent(new PathRev(path, rev));
+ if (result == null){
+ NodeStateCacheEntry entry = nodeStateCache.getDocumentNodeState(path, rootRevision, rev);
+ if (entry.isMissing()){
+ return null;
+ } else if (entry.isFound()){
+ return entry.getState();
+ }
+ } else {
+ return result == missing
+ || result.equals(missing) ? null : result;
+ }
+
+ return getNode(path, rev);
+ }
+
/**
* Get the node for the given path and revision. The returned object might
* not be modified directly.
@@ -2804,4 +2827,8 @@ public final class DocumentNodeStore
public DocumentNodeStoreStatsCollector getStatsCollector() {
return nodeStoreStatsCollector;
}
+
+ public void setNodeStateCache(DocumentNodeStateCache nodeStateCache) {
+ this.nodeStateCache = nodeStateCache;
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1749425&r1=1749424&r2=1749425&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java Tue Jun 21 06:17:44 2016
@@ -265,7 +265,7 @@ public class DocumentNodeStoreService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
- private ServiceRegistration reg;
+ private ServiceRegistration nodeStoreReg;
private final List<Registration> registrations = new ArrayList<Registration>();
private WhiteboardExecutor executor;
@@ -285,6 +285,10 @@ public class DocumentNodeStoreService {
)
private volatile DataSource blobDataSource;
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY,
+ policy = ReferencePolicy.DYNAMIC)
+ private volatile DocumentNodeStateCache nodeStateCache;
+
private DocumentMK mk;
private ObserverTracker observerTracker;
private ComponentContext context;
@@ -345,6 +349,8 @@ public class DocumentNodeStoreService {
private boolean customBlobStore;
+ private DocumentNodeStore documentNodeStore;
+
@Activate
protected void activate(ComponentContext context, Map<String, ?> config) throws Exception {
this.context = context;
@@ -501,9 +507,9 @@ public class DocumentNodeStoreService {
registerJournalGC(mk.getNodeStore());
NodeStore store;
- DocumentNodeStore mns = mk.getNodeStore();
- store = mns;
- observerTracker = new ObserverTracker(mns);
+ documentNodeStore = mk.getNodeStore();
+ store = documentNodeStore;
+ observerTracker = new ObserverTracker(documentNodeStore);
observerTracker.start(context.getBundleContext());
@@ -532,7 +538,7 @@ public class DocumentNodeStoreService {
// OAK-2844: in order to allow DocumentDiscoveryLiteService to directly
// require a service DocumentNodeStore (instead of having to do an 'instanceof')
// the registration is now done for both NodeStore and DocumentNodeStore here.
- reg = context.getBundleContext().registerService(
+ nodeStoreReg = context.getBundleContext().registerService(
new String[]{
NodeStore.class.getName(),
DocumentNodeStore.class.getName(),
@@ -589,6 +595,21 @@ public class DocumentNodeStoreService {
unregisterNodeStore();
}
+ @SuppressWarnings("UnusedDeclaration")
+ protected void bindNodeStateCache(DocumentNodeStateCache nodeStateCache) throws IOException {
+ if (documentNodeStore != null){
+ log.info("Registered DocumentNodeStateCache [{}] with DocumentNodeStore", nodeStateCache);
+ documentNodeStore.setNodeStateCache(nodeStateCache);
+ }
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ protected void unbindNodeStateCache(DocumentNodeStateCache nodeStateCache) {
+ if (documentNodeStore != null){
+ documentNodeStore.setNodeStateCache(DocumentNodeStateCache.NOOP);
+ }
+ }
+
private void unregisterNodeStore() {
deactivationTimestamp = System.currentTimeMillis();
@@ -597,9 +618,9 @@ public class DocumentNodeStoreService {
}
registrations.clear();
- if (reg != null) {
- reg.unregister();
- reg = null;
+ if (nodeStoreReg != null) {
+ nodeStoreReg.unregister();
+ nodeStoreReg = null;
}
if (mk != null) {