Return-Path: X-Original-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Delivered-To: apmail-jackrabbit-oak-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D2578106EE for ; Tue, 29 Oct 2013 15:33:41 +0000 (UTC) Received: (qmail 35927 invoked by uid 500); 29 Oct 2013 15:31:52 -0000 Delivered-To: apmail-jackrabbit-oak-commits-archive@jackrabbit.apache.org Received: (qmail 35913 invoked by uid 500); 29 Oct 2013 15:31:51 -0000 Mailing-List: contact oak-commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: oak-dev@jackrabbit.apache.org Delivered-To: mailing list oak-commits@jackrabbit.apache.org Received: (qmail 35904 invoked by uid 99); 29 Oct 2013 15:31:50 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 29 Oct 2013 15:31:50 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 29 Oct 2013 15:31:45 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 73DCA2388A02; Tue, 29 Oct 2013 15:31:23 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Tue, 29 Oct 2013 15:31:23 -0000 To: oak-commits@jackrabbit.apache.org From: mreutegg@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131029153123.73DCA2388A02@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 { + + 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