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 ju...@apache.org on 2012/05/16 10:30:52 UTC
svn commit: r1339056 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak:
plugins/memory/MemoryNodeStateBuilder.java
plugins/memory/MemoryNodeStore.java plugins/memory/ModifiedNodeState.java
spi/state/DefaultNodeStateDiff.java
Author: jukka
Date: Wed May 16 08:30:51 2012
New Revision: 1339056
URL: http://svn.apache.org/viewvc?rev=1339056&view=rev
Log:
OAK-68: Extension point for commit validation
Add rebase handling to the in-memory draft
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java?rev=1339056&r1=1339055&r2=1339056&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java Wed May 16 08:30:51 2012
@@ -46,10 +46,14 @@ public class MemoryNodeStateBuilder impl
@Override
public NodeState getNodeState() {
- return new ModifiedNodeState(
- base,
- new HashMap<String, PropertyState>(properties),
- new HashMap<String, NodeState>(nodes));
+ if (properties.isEmpty() && nodes.isEmpty()) {
+ return base; // shortcut
+ } else {
+ return new ModifiedNodeState(
+ base,
+ new HashMap<String, PropertyState>(properties),
+ new HashMap<String, NodeState>(nodes));
+ }
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java?rev=1339056&r1=1339055&r2=1339056&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java Wed May 16 08:30:51 2012
@@ -57,14 +57,22 @@ public class MemoryNodeStore extends Abs
@Override
public void setRoot(NodeState newRoot) throws CommitFailedException {
- while (true) {
- NodeState oldRoot = getRoot();
- NodeState setRoot = commitHook.beforeCommit(this, oldRoot, newRoot);
- if (root.compareAndSet(oldRoot, setRoot)) {
- return;
- } else {
- // TODO: try to rebase the changes in newRoot
- }
+ NodeState oldRoot;
+ do {
+ oldRoot = root.get();
+ newRoot = rebase(newRoot, oldRoot);
+ } while (!root.compareAndSet(
+ oldRoot, commitHook.beforeCommit(this, oldRoot, newRoot)));
+ }
+
+ NodeState rebase(NodeState state, NodeState base)
+ throws CommitFailedException {
+ if (state instanceof ModifiedNodeState) {
+ return ((ModifiedNodeState) state).rebase(this, base);
+ } else if (state.equals(base)) {
+ return state;
+ } else {
+ throw new CommitFailedException("Failed to rebase changes");
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java?rev=1339056&r1=1339055&r2=1339056&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/ModifiedNodeState.java Wed May 16 08:30:51 2012
@@ -16,14 +16,17 @@
*/
package org.apache.jackrabbit.oak.plugins.memory;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.ProxyNodeState;
@@ -42,6 +45,64 @@ public class ModifiedNodeState extends P
this.nodes = nodes;
}
+ NodeState getBase() {
+ return delegate;
+ }
+
+ ModifiedNodeState rebase(MemoryNodeStore store, NodeState base)
+ throws CommitFailedException {
+ if (delegate.equals(base)) {
+ return this;
+ } else if (nodes.isEmpty()) {
+ return this; // shortcut
+ } else {
+ return new ModifiedNodeState(
+ base, properties, rebaseChildren(store, base));
+ }
+ }
+
+ private Map<String, NodeState> rebaseChildren(
+ final MemoryNodeStore store, NodeState base)
+ throws CommitFailedException {
+ // TODO: better conflict resolution
+ final Map<String, NodeState> rebasedNodes =
+ new HashMap<String, NodeState>(nodes);
+ final Map<String, CommitFailedException> failures =
+ new HashMap<String, CommitFailedException>();
+ store.compare(delegate, base, new DefaultNodeStateDiff() {
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ rebaseChild(name, after);
+ }
+ @Override
+ public void childNodeChanged(
+ String name, NodeState before, NodeState after) {
+ rebaseChild(name, after);
+ }
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ rebaseChild(name, MemoryNodeState.EMPTY_NODE);
+ }
+ private void rebaseChild(String name, NodeState base) {
+ NodeState child = nodes.get(name);
+ if (child != null) {
+ try {
+ rebasedNodes.put(name, store.rebase(child, base));
+ } catch (CommitFailedException e) {
+ failures.put(name, e);
+ }
+ }
+ }
+ });
+ if (failures.isEmpty()) {
+ return rebasedNodes;
+ } else {
+ throw new CommitFailedException("Failed to rebase changes");
+ }
+ }
+
+ //---------------------------------------------------------< NodeState >--
+
@Override
public PropertyState getProperty(String name) {
if (properties.containsKey(name)) {
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java?rev=1339056&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/DefaultNodeStateDiff.java Wed May 16 08:30:51 2012
@@ -0,0 +1,62 @@
+/*
+ * 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.spi.state;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+
+/**
+ * Node state diff handler that by default does nothing. Useful as a base
+ * class for more complicated diff handlers that can safely ignore one or
+ * more types of changes.
+ */
+public class DefaultNodeStateDiff implements NodeStateDiff {
+
+ public static final NodeStateDiff INSTANCE = new DefaultNodeStateDiff();
+
+ @Override
+ public void propertyAdded(PropertyState after) {
+ // do nothing
+ }
+
+ @Override
+ public void propertyChanged(PropertyState before, PropertyState after) {
+ // do nothing
+ }
+
+ @Override
+ public void propertyDeleted(PropertyState before) {
+ // do nothing
+ }
+
+ @Override
+ public void childNodeAdded(String name, NodeState after) {
+ // do nothing
+ }
+
+ @Override
+ public void childNodeChanged(String name, NodeState before, NodeState after) {
+ // do nothing
+ }
+
+ @Override
+ public void childNodeDeleted(String name, NodeState before) {
+ // do nothing
+ }
+
+}