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 mr...@apache.org on 2013/10/29 16:31:23 UTC
svn commit: r1536758 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk:
MongoMK.java MongoNodeBuilder.java MongoNodeState.java MongoNodeStore.java
MongoNodeStoreBranch.java MongoRootBuilder.java
Author: mreutegg
Date: Tue Oct 29 15:31:22 2013
New Revision: 1536758
URL: http://svn.apache.org/r1536758
Log:
OAK-1080: MongoMK: improved concurrency
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java (with props)
Modified:
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/MongoNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStore.java
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=1536758&r1=1536757&r2=1536758&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 Tue Oct 29 15:31:22 2013
@@ -405,34 +405,9 @@ public class MongoMK implements MicroKer
try {
Revision baseRev = commit.getBaseRevision();
isBranch = baseRev != null && baseRev.isBranch();
- rev = commit.getRevision();
parseJsonDiff(commit, jsonDiff, rootPath);
- if (isBranch) {
- rev = rev.asBranchRevision();
- // remember branch commit
- Branch b = nodeStore.getBranches().getBranch(baseRev);
- if (b == null) {
- // baseRev is marker for new branch
- b = nodeStore.getBranches().create(baseRev.asTrunkRevision(), rev);
- } else {
- b.addCommit(rev);
- }
- try {
- // prepare commit
- commit.prepare(baseRev);
- success = true;
- } finally {
- if (!success) {
- b.removeCommit(rev);
- if (!b.hasCommits()) {
- nodeStore.getBranches().remove(b);
- }
- }
- }
- } else {
- commit.apply();
- success = true;
- }
+ rev = nodeStore.apply(commit);
+ success = true;
} finally {
if (!success) {
nodeStore.canceled(commit);
@@ -460,43 +435,7 @@ public class MongoMK implements MicroKer
if (!revision.isBranch()) {
throw new MicroKernelException("Not a branch: " + branchRevisionId);
}
- Branch b = nodeStore.getBranches().getBranch(revision);
- Revision base = revision;
- if (b != null) {
- base = b.getBase(revision);
- }
- boolean success = false;
- Commit commit = nodeStore.newCommit(base);
- try {
- // make branch commits visible
- UpdateOp op = new UpdateOp(Utils.getIdFromPath("/"), false);
- NodeDocument.setModified(op, commit.getRevision());
- if (b != null) {
- String commitTag = "c-" + commit.getRevision().toString();
- for (Revision rev : b.getCommits()) {
- rev = rev.asTrunkRevision();
- NodeDocument.setRevision(op, rev, commitTag);
- op.containsMapEntry(NodeDocument.COLLISIONS, rev, false);
- }
- if (store.findAndUpdate(Collection.NODES, op) != null) {
- // remove from branchCommits map after successful update
- b.applyTo(nodeStore.getPendingModifications(), commit.getRevision());
- nodeStore.getBranches().remove(b);
- } else {
- throw new MicroKernelException("Conflicting concurrent change. Update operation failed: " + op);
- }
- } else {
- // no commits in this branch -> do nothing
- }
- success = true;
- } finally {
- if (!success) {
- nodeStore.canceled(commit);
- } else {
- nodeStore.done(commit, false);
- }
- }
- return commit.getRevision().toString();
+ return nodeStore.merge(revision).toString();
}
@Override
@@ -504,24 +443,11 @@ public class MongoMK implements MicroKer
public String rebase(@Nonnull String branchRevisionId,
@Nullable String newBaseRevisionId)
throws MicroKernelException {
- // TODO conflict handling
Revision r = Revision.fromString(branchRevisionId);
Revision base = newBaseRevisionId != null ?
Revision.fromString(newBaseRevisionId) :
nodeStore.getHeadRevision();
- Branch b = nodeStore.getBranches().getBranch(r);
- if (b == null) {
- // empty branch
- return base.asBranchRevision().toString();
- }
- if (b.getBase().equals(base)) {
- return branchRevisionId;
- }
- // add a pseudo commit to make sure current head of branch
- // has a higher revision than base of branch
- Revision head = nodeStore.newRevision().asBranchRevision();
- b.rebase(head, base);
- return head.toString();
+ return nodeStore.rebase(r, base).toString();
}
@Override
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java?rev=1536758&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java Tue Oct 29 15:31:22 2013
@@ -0,0 +1,38 @@
+/*
+ * 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 org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder;
+
+/**
+ * A node builder implementation for MongoMK.
+ */
+class MongoNodeBuilder extends MemoryNodeBuilder {
+
+ protected MongoNodeBuilder(MongoNodeState base) {
+ super(base);
+ }
+
+ private MongoNodeBuilder(MongoNodeBuilder parent, String name) {
+ super(parent, name);
+ }
+
+ @Override
+ protected MongoNodeBuilder createChildBuilder(String name) {
+ return new MongoNodeBuilder(this, name);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeBuilder.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeState.java?rev=1536758&r1=1536757&r2=1536758&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeState.java Tue Oct 29 15:31:22 2013
@@ -81,7 +81,6 @@ class MongoNodeState extends AbstractNod
@Override
public boolean exists() {
- // TODO: implement
return true;
}
@@ -112,4 +111,7 @@ class MongoNodeState extends AbstractNod
// TODO: implement
return new MemoryNodeBuilder(this);
}
+
+ //------------------------------< internal >--------------------------------
+
}
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=1536758&r1=1536757&r2=1536758&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 Tue Oct 29 15:31:22 2013
@@ -495,8 +495,8 @@ public final class MongoNodeStore
}
}
- public Node.Children getChildren(final String path, final Revision rev, final int limit) throws
- MicroKernelException {
+ 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
@@ -728,10 +728,120 @@ public final class MongoNodeStore
* @return the root node state at the given revision.
*/
@Nonnull
- NodeState getRoot(@Nonnull Revision revision) {
+ MongoNodeState getRoot(@Nonnull Revision revision) {
return new MongoNodeState(this, "/", revision);
}
+ @Nonnull
+ MongoNodeStoreBranch createBranch(MongoNodeState base) {
+ return new MongoNodeStoreBranch(this, base);
+ }
+
+ @Nonnull
+ Revision rebase(@Nonnull Revision branchHead, @Nonnull Revision base) {
+ checkNotNull(branchHead);
+ checkNotNull(base);
+ // TODO conflict handling
+ Branch b = getBranches().getBranch(branchHead);
+ if (b == null) {
+ // empty branch
+ return base.asBranchRevision();
+ }
+ if (b.getBase().equals(base)) {
+ return branchHead;
+ }
+ // add a pseudo commit to make sure current head of branch
+ // has a higher revision than base of branch
+ Revision head = newRevision().asBranchRevision();
+ b.rebase(head, base);
+ return head;
+ }
+
+ @Nonnull
+ Revision merge(@Nonnull Revision branchHead) {
+ Branch b = getBranches().getBranch(branchHead);
+ Revision base = branchHead;
+ if (b != null) {
+ base = b.getBase(branchHead);
+ }
+ boolean success = false;
+ Commit commit = newCommit(base);
+ try {
+ // make branch commits visible
+ UpdateOp op = new UpdateOp(Utils.getIdFromPath("/"), false);
+ NodeDocument.setModified(op, commit.getRevision());
+ if (b != null) {
+ String commitTag = "c-" + commit.getRevision().toString();
+ for (Revision rev : b.getCommits()) {
+ rev = rev.asTrunkRevision();
+ NodeDocument.setRevision(op, rev, commitTag);
+ op.containsMapEntry(NodeDocument.COLLISIONS, rev, false);
+ }
+ if (store.findAndUpdate(Collection.NODES, op) != null) {
+ // remove from branchCommits map after successful update
+ b.applyTo(getPendingModifications(), commit.getRevision());
+ getBranches().remove(b);
+ } else {
+ // TODO: use non-MK exception type
+ throw new MicroKernelException("Conflicting concurrent change. Update operation failed: " + op);
+ }
+ } else {
+ // no commits in this branch -> do nothing
+ }
+ success = true;
+ } finally {
+ if (!success) {
+ canceled(commit);
+ } else {
+ done(commit, false);
+ }
+ }
+ return commit.getRevision();
+ }
+
+ /**
+ * Applies a commit to the store and updates the caches accordingly.
+ *
+ * @param commit the commit to apply.
+ * @return the commit revision.
+ * @throws MicroKernelException if the commit cannot be applied.
+ * TODO: use non-MK exception type
+ */
+ @Nonnull
+ Revision apply(@Nonnull Commit commit) throws MicroKernelException {
+ checkNotNull(commit);
+ boolean success = false;
+ Revision baseRev = commit.getBaseRevision();
+ boolean isBranch = baseRev != null && baseRev.isBranch();
+ Revision rev = commit.getRevision();
+ if (isBranch) {
+ rev = rev.asBranchRevision();
+ // remember branch commit
+ Branch b = getBranches().getBranch(baseRev);
+ if (b == null) {
+ // baseRev is marker for new branch
+ b = getBranches().create(baseRev.asTrunkRevision(), rev);
+ } else {
+ b.addCommit(rev);
+ }
+ try {
+ // prepare commit
+ commit.prepare(baseRev);
+ success = true;
+ } finally {
+ if (!success) {
+ b.removeCommit(rev);
+ if (!b.hasCommits()) {
+ getBranches().remove(b);
+ }
+ }
+ }
+ } else {
+ commit.apply();
+ }
+ return rev;
+ }
+
//------------------------< Observable >------------------------------------
@Override
@@ -743,7 +853,7 @@ public final class MongoNodeStore
@Nonnull
@Override
- public NodeState getRoot() {
+ public MongoNodeState getRoot() {
return getRoot(headRevision);
}
@@ -753,21 +863,18 @@ public final class MongoNodeStore
@Nonnull CommitHook commitHook,
@Nullable CommitInfo info)
throws CommitFailedException {
- // TODO: implement
- return null;
+ return asMongoRootBuilder(builder).merge(commitHook, info);
}
@Nonnull
@Override
public NodeState rebase(@Nonnull NodeBuilder builder) {
- // TODO: implement
- return null;
+ return asMongoRootBuilder(builder).rebase();
}
@Override
public NodeState reset(@Nonnull NodeBuilder builder) {
- // TODO: implement
- return null;
+ return asMongoRootBuilder(builder).reset();
}
@Override
@@ -1020,6 +1127,15 @@ public final class MongoNodeStore
//-----------------------------< internal >---------------------------------
+ private static MongoRootBuilder asMongoRootBuilder(NodeBuilder builder)
+ throws IllegalArgumentException {
+ if (!(builder instanceof MongoRootBuilder)) {
+ throw new IllegalArgumentException("builder must be a " +
+ MongoRootBuilder.class.getName());
+ }
+ return (MongoRootBuilder) builder;
+ }
+
private void moveOrCopyNode(boolean move,
String sourcePath,
String targetPath,
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java?rev=1536758&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java Tue Oct 29 15:31:22 2013
@@ -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.plugins.mongomk;
+
+import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
+import org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Implementation of a MongoMK based node store branch.
+ */
+public class MongoNodeStoreBranch
+ extends AbstractNodeStoreBranch<MongoNodeStore, MongoNodeState> {
+
+ public MongoNodeStoreBranch(MongoNodeStore store,
+ MongoNodeState base) {
+ super(store, new ChangeDispatcher(store), base);
+ }
+
+ @Override
+ protected MongoNodeState getRoot() {
+ return store.getRoot();
+ }
+
+ @Override
+ protected MongoNodeState createBranch(MongoNodeState state) {
+ return store.getRoot(state.getRevision().asBranchRevision());
+ }
+
+ @Override
+ protected MongoNodeState rebase(MongoNodeState branchHead,
+ MongoNodeState base) {
+ return store.getRoot(store.rebase(branchHead.getRevision(), base.getRevision()));
+ }
+
+ @Override
+ protected MongoNodeState merge(MongoNodeState branchHead) {
+ return store.getRoot(store.merge(branchHead.getRevision()));
+ }
+
+ @Override
+ protected MongoNodeState persist(NodeState toPersist, MongoNodeState base) {
+ // TODO
+ return null;
+ }
+
+ @Override
+ protected MongoNodeState copy(String source,
+ String target,
+ MongoNodeState base) {
+ boolean success = false;
+ Commit c = store.newCommit(base.getRevision());
+ Revision rev;
+ try {
+ store.copyNode(source, target, c);
+ rev = store.apply(c);
+ success = true;
+ } finally {
+ if (success) {
+ store.done(c, base.getRevision().isBranch());
+ } else {
+ store.canceled(c);
+ }
+ }
+ return store.getRoot(rev);
+ }
+
+ @Override
+ protected MongoNodeState move(String source,
+ String target,
+ MongoNodeState base) {
+ boolean success = false;
+ Commit c = store.newCommit(base.getRevision());
+ Revision rev;
+ try {
+ store.moveNode(source, target, c);
+ rev = store.apply(c);
+ success = true;
+ } finally {
+ if (success) {
+ store.done(c, base.getRevision().isBranch());
+ } else {
+ store.canceled(c);
+ }
+ }
+ return store.getRoot(rev);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoNodeStoreBranch.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java?rev=1536758&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java Tue Oct 29 15:31:22 2013
@@ -0,0 +1,153 @@
+/*
+ * 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 static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * This implementation tracks the number of pending changes and purges them to
+ * a private branch of the underlying store if a certain threshold is met.
+ */
+class MongoRootBuilder extends MongoNodeBuilder {
+
+ /**
+ * Number of content updates that need to happen before the updates
+ * are automatically purged to the private branch.
+ */
+ private static final int UPDATE_LIMIT = Integer.getInteger("update.limit", 1000);
+
+ /**
+ * The underlying store
+ */
+ private final MongoNodeStore store;
+
+ /**
+ * The base state of this builder, possibly non-existent if this builder
+ * represents a new node that didn't yet exist in the base content tree.
+ * This differs from the base state of super since the latter one reflects
+ * the base created by the last purge.
+ */
+ private NodeState base;
+
+ /**
+ * Private branch used to hold pending changes exceeding {@link #UPDATE_LIMIT}
+ */
+ private MongoNodeStoreBranch branch;
+
+ /**
+ * Number of updated not yet persisted to the private {@link #branch}
+ */
+ private int updates = 0;
+
+ MongoRootBuilder(MongoNodeState base, MongoNodeStore store) {
+ super(checkNotNull(base));
+ this.base = base;
+ this.store = store;
+ this.branch = store.createBranch(base);
+ }
+
+ //--------------------------------------------------< MemoryNodeBuilder >---
+
+
+ @Override
+ public NodeState getBaseState() {
+ return base;
+ }
+
+ @Override
+ public void reset(NodeState newBase) {
+ base = newBase;
+ super.reset(newBase);
+ }
+
+ @Override
+ protected void updated() {
+ if (updates++ > UPDATE_LIMIT) {
+ purge();
+ }
+ }
+
+ //------------------------------------------------------------< internal >---
+
+ /**
+ * Rebase this builder on top of the head of the underlying store
+ */
+ NodeState rebase() {
+ purge();
+ branch.rebase();
+ NodeState head = branch.getHead();
+ reset(head);
+ return head;
+ }
+
+ /**
+ * Reset this builder by creating a new branch and setting the head
+ * state of that branch as the new base state of this builder.
+ */
+ NodeState reset() {
+ branch = store.createBranch(store.getRoot());
+ NodeState head = branch.getHead();
+ reset(head);
+ return head;
+ }
+
+ /**
+ * Merge all changes tracked in this builder into the underlying store.
+ */
+ NodeState merge(CommitHook hook, CommitInfo info) throws CommitFailedException {
+ purge();
+ branch.merge(hook, info);
+ return reset();
+ }
+
+ /**
+ * Applied all pending changes to the underlying branch and then
+ * move the node as a separate operation on the underlying store.
+ * This allows stores to optimise move operations instead of
+ * seeing them as an added node followed by a deleted node.
+ */
+ boolean move(String source, String target) {
+ purge();
+ boolean success = branch.move(source, target);
+ super.reset(branch.getHead());
+ return success;
+ }
+
+ /**
+ * Applied all pending changes to the underlying branch and then
+ * copy the node as a separate operation on the underlying store.
+ * This allows stores to optimise copy operations instead of
+ * seeing them as an added node.
+ */
+ boolean copy(String source, String target) {
+ purge();
+ boolean success = branch.copy(source, target);
+ super.reset(branch.getHead());
+ return success;
+ }
+
+ private void purge() {
+ branch.setRoot(getNodeState());
+ super.reset(branch.getHead());
+ updates = 0;
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoRootBuilder.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL