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());
     }