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 2013/10/28 10:48:25 UTC
svn commit: r1536295 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/mongomk/
main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/
test/java/org/apache/jackrabbit/oak/plugins/mongomk/
Author: chetanm
Date: Mon Oct 28 09:48:24 2013
New Revision: 1536295
URL: http://svn.apache.org/r1536295
Log:
OAK-1117 - [MongoMk]Flag document with children
Adding support for marking nodes which have child nodes.
* Added DocumentStore.getIfCached replacing unused isCached
* Added a new boolean attribute `_hasChildNodes` to mark nodes which have child
* Modified Commit logic to mark parents by setting `_hasChildNodes` to true
* Changed assertion in two testcase as with this change the commit root might change
in some cases
Added:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/OptimizedChildFetchTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Node.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/LoggingDocumentStoreWrapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/TimingDocumentStoreWrapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/Utils.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Commit.java Mon Oct 28 09:48:24 2013
@@ -20,12 +20,14 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.collect.Sets;
import org.apache.jackrabbit.mk.api.MicroKernelException;
import org.apache.jackrabbit.mk.json.JsopStream;
import org.apache.jackrabbit.mk.json.JsopWriter;
@@ -138,6 +140,7 @@ public class Commit {
*/
void apply() {
if (!operations.isEmpty()) {
+ updateParentChildStatus();
applyToDocumentStore();
applyToCache(false);
}
@@ -145,6 +148,7 @@ public class Commit {
void prepare(Revision baseRevision) {
if (!operations.isEmpty()) {
+ updateParentChildStatus();
applyToDocumentStore(baseRevision);
applyToCache(true);
}
@@ -269,6 +273,47 @@ public class Commit {
throw new MicroKernelException(msg, e);
}
}
+
+ private void updateParentChildStatus() {
+ final DocumentStore store = nodeStore.getDocumentStore();
+ final Set<String> processedParents = Sets.newHashSet();
+ for (String path : addedNodes) {
+ if (PathUtils.denotesRoot(path)) {
+ continue;
+ }
+
+ String parentPath = PathUtils.getParentPath(path);
+
+ if (processedParents.contains(parentPath)) {
+ continue;
+ }
+
+ processedParents.add(parentPath);
+ final UpdateOp op = operations.get(parentPath);
+ if (op != null) {
+ //Parent node all ready part of modification list
+ //Update it in place
+ if (op.isNew()) {
+ NodeDocument.setChildNodesStatus(op, true);
+ } else {
+ NodeDocument nd = store.getIfCached(Collection.NODES, Utils.getIdFromPath(parentPath));
+ if (nd != null && nd.hasChildNodes()) {
+ continue;
+ }
+ NodeDocument.setChildNodesStatus(op, true);
+ }
+ } else {
+ NodeDocument nd = store.getIfCached(Collection.NODES, Utils.getIdFromPath(parentPath));
+ if (nd != null && nd.hasChildNodes()) {
+ //Status already set to true. Nothing to do
+ continue;
+ } else {
+ UpdateOp updateParentOp = getUpdateOperationForNode(parentPath);
+ NodeDocument.setChildNodesStatus(updateParentOp, true);
+ }
+ }
+ }
+ }
private void rollback(ArrayList<UpdateOp> newDocuments, ArrayList<UpdateOp> changed) {
DocumentStore store = nodeStore.getDocumentStore();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentStore.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentStore.java Mon Oct 28 09:48:24 2013
@@ -176,13 +176,14 @@ public interface DocumentStore {
void dispose();
/**
- * Check whether the given document is in the cache.
- *
+ * Fetches the cached document. If document is not present in cache <code>null</code> would be returned
+ *
* @param <T> the document type
* @param collection the collection
* @param key the key
- * @return true if yes
+ * @return cached document if present. Otherwise null
*/
- <T extends Document> boolean isCached(Collection<T> collection, String key);
+ @CheckForNull
+ <T extends Document> T getIfCached(Collection<T> collection, String key);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java Mon Oct 28 09:48:24 2013
@@ -356,8 +356,8 @@ public class MemoryDocumentStore impleme
}
@Override
- public <T extends Document> boolean isCached(Collection<T> collection, String key) {
- return false;
+ public <T extends Document> T getIfCached(Collection<T> collection, String key) {
+ return find(collection,key);
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java Mon Oct 28 09:48:24 2013
@@ -457,7 +457,7 @@ public class MongoDocumentStore implemen
}
} finally {
end("create", start);
- }
+ }
}
@Override
@@ -516,6 +516,8 @@ public class MongoDocumentStore implemen
copy.put(key, o);
} else if (o instanceof Long) {
copy.put(key, o);
+ } else if (o instanceof Boolean) {
+ copy.put(key, o);
} else if (o instanceof BasicDBObject) {
copy.put(key, convertMongoMap((BasicDBObject) o));
}
@@ -571,11 +573,11 @@ public class MongoDocumentStore implemen
}
@Override
- public <T extends Document> boolean isCached(Collection<T> collection, String key) {
+ public <T extends Document> T getIfCached(Collection<T> collection, String key){
if (collection != Collection.NODES) {
- return false;
+ return null;
}
- return nodesCache.getIfPresent(key) != null;
+ return (T)nodesCache.getIfPresent(key);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoMK.java Mon Oct 28 09:48:24 2013
@@ -574,10 +574,6 @@ public class MongoMK implements MicroKer
return nodeStore.getDocChildrenCacheStats();
}
- public boolean isCached(String path) {
- return store.isCached(Collection.NODES, Utils.getIdFromPath(path));
- }
-
//------------------------------< internal >--------------------------------
private void parseJsonDiff(Commit commit, String json, String rootPath) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java Mon Oct 28 09:48:24 2013
@@ -498,6 +498,14 @@ public final class MongoNodeStore
public Node.Children getChildren(final String path, final Revision rev, final int limit) throws
MicroKernelException {
checkRevisionAge(rev, path);
+
+ //Preemptive check. If we know there are no child then
+ //return straight away
+ final Node node = getNode(path,rev);
+ if(node.hasNoChildren()){
+ return new Node.Children();
+ }
+
String key = path + "@" + rev;
Node.Children children;
try {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Node.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Node.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Node.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/Node.java Mon Oct 28 09:48:24 2013
@@ -29,7 +29,6 @@ import org.apache.jackrabbit.oak.plugins
* Represents a node held in memory (in the cache for example).
*/
public class Node implements CacheValue {
-
/**
* A node, which does not exist at a given revision.
*/
@@ -44,10 +43,16 @@ public class Node implements CacheValue
final Revision rev;
final Map<String, String> properties = Utils.newMap();
Revision lastRevision;
+ final boolean hasChildren;
Node(String path, Revision rev) {
+ this(path,rev,false);
+ }
+
+ Node(String path, Revision rev,boolean hasChildren) {
this.path = path;
this.rev = rev;
+ this.hasChildren = hasChildren;
}
void setProperty(String propertyName, String value) {
@@ -70,6 +75,10 @@ public class Node implements CacheValue
newNode.properties.putAll(properties);
}
+ public boolean hasNoChildren(){
+ return !hasChildren;
+ }
+
@Override
public String toString() {
StringBuilder buff = new StringBuilder();
@@ -89,6 +98,7 @@ public class Node implements CacheValue
op.set(Document.ID, id);
NodeDocument.setModified(op, rev);
NodeDocument.setDeleted(op, rev, false);
+ NodeDocument.setChildNodesStatus(op,false);
for (String p : properties.keySet()) {
String key = Utils.escapePropertyName(p);
op.setMapEntry(key, rev, properties.get(p));
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java Mon Oct 28 09:48:24 2013
@@ -34,6 +34,7 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.cache.CacheValue;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
@@ -125,11 +126,18 @@ public class NodeDocument extends Docume
private static final String LAST_REV = "_lastRev";
/**
+ * Flag indicating that there are child nodes present. Its just used as a hint.
+ * If false then that indicates that there are no child. However if its true its
+ * not necessary that there are child nodes. It just means at some moment this
+ * node had a child node
+ */
+ private static final String HAS_CHILD_NODE = "_hasChildNodes";
+
+ /**
* Properties to ignore when a document is split.
*/
- private static final Set<String> IGNORE_ON_SPLIT =
- Collections.unmodifiableSet(new HashSet<String>(
- Arrays.asList(ID, MOD_COUNT, MODIFIED, PREVIOUS, LAST_REV)));
+ private static final Set<String> IGNORE_ON_SPLIT = ImmutableSet.of(ID, MOD_COUNT, MODIFIED, PREVIOUS,
+ LAST_REV, HAS_CHILD_NODE);
final DocumentStore store;
@@ -171,6 +179,13 @@ public class NodeDocument extends Docume
}
/**
+ * @return the approximate number of children for this node.
+ */
+ public boolean hasChildNodes() {
+ return checkNotNull((Boolean) get(HAS_CHILD_NODE)).booleanValue();
+ }
+
+ /**
* @return a map of the last known revision for each clusterId.
*/
@Nonnull
@@ -391,7 +406,7 @@ public class NodeDocument extends Docume
return null;
}
String path = Utils.getPathFromId(getId());
- Node n = new Node(path, readRevision);
+ Node n = new Node(path, readRevision, hasChildNodes());
for (String key : keySet()) {
if (!Utils.isPropertyName(key)) {
continue;
@@ -757,6 +772,11 @@ public class NodeDocument extends Docume
//-------------------------< UpdateOp modifiers >---------------------------
+ public static void setChildNodesStatus(@Nonnull UpdateOp op,
+ boolean hasChildNode) {
+ checkNotNull(op).set(HAS_CHILD_NODE, Boolean.valueOf(hasChildNode));
+ }
+
public static void setModified(@Nonnull UpdateOp op,
@Nonnull Revision revision) {
checkNotNull(op).set(MODIFIED, Commit.getModified(checkNotNull(revision).getTimestamp()));
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/LoggingDocumentStoreWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/LoggingDocumentStoreWrapper.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/LoggingDocumentStoreWrapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/LoggingDocumentStoreWrapper.java Mon Oct 28 09:48:24 2013
@@ -240,14 +240,14 @@ public class LoggingDocumentStoreWrapper
}
@Override
- public <T extends Document> boolean isCached(final Collection<T> collection,
- final String key) {
+ public <T extends Document> T getIfCached(final Collection<T> collection,
+ final String key) {
try {
logMethod("isCached", collection, key);
- return logResult(new Callable<Boolean>() {
+ return logResult(new Callable<T>() {
@Override
- public Boolean call() throws Exception {
- return store.isCached(collection, key);
+ public T call() throws Exception {
+ return store.getIfCached(collection, key);
}
});
} catch (Exception e) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/TimingDocumentStoreWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/TimingDocumentStoreWrapper.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/TimingDocumentStoreWrapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/TimingDocumentStoreWrapper.java Mon Oct 28 09:48:24 2013
@@ -275,10 +275,10 @@ public class TimingDocumentStoreWrapper
}
@Override
- public <T extends Document> boolean isCached(Collection<T> collection, String key) {
+ public <T extends Document> T getIfCached(Collection<T> collection, String key) {
try {
long start = now();
- boolean result = base.isCached(collection, key);
+ T result = base.getIfCached(collection, key);
updateAndLogTimes("isCached", start, 0, 0);
return result;
} catch (Exception e) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/Utils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/Utils.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/Utils.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/util/Utils.java Mon Oct 28 09:48:24 2013
@@ -94,6 +94,8 @@ public class Utils {
size += 48 + ((String) o).length() * 2;
} else if (o instanceof Long) {
size += 16;
+ } else if (o instanceof Boolean) {
+ size += 8;
} else if (o instanceof Integer) {
size += 8;
} else if (o instanceof Map) {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java Mon Oct 28 09:48:24 2013
@@ -195,7 +195,7 @@ public class DocumentSplitTest extends B
Map<Revision, String> revs = doc.getLocalRevisions();
assertEquals(3, revs.size());
revs = doc.getValueMap("_revisions");
- assertEquals(3 * NodeDocument.REVISIONS_SPLIT_OFF_SIZE + 1, revs.size());
+ assertEquals(3 * NodeDocument.REVISIONS_SPLIT_OFF_SIZE, revs.size());
Revision previous = null;
for (Map.Entry<Revision, String> entry : revs.entrySet()) {
if (previous != null) {
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/OptimizedChildFetchTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/OptimizedChildFetchTest.java?rev=1536295&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/OptimizedChildFetchTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/OptimizedChildFetchTest.java Mon Oct 28 09:48:24 2013
@@ -0,0 +1,113 @@
+/*
+ * 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.mongomk;
+
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+import java.util.Set;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.matchers.JUnitMatchers.hasItem;
+
+
+public class OptimizedChildFetchTest extends BaseMongoMKTest {
+
+ private TestDocumentStore ds = new TestDocumentStore();
+
+ @Before
+ public void initMongoMK() {
+ mk = new MongoMK.Builder().setDocumentStore(ds).open();
+ }
+
+ @Test
+ public void checkForChildStatusFlag() {
+ String head = mk.getHeadRevision();
+ mk.commit("",
+ "+\"/root\":{}\n" +
+ "+\"/root/a\":{}\n" +
+ "+\"/root/a/b\":{}\n",
+ head, "");
+
+ assertTrue(getChildStatus("/root"));
+ assertTrue(getChildStatus("/root/a"));
+ assertFalse(getChildStatus("/root/a/b"));
+ }
+
+ @Test
+ public void checkForNoCallsToFetchChildForLeafNodes() {
+ String head = mk.getHeadRevision();
+ String rev = mk.commit("",
+ "+\"/root\":{}\n" +
+ "+\"/root/a\":{}\n" +
+ "+\"/root/c\":{}\n" +
+ "+\"/root/a/b\":{}\n",
+ head, "");
+
+ //Clear the caches
+ ds.paths.clear();
+ resetMK();
+
+ //Check that call is made to fetch child for non
+ //leaf nodes
+ mk.getNodes("/root/a", rev, 0, 0, 10, null);
+ assertThat(ds.paths, hasItem("3:/root/a/"));
+
+ resetMK();
+ ds.paths.clear();
+
+ //Check that no query is made to fetch children for
+ //leaf nodes
+ assertNotNull(mk.getNodes("/root/c", rev, 0, 0, 10, null));
+ assertNotNull(mk.getNodes("/root/a/b", rev, 0, 0, 10, null));
+ assertTrue(ds.paths.isEmpty());
+ }
+
+ private void resetMK() {
+ disposeMongoMK();
+ initMongoMK();
+
+ }
+
+ private boolean getChildStatus(String path) {
+ NodeDocument nd = mk.getDocumentStore().find(Collection.NODES, Utils.getIdFromPath(path));
+ return nd.hasChildNodes();
+ }
+
+
+ private static class TestDocumentStore extends MemoryDocumentStore {
+ Set<String> paths = Sets.newHashSet();
+
+ @Nonnull
+ @Override
+ public <T extends Document> List<T> query(Collection<T> collection, String fromKey, String toKey,
+ String indexedProperty, long startValue, int limit) {
+ paths.add(fromKey);
+ return super.query(collection, fromKey, toKey, indexedProperty, startValue, limit);
+ }
+ }
+}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java?rev=1536295&r1=1536294&r2=1536295&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/SimpleTest.java Mon Oct 28 09:48:24 2013
@@ -388,20 +388,23 @@ public class SimpleTest {
// root node must not have the revision
NodeDocument rootDoc = store.find(Collection.NODES, "0:/");
- assertNotNull(rootDoc);
- assertFalse(rootDoc.containsRevision(head));
+
+ //As we update the childStatus flag the commit root would shift
+ //one layer above
+ // assertNotNull(rootDoc);
+ // assertFalse(rootDoc.containsRevision(head));
// test node must have head in revisions
NodeDocument node = store.find(Collection.NODES, "1:/test");
- assertNotNull(node);
- assertTrue(node.containsRevision(head));
+ //assertNotNull(node);
+ //assertTrue(node.containsRevision(head));
// foo must not have head in revisions and must refer to test
// as commit root (depth = 1)
NodeDocument foo = store.find(Collection.NODES, "2:/test/foo");
assertNotNull(foo);
assertFalse(foo.containsRevision(head));
- assertEquals("/test", foo.getCommitRootPath(head));
+ assertEquals("/", foo.getCommitRootPath(head));
head = Revision.fromString(mk.commit("", "+\"/bar\":{}+\"/test/foo/bar\":{}", head.toString(), null));