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 12:57:13 UTC
svn commit: r1536679 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak:
kernel/KernelNodeStore.java kernel/KernelNodeStoreBranch.java
spi/state/AbstractNodeStoreBranch.java
Author: mreutegg
Date: Tue Oct 29 11:57:12 2013
New Revision: 1536679
URL: http://svn.apache.org/r1536679
Log:
OAK-1123: Reusable NodeStoreBranch base implementation
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java (contents, props changed)
- copied, changed from r1536363, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java?rev=1536679&r1=1536678&r2=1536679&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java Tue Oct 29 11:57:12 2013
@@ -248,8 +248,8 @@ public class KernelNodeStore implements
}
}
- NodeStoreBranch createBranch(NodeState base) {
- return new KernelNodeStoreBranch(this, mergeLock, (KernelNodeState) base);
+ NodeStoreBranch createBranch(KernelNodeState base) {
+ return new KernelNodeStoreBranch(this, changeDispatcher, mergeLock, base);
}
MicroKernel getKernel() {
@@ -257,6 +257,10 @@ public class KernelNodeStore implements
}
KernelNodeState commit(String jsop, KernelNodeState base) {
+ if (jsop.isEmpty()) {
+ // nothing to commit
+ return base;
+ }
KernelNodeState rootState = getRootState(kernel.commit("", jsop, base.getRevision(), null));
if (base.isBranch()) {
rootState.setBranch();
@@ -272,20 +276,7 @@ public class KernelNodeStore implements
return getRootState(kernel.rebase(branchHead.getRevision(), base.getRevision())).setBranch();
}
- NodeState merge(KernelNodeState branchHead) {
+ KernelNodeState merge(KernelNodeState branchHead) {
return getRootState(kernel.merge(branchHead.getRevision(), null));
}
-
- void beforeCommit(NodeState root) {
- changeDispatcher.beforeCommit(root);
- }
-
- void localCommit(NodeState root, CommitInfo info) {
- changeDispatcher.localCommit(root, info);
- }
-
- void afterCommit(NodeState root) {
- changeDispatcher.afterCommit(root);
- }
-
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java?rev=1536679&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java Tue Oct 29 11:57:12 2013
@@ -0,0 +1,134 @@
+/*
+ * 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.kernel;
+
+import java.io.IOException;
+import java.util.concurrent.locks.Lock;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * {@code NodeStoreBranch} based on {@link MicroKernel} branching and merging.
+ * This implementation keeps changes in memory up to a certain limit and writes
+ * them back to the Microkernel branch when the limit is exceeded.
+ */
+public class KernelNodeStoreBranch extends
+ AbstractNodeStoreBranch<KernelNodeStore, KernelNodeState> {
+
+ /** Lock for coordinating concurrent merge operations */
+ private final Lock mergeLock;
+
+ private final BlobSerializer blobs = new BlobSerializer() {
+ @Override
+ public String serialize(Blob blob) {
+ KernelBlob kernelBlob;
+ if (blob instanceof KernelBlob) {
+ kernelBlob = (KernelBlob) blob;
+ } else {
+ try {
+ kernelBlob = store.createBlob(blob.getNewStream());
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ return kernelBlob.getBinaryID();
+ }
+ };
+
+ public KernelNodeStoreBranch(KernelNodeStore kernelNodeStore,
+ ChangeDispatcher dispatcher,
+ Lock mergeLock,
+ KernelNodeState base) {
+ super(kernelNodeStore, dispatcher, base);
+ this.mergeLock = checkNotNull(mergeLock);
+ }
+
+ //----------------------< AbstractNodeStoreBranch >-------------------------
+
+ @Override
+ public KernelNodeState createBranch(KernelNodeState state) {
+ return store.branch(state);
+ }
+
+ @Override
+ public KernelNodeState getRoot() {
+ return store.getRoot();
+ }
+
+ @Override
+ protected KernelNodeState rebase(KernelNodeState branchHead,
+ KernelNodeState base) {
+ return store.rebase(branchHead, base);
+ }
+
+ @Override
+ protected KernelNodeState merge(KernelNodeState branchHead) {
+ return store.merge(branchHead);
+ }
+
+ @Override
+ protected KernelNodeState persist(NodeState toPersist, KernelNodeState base) {
+ JsopDiff diff = new JsopDiff(blobs);
+ toPersist.compareAgainstBaseState(base, diff);
+ return store.commit(diff.toString(), base);
+ }
+
+ @Override
+ protected KernelNodeState copy(String source,
+ String target,
+ KernelNodeState base) {
+ return store.commit("*\"" + source + "\":\"" + target + '"', base);
+ }
+
+ @Override
+ protected KernelNodeState move(String source,
+ String target,
+ KernelNodeState base) {
+ return store.commit(">\"" + source + "\":\"" + target + '"', base);
+ }
+
+//------------------------< NodeStoreBranch >-------------------------------
+
+ @Nonnull
+ @Override
+ public NodeState merge(@Nonnull CommitHook hook, @Nullable CommitInfo info)
+ throws CommitFailedException {
+ mergeLock.lock();
+ try {
+ return super.merge(hook, info);
+ } catch (MicroKernelException e) {
+ throw new CommitFailedException(
+ "Kernel", 1,
+ "Failed to merge changes to the underlying MicroKernel", e);
+ } finally {
+ mergeLock.unlock();
+ }
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Copied: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java (from r1536363, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java&r1=1536363&r2=1536679&rev=1536679&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java Tue Oct 29 11:57:12 2013
@@ -14,43 +14,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.jackrabbit.oak.kernel;
+package org.apache.jackrabbit.oak.spi.state;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
-import java.io.IOException;
-import java.util.concurrent.locks.Lock;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import org.apache.jackrabbit.mk.api.MicroKernel;
-import org.apache.jackrabbit.mk.api.MicroKernelException;
-import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.observation.ChangeDispatcher;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.state.ConflictAnnotatingRebaseDiff;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
/**
- * {@code NodeStoreBranch} based on {@link MicroKernel} branching and merging.
+ * A base implementation of a node store branch, which supports partially
+ * persisted branches.
+ * <p>
* This implementation keeps changes in memory up to a certain limit and writes
- * them back to the Microkernel branch when the limit is exceeded.
+ * them back to the underlying branch when the limit is exceeded.
*/
-class KernelNodeStoreBranch implements NodeStoreBranch {
+public abstract class AbstractNodeStoreBranch<S extends NodeStore, N extends NodeState>
+ implements NodeStoreBranch {
/** The underlying store to which this branch belongs */
- private final KernelNodeStore store;
+ protected final S store;
- /** Lock for coordinating concurrent merge operations */
- private final Lock mergeLock;
+ /** The dispatcher to report changes */
+ protected final ChangeDispatcher dispatcher;
/**
* State of the this branch. Either {@link Unmodified}, {@link InMemory}, {@link Persisted}
@@ -59,31 +53,97 @@ class KernelNodeStoreBranch implements N
*/
private BranchState branchState;
- private final BlobSerializer blobs = new BlobSerializer() {
- @Override
- public String serialize(Blob blob) {
- KernelBlob kernelBlob;
- if (blob instanceof KernelBlob) {
- kernelBlob = (KernelBlob) blob;
- } else {
- try {
- kernelBlob = store.createBlob(blob.getNewStream());
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
- return kernelBlob.getBinaryID();
- }
- };
-
- public KernelNodeStoreBranch(KernelNodeStore kernelNodeStore, Lock mergeLock,
- KernelNodeState base) {
+ public AbstractNodeStoreBranch(S kernelNodeStore,
+ ChangeDispatcher dispatcher,
+ N base) {
this.store = checkNotNull(kernelNodeStore);
- this.mergeLock = checkNotNull(mergeLock);
+ this.dispatcher = dispatcher;
branchState = new Unmodified(checkNotNull(base));
}
+ /**
+ * @return the current root of the underlying store.
+ */
+ protected abstract N getRoot();
+
+ /**
+ * Create a new branch state from the given state.
+ *
+ * @param state the state from where to create a branch from.
+ * @return the branch state.
+ */
+ protected abstract N createBranch(N state);
+
+ /**
+ * Rebases the branch head to the given base.
+ *
+ * @param branchHead the head state of a branch.
+ * @param base the new base state for the branch.
+ * @return the rebased branch head.
+ */
+ protected abstract N rebase(N branchHead, N base);
+
+ /**
+ * Merges the branch head and returns the result state of the merge.
+ *
+ * @param branchHead the head of the branch to merge.
+ * @return the result state of the merge.
+ */
+ protected abstract N merge(N branchHead);
+
+ /**
+ * Persists the changes between <code>toPersist</code> and <code>base</code>
+ * to the underlying store.
+ * <p>
+ * While this method does not declare any exceptions to be thrown, an
+ * implementation may still throw a runtime exception specific to the
+ * concrete implementation of this node store branch.
+ *
+ * @param toPersist the state with the changes on top of <code>base</code>.
+ * @param base the base state.
+ * @return the state with the persisted changes.
+ */
+ protected abstract N persist(NodeState toPersist, N base);
+
+ /**
+ * Perform a potentially optimized copy operation directly on the underlying
+ * store.
+ * <p>
+ * This base class ensures that preconditions are met (e.g. the source
+ * exists), which means an implementation of this method just needs to
+ * perform the copy operation.
+ * <p>
+ * While this method does not declare any exceptions to be thrown, an
+ * implementation may still throw a runtime exception specific to the
+ * concrete implementation of this node store branch.
+ *
+ * @param source the source of the copy operation.
+ * @param target the destination of the copy operation.
+ * @param base the base state.
+ * @return the result of the copy operation.
+ */
+ protected abstract N copy(String source, String target, N base);
+
+ /**
+ * Perform a potentially optimized move operation directly on the underlying
+ * store.
+ * <p>
+ * This base class ensures that preconditions are met (e.g. the source
+ * exists), which means an implementation of this method just needs to
+ * perform the move operation.
+ * <p>
+ * While this method does not declare any exceptions to be thrown, an
+ * implementation may still throw a runtime exception specific to the
+ * concrete implementation of this node store branch.
+ *
+ * @param source the source of the move operation.
+ * @param target the destination of the move operation.
+ * @param base the base state.
+ * @return the result of the move operation.
+ */
+ protected abstract N move(String source, String target, N base);
+
@Override
public String toString() {
return branchState.toString();
@@ -127,7 +187,7 @@ class KernelNodeStoreBranch implements N
// destination exists already
return false;
}
- branchState.persist().commit(">\"" + source + "\":\"" + target + '"');
+ branchState.persist().move(source, target);
return true;
}
@@ -146,7 +206,7 @@ class KernelNodeStoreBranch implements N
// destination exists already
return false;
}
- branchState.persist().commit("*\"" + source + "\":\"" + target + '"');
+ branchState.persist().copy(source, target);
return true;
}
@@ -162,6 +222,8 @@ class KernelNodeStoreBranch implements N
branchState.rebase();
}
+ //----------------------------< internal >----------------------------------
+
private NodeState getNode(String path) {
NodeState node = getHead();
for (String name : elements(path)) {
@@ -176,9 +238,9 @@ class KernelNodeStoreBranch implements N
*/
private abstract class BranchState {
/** Root state of the base revision of this branch */
- protected KernelNodeState base;
+ protected N base;
- protected BranchState(KernelNodeState base) {
+ protected BranchState(N base) {
this.base = base;
}
@@ -186,11 +248,12 @@ class KernelNodeStoreBranch implements N
* Persist this branch to an underlying branch in the {@code MicroKernel}.
*/
Persisted persist() {
- branchState = new Persisted(base, getHead());
- return (Persisted) branchState;
+ Persisted p = new Persisted(base, getHead());
+ branchState = p;
+ return p;
}
- KernelNodeState getBase(){
+ N getBase(){
return base;
}
@@ -201,6 +264,21 @@ class KernelNodeStoreBranch implements N
abstract void rebase();
+ /**
+ * Runs the commit hook on the changes tracked with this branch state
+ * merges the result.
+ * <p>
+ * In addition to the {@link CommitFailedException}, an implementation
+ * may also throw an unchecked exception when an error occurs while
+ * persisting the changes. This exception is implementation specific
+ * and it is the responsibility of the caller to convert it into a
+ * {@link CommitFailedException}.
+ *
+ * @param hook the commit hook to run.
+ * @param info the associated commit info.
+ * @return the result of the merge.
+ * @throws CommitFailedException if a commit hook rejected the changes.
+ */
@Nonnull
abstract NodeState merge(@Nonnull CommitHook hook, @Nullable CommitInfo info)
throws CommitFailedException;
@@ -217,7 +295,7 @@ class KernelNodeStoreBranch implements N
* </ul>
*/
private class Unmodified extends BranchState {
- Unmodified(KernelNodeState base) {
+ Unmodified(N base) {
super(base);
}
@@ -227,6 +305,7 @@ class KernelNodeStoreBranch implements N
}
@Override
+ @Nonnull
NodeState getHead() {
return base;
}
@@ -240,11 +319,12 @@ class KernelNodeStoreBranch implements N
@Override
void rebase() {
- base = store.getRoot();
+ base = getRoot();
}
@Override
- NodeState merge(CommitHook hook, CommitInfo info) throws CommitFailedException {
+ @Nonnull
+ NodeState merge(@Nonnull CommitHook hook, CommitInfo info) {
branchState = new Merged(base);
return base;
}
@@ -271,12 +351,13 @@ class KernelNodeStoreBranch implements N
return "InMemory[" + base + ", " + head + ']';
}
- InMemory(KernelNodeState base, NodeState head) {
+ InMemory(N base, NodeState head) {
super(base);
this.head = head;
}
@Override
+ @Nonnull
NodeState getHead() {
return head;
}
@@ -293,7 +374,7 @@ class KernelNodeStoreBranch implements N
@Override
void rebase() {
- KernelNodeState root = store.getRoot();
+ N root = getRoot();
NodeBuilder builder = root.builder();
head.compareAgainstBaseState(base, new ConflictAnnotatingRebaseDiff(builder));
head = builder.getNodeState();
@@ -301,25 +382,19 @@ class KernelNodeStoreBranch implements N
}
@Override
- NodeState merge(CommitHook hook, CommitInfo info) throws CommitFailedException {
- mergeLock.lock();
+ @Nonnull
+ NodeState merge(@Nonnull CommitHook hook, CommitInfo info)
+ throws CommitFailedException {
try {
rebase();
- store.beforeCommit(base);
+ dispatcher.beforeCommit(base);
NodeState toCommit = checkNotNull(hook).processCommit(base, head);
- JsopDiff diff = new JsopDiff(blobs);
- toCommit.compareAgainstBaseState(base, diff);
- NodeState newHead = store.commit(diff.toString(), base);
- store.localCommit(newHead, info);
+ NodeState newHead = AbstractNodeStoreBranch.this.persist(toCommit, base);
+ dispatcher.localCommit(newHead, info);
branchState = new Merged(base);
return newHead;
- } catch (MicroKernelException e) {
- throw new CommitFailedException(
- "Kernel", 1,
- "Failed to merge changes to the underlying MicroKernel", e);
} finally {
- store.afterCommit(store.getRoot());
- mergeLock.unlock();
+ dispatcher.afterCommit(getRoot());
}
}
}
@@ -337,26 +412,29 @@ class KernelNodeStoreBranch implements N
*/
private class Persisted extends BranchState {
/** Root state of the transient head, top of persisted branch. */
- private KernelNodeState head;
+ private N head;
@Override
public String toString() {
return "Persisted[" + base + ", " + head + ']';
}
- Persisted(KernelNodeState base, NodeState head) {
+ Persisted(N base, NodeState head) {
super(base);
- this.head = store.branch(base);
+ this.head = createBranch(base);
persistTransientHead(head);
}
- void commit(String jsop) {
- if (!jsop.isEmpty()) {
- head = store.commit(jsop, head);
- }
+ void move(String source, String target) {
+ head = AbstractNodeStoreBranch.this.move(source, target, head);
+ }
+
+ void copy(String source, String target) {
+ head = AbstractNodeStoreBranch.this.copy(source, target, head);
}
@Override
+ @Nonnull
NodeState getHead() {
return head;
}
@@ -372,52 +450,43 @@ class KernelNodeStoreBranch implements N
@Override
void rebase() {
- KernelNodeState root = store.getRoot();
+ N root = getRoot();
if (head.equals(root)) {
// Nothing was written to this branch: set new base revision
head = root;
base = root;
} else {
- // perform rebase in kernel
- head = store.rebase(head, root);
+ // perform rebase in store
+ head = AbstractNodeStoreBranch.this.rebase(head, root);
base = root;
}
}
@Override
- NodeState merge(CommitHook hook, CommitInfo info) throws CommitFailedException {
- mergeLock.lock();
+ @Nonnull
+ NodeState merge(@Nonnull CommitHook hook, CommitInfo info) throws CommitFailedException {
try {
rebase();
- store.beforeCommit(base);
+ dispatcher.beforeCommit(base);
NodeState toCommit = checkNotNull(hook).processCommit(base, head);
if (toCommit.equals(base)) {
branchState = new Merged(base);
return base;
} else {
- JsopDiff diff = new JsopDiff(blobs);
- toCommit.compareAgainstBaseState(head, diff);
- commit(diff.toString());
- NodeState newRoot = store.merge(head);
- store.localCommit(newRoot, info);
+ head = AbstractNodeStoreBranch.this.persist(toCommit, head);
+ NodeState newRoot = AbstractNodeStoreBranch.this.merge(head);
+ dispatcher.localCommit(newRoot, info);
branchState = new Merged(base);
return newRoot;
}
- } catch (MicroKernelException e) {
- throw new CommitFailedException(
- "Kernel", 1,
- "Failed to merge changes to the underlying MicroKernel", e);
} finally {
- store.afterCommit(store.getRoot());
- mergeLock.unlock();
+ dispatcher.afterCommit(getRoot());
}
}
private void persistTransientHead(NodeState newHead) {
if (!newHead.equals(head)) {
- JsopDiff diff = new JsopDiff(blobs);
- newHead.compareAgainstBaseState(head, diff);
- head = store.commit(diff.toString(), head);
+ head = AbstractNodeStoreBranch.this.persist(newHead, head);
}
}
}
@@ -429,7 +498,7 @@ class KernelNodeStoreBranch implements N
* Transitions to: none.
*/
private class Merged extends BranchState {
- protected Merged(KernelNodeState base) {
+ protected Merged(N base) {
super(base);
}
@@ -439,6 +508,7 @@ class KernelNodeStoreBranch implements N
}
@Override
+ @Nonnull
NodeState getHead() {
throw new IllegalStateException("Branch has already been merged");
}
@@ -454,7 +524,8 @@ class KernelNodeStoreBranch implements N
}
@Override
- NodeState merge(CommitHook hook, CommitInfo info) throws CommitFailedException {
+ @Nonnull
+ NodeState merge(@Nonnull CommitHook hook, CommitInfo info) {
throw new IllegalStateException("Branch has already been merged");
}
}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/AbstractNodeStoreBranch.java
------------------------------------------------------------------------------
svn:eol-style = native