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 2013/10/18 22:24:44 UTC
svn commit: r1533617 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/kernel/
main/java/org/apache/jackrabbit/oak/plugins/memory/
test/java/org/apache/jackrabbit/oak/kernel/
Author: jukka
Date: Fri Oct 18 20:24:44 2013
New Revision: 1533617
URL: http://svn.apache.org/r1533617
Log:
OAK-987: Implement the MicroKernel API
Various JSON/P cleanups
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/BlobSerializer.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsonSerializer.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStoreBranch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/NodeStoreKernel.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/JsopDiffTest.java
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/BlobSerializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/BlobSerializer.java?rev=1533617&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/BlobSerializer.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/BlobSerializer.java Fri Oct 18 20:24:44 2013
@@ -0,0 +1,31 @@
+/*
+ * 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 org.apache.jackrabbit.oak.api.Blob;
+
+/**
+ * Customizable mechanism for mapping {@link Blob} instances to corresponding
+ * serialization identifiers.
+ */
+class BlobSerializer {
+
+ public String serialize(Blob blob) {
+ return "Blob{" + blob + '}';
+ }
+
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsonSerializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsonSerializer.java?rev=1533617&r1=1533616&r2=1533617&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsonSerializer.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsonSerializer.java Fri Oct 18 20:24:44 2013
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.kernel
import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.jackrabbit.oak.api.Type.BINARY;
import static org.apache.jackrabbit.oak.api.Type.BOOLEAN;
-import static org.apache.jackrabbit.oak.api.Type.DOUBLE;
import static org.apache.jackrabbit.oak.api.Type.LONG;
import static org.apache.jackrabbit.oak.api.Type.STRING;
@@ -48,27 +47,32 @@ class JsonSerializer {
private final boolean includeChildNodeCount;
+ private final BlobSerializer blobs;
+
private JsonSerializer(
JsopBuilder json, int depth, long offset, int maxChildNodes,
- boolean includeChildNodeCount) {
+ boolean includeChildNodeCount, BlobSerializer blobs) {
this.json = checkNotNull(json);
this.depth = depth;
this.offset = offset;
this.maxChildNodes = maxChildNodes;
this.includeChildNodeCount = includeChildNodeCount;
+ this.blobs = checkNotNull(blobs);
}
- JsonSerializer(int depth, long offset, int maxChildNodes) {
- this(new JsopBuilder(), depth, offset, maxChildNodes, true);
+ JsonSerializer(
+ int depth, long offset, int maxChildNodes, BlobSerializer blobs) {
+ this(new JsopBuilder(), depth, offset, maxChildNodes, true, blobs);
}
- JsonSerializer(JsopBuilder json) {
- this(json, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, false);
+ JsonSerializer(JsopBuilder json, BlobSerializer blobs) {
+ this(json, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, false, blobs);
}
protected JsonSerializer getChildSerializer() {
return new JsonSerializer(
- json, depth - 1, 0, maxChildNodes, includeChildNodeCount);
+ json, depth - 1, 0, maxChildNodes,
+ includeChildNodeCount, blobs);
}
protected String getBlobId(Blob blob) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java?rev=1533617&r1=1533616&r2=1533617&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/JsopDiff.java Fri Oct 18 20:24:44 2013
@@ -16,10 +16,7 @@
*/
package org.apache.jackrabbit.oak.kernel;
-import java.io.IOException;
-
import org.apache.jackrabbit.mk.json.JsopBuilder;
-import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -30,40 +27,29 @@ import org.apache.jackrabbit.oak.spi.sta
*/
public class JsopDiff implements NodeStateDiff {
- private final KernelNodeStore store;
-
private final JsopBuilder jsop;
+ private final BlobSerializer blobs;
+
protected final String path;
- JsopDiff(KernelNodeStore store, JsopBuilder jsop, String path) {
- this.store = store;
+ private JsopDiff(JsopBuilder jsop, String path, BlobSerializer blobs) {
this.jsop = jsop;
this.path = path;
+ this.blobs = blobs;
}
- JsopDiff(KernelNodeStore store) {
- this(store, new JsopBuilder(), "/");
+
+ JsopDiff(BlobSerializer blobs) {
+ this(new JsopBuilder(), "/", blobs);
}
- /**
- * Create the jsop diff between {@code before} and {@code after} and
- * stores binaries to {@code store}.
- *
- * @param store node store for storing binaries.
- * @param before before node state
- * @param after after node state
- * @param path base path
- * @param jsop builder to feed in the diff
- */
- public static void diffToJsop(
- KernelNodeStore store, NodeState before, NodeState after,
- String path, JsopBuilder jsop) {
- after.compareAgainstBaseState(before, new JsopDiff(store, jsop, path));
+ JsopDiff() {
+ this(new BlobSerializer());
}
/**
- * Create the jsop diff between {@code before} and {@code after} for
+ * Create the JSOP diff between {@code before} and {@code after} for
* debugging purposes.
* <p>
* This method does not store binaries but returns them inlined
@@ -75,48 +61,24 @@ public class JsopDiff implements NodeSta
* @return jsop diff between {@code before} and {@code after}
*/
public static String diffToJsop(NodeState before, NodeState after) {
- class ToStringDiff extends JsopDiff {
- public ToStringDiff() {
- super(null);
- }
-
- public ToStringDiff(JsopBuilder jsop, String path) {
- super(null, jsop, path);
- }
-
- @Override
- protected String writeBlob(Blob blob) {
- return "Blob{" + blob + '}';
- }
-
- @Override
- protected JsopDiff createChildDiff(JsopBuilder jsop, String path) {
- return new ToStringDiff(jsop, path);
- }
- }
-
- JsopDiff diff = new ToStringDiff();
+ JsopDiff diff = new JsopDiff();
after.compareAgainstBaseState(before, diff);
return diff.toString();
}
- protected JsopDiff createChildDiff(JsopBuilder jsop, String path) {
- return new JsopDiff(store, jsop, path);
- }
-
//-----------------------------------------------------< NodeStateDiff >--
@Override
public boolean propertyAdded(PropertyState after) {
jsop.tag('^').key(buildPath(after.getName()));
- new DiffJsonSerializer().serialize(after);
+ new JsonSerializer(jsop, blobs).serialize(after);
return true;
}
@Override
public boolean propertyChanged(PropertyState before, PropertyState after) {
jsop.tag('^').key(buildPath(after.getName()));
- new DiffJsonSerializer().serialize(after);
+ new JsonSerializer(jsop, blobs).serialize(after);
return true;
}
@@ -129,7 +91,7 @@ public class JsopDiff implements NodeSta
@Override
public boolean childNodeAdded(String name, NodeState after) {
jsop.tag('+').key(buildPath(name));
- new DiffJsonSerializer().serialize(after);
+ new JsonSerializer(jsop, blobs).serialize(after);
return true;
}
@@ -141,8 +103,8 @@ public class JsopDiff implements NodeSta
@Override
public boolean childNodeChanged(String name, NodeState before, NodeState after) {
- String path = buildPath(name);
- after.compareAgainstBaseState(before, createChildDiff(jsop, path));
+ after.compareAgainstBaseState(
+ before, new JsopDiff(jsop, buildPath(name), blobs));
return true;
}
@@ -159,50 +121,4 @@ public class JsopDiff implements NodeSta
return PathUtils.concat(path, name);
}
- /**
- * Make sure {@code blob} is persisted and return the id of
- * the persisted blob.
- *
- * @param blob blob to persist
- * @return id of the persisted blob
- */
- protected String writeBlob(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();
- }
-
- private class DiffJsonSerializer extends JsonSerializer {
-
- DiffJsonSerializer() {
- super(jsop);
- }
-
- @Override
- protected JsonSerializer getChildSerializer() {
- return new DiffJsonSerializer();
- }
-
- /**
- * Make sure {@code blob} is persisted and return the id of
- * the persisted blob.
- *
- * @param blob blob to persist
- * @return id of the persisted blob
- */
- @Override
- protected String getBlobId(Blob blob) {
- return writeBlob(blob);
- }
-
- }
-
}
\ No newline at end of file
Modified: 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=1533617&r1=1533616&r2=1533617&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/kernel/KernelNodeStoreBranch.java Fri Oct 18 20:24:44 2013
@@ -21,12 +21,14 @@ import static org.apache.jackrabbit.oak.
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 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.spi.commit.CommitHook;
@@ -56,6 +58,23 @@ 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) {
@@ -287,7 +306,7 @@ class KernelNodeStoreBranch implements N
rebase();
store.beforeCommit(base);
NodeState toCommit = checkNotNull(hook).processCommit(base, head);
- JsopDiff diff = new JsopDiff(store);
+ JsopDiff diff = new JsopDiff(blobs);
toCommit.compareAgainstBaseState(base, diff);
NodeState newHead = store.commit(diff.toString(), base);
store.localCommit(newHead, info);
@@ -375,7 +394,7 @@ class KernelNodeStoreBranch implements N
branchState = new Merged(base);
return base;
} else {
- JsopDiff diff = new JsopDiff(store);
+ JsopDiff diff = new JsopDiff(blobs);
toCommit.compareAgainstBaseState(head, diff);
commit(diff.toString());
NodeState newRoot = store.merge(head);
@@ -395,7 +414,7 @@ class KernelNodeStoreBranch implements N
private void persistTransientHead(NodeState newHead) {
if (!newHead.equals(head)) {
- JsopDiff diff = new JsopDiff(store);
+ JsopDiff diff = new JsopDiff(blobs);
newHead.compareAgainstBaseState(head, diff);
head = store.commit(diff.toString(), head);
}
@@ -438,4 +457,5 @@ class KernelNodeStoreBranch implements N
throw new IllegalStateException("Branch has already been merged");
}
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/NodeStoreKernel.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/NodeStoreKernel.java?rev=1533617&r1=1533616&r2=1533617&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/NodeStoreKernel.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/NodeStoreKernel.java Fri Oct 18 20:24:44 2013
@@ -39,12 +39,14 @@ import org.apache.jackrabbit.oak.api.Blo
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.AbstractBlob;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import com.google.common.hash.HashCode;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
@@ -62,6 +64,15 @@ public class NodeStoreKernel implements
private final Map<String, Blob> blobs = newConcurrentMap();
+ private final BlobSerializer blobSerializer = new BlobSerializer() {
+ @Override
+ public String serialize(Blob blob) {
+ String id = AbstractBlob.calculateSha256(blob).toString();
+ blobs.put(id, blob);
+ return id;
+ }
+ };
+
private String head;
public NodeStoreKernel(NodeStore store) {
@@ -303,7 +314,7 @@ public class NodeStoreKernel implements
NodeState before = getRoot(fromRevisionId);
NodeState after = getRoot(toRevisionId);
- JsopDiff diff = new JsopDiff(null);
+ JsopDiff diff = new JsopDiff();
after.compareAgainstBaseState(before, diff);
return diff.toString();
}
@@ -340,8 +351,8 @@ public class NodeStoreKernel implements
if (maxChildNodes < 0) {
maxChildNodes = Integer.MAX_VALUE;
}
- JsonSerializer json =
- new JsonSerializer(depth, offset, maxChildNodes);
+ JsonSerializer json = new JsonSerializer(
+ depth, offset, maxChildNodes, blobSerializer);
json.serialize(node);
return json.toString();
} else {
@@ -464,26 +475,43 @@ public class NodeStoreKernel implements
public String write(InputStream in) throws MicroKernelException {
try {
final Hasher hasher = Hashing.sha256().newHasher();
- Blob blob = store.createBlob(new CheckedInputStream(in, new Checksum() {
- @Override
- public void update(byte[] b, int off, int len) {
- hasher.putBytes(b, off, len);
- }
- @Override
- public void update(int b) {
- hasher.putByte((byte) b);
- }
- @Override
- public void reset() {
- throw new UnsupportedOperationException();
- }
- @Override
- public long getValue() {
- throw new UnsupportedOperationException();
- }
- }));
+ Blob blob = store.createBlob(
+ new CheckedInputStream(in, new Checksum() {
+ @Override
+ public void update(byte[] b, int off, int len) {
+ hasher.putBytes(b, off, len);
+ }
+ @Override
+ public void update(int b) {
+ hasher.putByte((byte) b);
+ }
+ @Override
+ public void reset() {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public long getValue() {
+ throw new UnsupportedOperationException();
+ }
+ }));
+ HashCode hash = hasher.hash();
+
+ // wrap into AbstractBlob for the SHA-256 memorization feature
+ if (!(blob instanceof AbstractBlob)) {
+ final Blob b = blob;
+ blob = new AbstractBlob(hash) {
+ @Override
+ public long length() {
+ return b.length();
+ }
+ @Override
+ public InputStream getNewStream() {
+ return b.getNewStream();
+ }
+ };
+ }
- String id = hasher.hash().toString();
+ String id = hash.toString();
blobs.put(id, blob);
return id;
} catch (IOException e) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java?rev=1533617&r1=1533616&r2=1533617&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/AbstractBlob.java Fri Oct 18 20:24:44 2013
@@ -64,7 +64,15 @@ public abstract class AbstractBlob imple
}
}
- private HashCode hashCode = null; // synchronized access
+ private HashCode hashCode; // synchronized access
+
+ protected AbstractBlob(HashCode hashCode) {
+ this.hashCode = hashCode;
+ }
+
+ protected AbstractBlob() {
+ this(null);
+ }
private synchronized HashCode getSha256() {
// Blobs are immutable so we can safely cache the hash
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/JsopDiffTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/JsopDiffTest.java?rev=1533617&r1=1533616&r2=1533617&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/JsopDiffTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/JsopDiffTest.java Fri Oct 18 20:24:44 2013
@@ -35,23 +35,23 @@ public class JsopDiffTest {
JsopDiff diff;
PropertyState before = StringPropertyState.stringProperty("foo", "bar");
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.propertyAdded(before);
assertEquals("^\"/foo\":\"bar\"", diff.toString());
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.propertyChanged(before, LongPropertyState.createLongProperty("foo", 123L));
assertEquals("^\"/foo\":123", diff.toString());
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.propertyChanged(before, DoublePropertyState.doubleProperty("foo", 1.23));
assertEquals("^\"/foo\":\"dou:1.23\"", diff.toString()); // TODO: 1.23?
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.propertyChanged(before, BooleanPropertyState.booleanProperty("foo", true));
assertEquals("^\"/foo\":true", diff.toString());
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.propertyDeleted(before);
assertEquals("^\"/foo\":null", diff.toString());
}
@@ -65,15 +65,15 @@ public class JsopDiffTest {
builder.child("x");
NodeState after = builder.getNodeState();
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.childNodeAdded("test", before);
assertEquals("+\"/test\":{}", diff.toString());
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.childNodeChanged("test", before, after);
assertEquals("^\"/test/a\":1+\"/test/x\":{}", diff.toString());
- diff = new JsopDiff(null);
+ diff = new JsopDiff();
diff.childNodeDeleted("test", after);
assertEquals("-\"/test\"", diff.toString());
}