You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/05/25 18:52:48 UTC

[01/10] tinkerpop git commit: TINKERPOP-1675 Throw underlying unchecked exception in processNextStart [Forced Update!]

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1676 5c88c0bc9 -> f32d725a0 (forced update)


TINKERPOP-1675 Throw underlying unchecked exception in processNextStart

For consistency with previous behavior, if an unchecked exception is
set on the returned future throw that instead of the wrapped
CompletionException.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6813e9ef
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6813e9ef
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6813e9ef

Branch: refs/heads/TINKERPOP-1676
Commit: 6813e9efd86a4d032d3106000fb5e805deb26454
Parents: afa3432
Author: Andrew Tolbert <an...@datastax.com>
Authored: Mon May 22 12:14:15 2017 -0500
Committer: Andrew Tolbert <an...@datastax.com>
Committed: Mon May 22 12:20:27 2017 -0500

----------------------------------------------------------------------
 .../remote/traversal/step/map/RemoteStep.java    | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6813e9ef/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/step/map/RemoteStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/step/map/RemoteStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/step/map/RemoteStep.java
index 3e19097..8f7d12b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/step/map/RemoteStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/step/map/RemoteStep.java
@@ -30,6 +30,7 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.util.NoSuchElementException;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -57,7 +58,23 @@ public final class RemoteStep<S, E> extends AbstractStep<S, E> {
 
     @Override
     protected Traverser.Admin<E> processNextStart() throws NoSuchElementException {
-        if (null == this.remoteTraversal) promise().join();
+        if (null == this.remoteTraversal) {
+            try {
+                promise().join();
+            } catch (CompletionException e) {
+                Throwable cause = e.getCause();
+                // If the underlying future failed, join() will throw a CompletionException, for consistency
+                // with previous behavior:
+                // - Throw underlying exception if it was unchecked (RuntimeException or Error).
+                // - Wrap in IllegalStateException otherwise.
+                if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                } else if (cause instanceof Error) {
+                    throw (Error) cause;
+                }
+                throw new IllegalStateException(cause);
+            }
+        }
         return this.remoteTraversal.nextTraverser();
     }
 


[04/10] tinkerpop git commit: Merge branch 'pr-609' into tp32

Posted by sp...@apache.org.
Merge branch 'pr-609' into tp32


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/8812f85a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/8812f85a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/8812f85a

Branch: refs/heads/TINKERPOP-1676
Commit: 8812f85a022a9de0592bae5de8a0dd5503a9c86b
Parents: 1ee5b37 6813e9e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 25 09:53:20 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 09:53:20 2017 -0400

----------------------------------------------------------------------
 .../remote/traversal/step/map/RemoteStep.java    | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
----------------------------------------------------------------------



[03/10] tinkerpop git commit: Improved error messaging in addV() CTR

Posted by sp...@apache.org.
Improved error messaging in addV() CTR


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/1ee5b375
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/1ee5b375
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/1ee5b375

Branch: refs/heads/TINKERPOP-1676
Commit: 1ee5b37535467cf60c7d4671ab3728af18d3e057
Parents: 7bf6883
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 25 08:19:36 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 08:19:36 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                                               | 1 +
 .../process/traversal/dsl/graph/GraphTraversalSource.java        | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1ee5b375/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index be8059d..31a4064 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Improved error messaging on the `g.addV(Object...)` when passing an invalid arguments.
 * Reduced memory usage for TinkerGraph deserialization in GraphSON by streaming vertices and edges.
 * Now using Groovy `[...]` map notation in `GroovyTranslator` instead of `new LinkedHashMap(){{ }}`.
 * Maintained type information on `Traversal.promise()`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1ee5b375/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
index af78add..1b6a218 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalSource.java
@@ -41,6 +41,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Transaction;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.util.ArrayList;
@@ -263,16 +264,15 @@ public class GraphTraversalSource implements TraversalSource {
      */
     @Deprecated
     public GraphTraversal<Vertex, Vertex> addV(final Object... keyValues) {
+        ElementHelper.legalPropertyKeyValueArray(keyValues);
         if (keyValues.length != 0 && keyValues[0].equals(T.label)) {
             final GraphTraversal<Vertex, Vertex> traversal = this.addV(keyValues[1].toString());
-            this.addV(keyValues[1].toString());
             for (int i = 2; i < keyValues.length; i = i + 2) {
                 traversal.property(keyValues[i], keyValues[i + 1]);
             }
             return traversal;
         } else {
             final GraphTraversal<Vertex, Vertex> traversal = this.addV();
-            this.addV(keyValues[1].toString());
             for (int i = 0; i < keyValues.length; i = i + 2) {
                 traversal.property(keyValues[i], keyValues[i + 1]);
             }


[02/10] tinkerpop git commit: TINKERPOP-1653 Fixed multiple -e script execution in Console

Posted by sp...@apache.org.
TINKERPOP-1653 Fixed multiple -e script execution in Console

Added tests - not sure why these weren't there before.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/7bf68835
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/7bf68835
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/7bf68835

Branch: refs/heads/TINKERPOP-1676
Commit: 7bf688350251f64247a71c39900fa015c59eb35b
Parents: 7ea3875
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 25 06:45:12 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 06:45:12 2017 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/console/Console.groovy    |  6 ++---
 .../src/test/python/tests/test_console.py       | 25 ++++++++++++++++----
 .../src/test/python/x-printed.script            | 21 ++++++++++++++++
 gremlin-console/src/test/python/x.groovy        | 20 ----------------
 gremlin-console/src/test/python/x.script        | 20 ++++++++++++++++
 .../src/test/python/y-printed.script            | 21 ++++++++++++++++
 gremlin-console/src/test/python/y.groovy        | 20 ----------------
 gremlin-console/src/test/python/y.script        | 20 ++++++++++++++++
 .../src/test/python/z-printed.script            | 21 ++++++++++++++++
 gremlin-console/src/test/python/z.groovy        | 20 ----------------
 gremlin-console/src/test/python/z.script        | 20 ++++++++++++++++
 11 files changed, 147 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
----------------------------------------------------------------------
diff --git a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
index 393f1f2..3bdc8a1 100644
--- a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
+++ b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
@@ -365,7 +365,7 @@ class Console {
     }
 
     private void executeInShell(final List<List<String>> scriptsAndArgs) {
-        scriptsAndArgs.each { scriptAndArgs ->
+        scriptsAndArgs.eachWithIndex { scriptAndArgs, idx ->
             final String scriptFile = scriptAndArgs[0]
             try {
                 // check if this script comes with arguments. if so then set them up in an "args" bundle
@@ -400,8 +400,6 @@ class Console {
 
                     }
                 }
-
-                if (!interactive) System.exit(0)
             } catch (FileNotFoundException ignored) {
                 io.err.println(Colorizer.render(Preferences.errorColor, "Gremlin file not found at [$scriptFile]."))
                 if (!interactive) System.exit(1)
@@ -410,6 +408,8 @@ class Console {
                 if (!interactive) System.exit(1)
             }
         }
+
+        if (!interactive) System.exit(0)
     }
 
     public static void main(final String[] args) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/tests/test_console.py
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/tests/test_console.py b/gremlin-console/src/test/python/tests/test_console.py
index f079291..407b563 100644
--- a/gremlin-console/src/test/python/tests/test_console.py
+++ b/gremlin-console/src/test/python/tests/test_console.py
@@ -34,7 +34,7 @@ class TestConsole(object):
         TestConsole._close(child)
 
     def test_just_dash_i(self):
-        child = pexpect.spawn(TestConsole.gremlinsh + "-i x.groovy")
+        child = pexpect.spawn(TestConsole.gremlinsh + "-i x.script")
         TestConsole._expect_gremlin_header(child)
         TestConsole._send(child, "x")
         child.expect("==>2\r\n")
@@ -42,7 +42,7 @@ class TestConsole(object):
         TestConsole._close(child)
 
     def test_dash_i_with_args(self):
-        child = pexpect.spawn(TestConsole.gremlinsh + "-i y.groovy 1 2 3")
+        child = pexpect.spawn(TestConsole.gremlinsh + "-i y.script 1 2 3")
         TestConsole._expect_gremlin_header(child)
         TestConsole._send(child, "y")
         child.expect("==>6\r\n")
@@ -50,7 +50,7 @@ class TestConsole(object):
         TestConsole._close(child)
 
     def test_dash_i_multiple_scripts(self):
-        child = pexpect.spawn(TestConsole.gremlinsh + "-i y.groovy 1 2 3 -i x.groovy -i \"z.groovy x -i --color -D\"")
+        child = pexpect.spawn(TestConsole.gremlinsh + "-i y.script 1 2 3 -i x.script -i \"z.script x -i --color -D\"")
         TestConsole._expect_gremlin_header(child)
         TestConsole._send(child, "y")
         child.expect("==>6\r\n")
@@ -63,8 +63,25 @@ class TestConsole(object):
         TestConsole._expect_prompt(child)
         TestConsole._close(child)
 
+    def test_just_dash_e(self):
+        child = pexpect.spawn(TestConsole.gremlinsh + "-e x-printed.script")
+        child.expect("2\r\n")
+        TestConsole._close(child)
+
+    def test_dash_e_with_args(self):
+        child = pexpect.spawn(TestConsole.gremlinsh + "-e y-printed.script 1 2 3")
+        child.expect("6\r\n")
+        TestConsole._close(child)
+
+    def test_dash_e_multiple_scripts(self):
+        child = pexpect.spawn(TestConsole.gremlinsh + "-e y-printed.script 1 2 3 -e x-printed.script -e \"z-printed.script x -e --color -D\"")
+        child.expect("6\r\n")
+        child.expect("2\r\n")
+        child.expect("argument=\[x, -e, --color, -D\]\r\n")
+        TestConsole._close(child)
+
     def test_no_mix_dash_i_and_dash_e(self):
-        child = pexpect.spawn(TestConsole.gremlinsh + "-i y.groovy 1 2 3 -i x.groovy -e \"z.groovy x -i --color -D\"")
+        child = pexpect.spawn(TestConsole.gremlinsh + "-i y.script 1 2 3 -i x.script -e \"z.script x -i --color -D\"")
         child.expect("-i and -e options are mutually exclusive - provide one or the other")
         child.expect(pexpect.EOF)
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/x-printed.script
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/x-printed.script b/gremlin-console/src/test/python/x-printed.script
new file mode 100644
index 0000000..9be57a5
--- /dev/null
+++ b/gremlin-console/src/test/python/x-printed.script
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+x = 1 + 1
+println x
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/x.groovy
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/x.groovy b/gremlin-console/src/test/python/x.groovy
deleted file mode 100644
index 31a9f19..0000000
--- a/gremlin-console/src/test/python/x.groovy
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-x = 1 + 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/x.script
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/x.script b/gremlin-console/src/test/python/x.script
new file mode 100644
index 0000000..31a9f19
--- /dev/null
+++ b/gremlin-console/src/test/python/x.script
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+x = 1 + 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/y-printed.script
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/y-printed.script b/gremlin-console/src/test/python/y-printed.script
new file mode 100644
index 0000000..e297186
--- /dev/null
+++ b/gremlin-console/src/test/python/y-printed.script
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+y = args.collect{Integer.parseInt(it)}.sum()
+println y
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/y.groovy
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/y.groovy b/gremlin-console/src/test/python/y.groovy
deleted file mode 100644
index 8b0adf6..0000000
--- a/gremlin-console/src/test/python/y.groovy
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-y = args.collect{Integer.parseInt(it)}.sum()
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/y.script
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/y.script b/gremlin-console/src/test/python/y.script
new file mode 100644
index 0000000..8b0adf6
--- /dev/null
+++ b/gremlin-console/src/test/python/y.script
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+y = args.collect{Integer.parseInt(it)}.sum()
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/z-printed.script
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/z-printed.script b/gremlin-console/src/test/python/z-printed.script
new file mode 100644
index 0000000..676542a
--- /dev/null
+++ b/gremlin-console/src/test/python/z-printed.script
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+z = "argument=" + args
+println z
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/z.groovy
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/z.groovy b/gremlin-console/src/test/python/z.groovy
deleted file mode 100644
index 3d7d101..0000000
--- a/gremlin-console/src/test/python/z.groovy
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-z = "argument=" + args
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7bf68835/gremlin-console/src/test/python/z.script
----------------------------------------------------------------------
diff --git a/gremlin-console/src/test/python/z.script b/gremlin-console/src/test/python/z.script
new file mode 100644
index 0000000..3d7d101
--- /dev/null
+++ b/gremlin-console/src/test/python/z.script
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+z = "argument=" + args
\ No newline at end of file


[06/10] tinkerpop git commit: TINKERPOP-1676 Got rid of stream() usage

Posted by sp...@apache.org.
TINKERPOP-1676 Got rid of stream() usage

Can't believe we still had stream() in here. Will it ever all be gone from these performance sensitive places?! Anyway, removed that and deprecated a constructor on DetachedEdge that was using Pair for no really good reason. No need to create extra Pair objects for that. They just sorta get thrown away after usage.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/46e6e976
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/46e6e976
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/46e6e976

Branch: refs/heads/TINKERPOP-1676
Commit: 46e6e9767b6818f33b56366ee15d80cec5a908e0
Parents: 8812f85
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue May 23 16:03:17 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 14:52:30 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  2 ++
 .../structure/io/graphson/GraphSONReader.java   |  5 ++--
 .../structure/util/detached/DetachedEdge.java   | 26 +++++++++++++++++++-
 .../structure/util/detached/DetachedVertex.java | 12 ++++-----
 .../util/detached/DetachedEdgeTest.java         |  3 +--
 .../tinkergraph/structure/TinkerIoRegistry.java |  5 ++--
 .../structure/TinkerIoRegistryV1d0.java         |  5 ++--
 7 files changed, 40 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 31a4064..77d612e 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,8 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Removed use of `stream()` in `DetachedEdge` and `DetachedVertex`.
+* Deprecated a constructor in `DetachedEdge` that made use of `Pair` in favor of a new one that just uses the objects that were in the `Pair`.
 * Improved error messaging on the `g.addV(Object...)` when passing an invalid arguments.
 * Reduced memory usage for TinkerGraph deserialization in GraphSON by streaming vertices and edges.
 * Now using Groovy `[...]` map notation in `GroovyTranslator` instead of `new LinkedHashMap(){{ }}`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
index a1ccc5e..3f63b96 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
@@ -42,7 +42,6 @@ import org.apache.tinkerpop.shaded.jackson.core.type.TypeReference;
 import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
 import org.apache.tinkerpop.shaded.jackson.databind.node.JsonNodeType;
-import org.javatuples.Pair;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -205,8 +204,8 @@ public final class GraphSONReader implements GraphReader {
             final DetachedEdge edge = new DetachedEdge(edgeData.get(GraphSONTokens.ID),
                     edgeData.get(GraphSONTokens.LABEL).toString(),
                     edgeProperties,
-                    Pair.with(edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString()),
-                    Pair.with(edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString()));
+                    edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString(),
+                    edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString());
 
             return edgeAttachMethod.apply(edge);
         } else {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
index ba05cca..1284ca7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
@@ -74,6 +74,29 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
 
     public DetachedEdge(final Object id, final String label,
                         final Map<String, Object> properties,
+                        final Object outVId, final String outVLabel,
+                        final Object inVId, final String inVLabel) {
+        super(id, label);
+        this.outVertex = new DetachedVertex(outVId, outVLabel, Collections.emptyMap());
+        this.inVertex = new DetachedVertex(inVId, inVLabel, Collections.emptyMap());
+        if (properties != null && !properties.isEmpty()) {
+            this.properties = new HashMap<>();
+            properties.entrySet().iterator().forEachRemaining(entry -> {
+                if (Property.class.isAssignableFrom(entry.getValue().getClass())) {
+                    this.properties.put(entry.getKey(), Collections.singletonList((Property)entry.getValue()));
+                } else {
+                    this.properties.put(entry.getKey(), Collections.singletonList(new DetachedProperty<>(entry.getKey(), entry.getValue(), this)));
+                }
+            });
+        }
+    }
+
+    /**
+     * @deprecated As for release 3.2.5, replaced by {@link #DetachedEdge(Object, String, Map, Object, String, Object, String)}.
+     */
+    @Deprecated
+    public DetachedEdge(final Object id, final String label,
+                        final Map<String, Object> properties,
                         final Pair<Object, String> outV,
                         final Pair<Object, String> inV) {
         super(id, label);
@@ -81,7 +104,7 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
         this.inVertex = new DetachedVertex(inV.getValue0(), inV.getValue1(), Collections.emptyMap());
         if (properties != null && !properties.isEmpty()) {
             this.properties = new HashMap<>();
-            properties.entrySet().stream().forEach(entry -> {
+            properties.entrySet().iterator().forEachRemaining(entry -> {
                 if (Property.class.isAssignableFrom(entry.getValue().getClass())) {
                     this.properties.put(entry.getKey(), Collections.singletonList((Property)entry.getValue()));
                 } else {
@@ -90,6 +113,7 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
             });
         }
     }
+
     @Override
     public String toString() {
         return StringFactory.edgeString(this);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
index 70cce37..d3fbd8e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -78,12 +79,11 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
         super(id, label);
         if (properties != null && !properties.isEmpty()) {
             this.properties = new HashMap<>();
-            properties.entrySet().stream().forEach(
-                    entry -> this.properties.put(entry.getKey(), (List<VertexProperty>) ((List) entry.getValue()).stream()
-                                .map(m -> VertexProperty.class.isAssignableFrom(m.getClass())
-                                                ? m
-                                                : new DetachedVertexProperty<>(((Map) m).get(ID), entry.getKey(), ((Map) m).get(VALUE), (Map<String, Object>) ((Map) m).getOrDefault(PROPERTIES, new HashMap<>()), this))
-                                .collect(Collectors.toList())));
+            properties.entrySet().iterator().forEachRemaining(entry ->
+                this.properties.put(entry.getKey(), IteratorUtils.<VertexProperty>list(IteratorUtils.map(((List<Object>) entry.getValue()).iterator(),
+                        m -> VertexProperty.class.isAssignableFrom(m.getClass())
+                                ? (VertexProperty) m
+                                : new DetachedVertexProperty<>(((Map) m).get(ID), entry.getKey(), ((Map) m).get(VALUE), (Map<String, Object>) ((Map) m).getOrDefault(PROPERTIES, new HashMap<>()), this)))));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdgeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdgeTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdgeTest.java
index 1090fe4..29c5764 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdgeTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdgeTest.java
@@ -28,7 +28,6 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.javatuples.Pair;
 import org.junit.Test;
 
 import java.util.HashMap;
@@ -160,7 +159,7 @@ public class DetachedEdgeTest extends AbstractGremlinTest {
         properties.put("x", "a");
         properties.put("y", "b");
 
-        final DetachedEdge de = new DetachedEdge(10, "bought", properties, Pair.with(1, "person"), Pair.with(2, "product"));
+        final DetachedEdge de = new DetachedEdge(10, "bought", properties, 1, "person", 2, "product");
 
         assertEquals(10, de.id());
         assertEquals("bought", de.label());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistry.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistry.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistry.java
index 40720e5..5abb363 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistry.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistry.java
@@ -48,7 +48,6 @@ import org.apache.tinkerpop.shaded.kryo.Kryo;
 import org.apache.tinkerpop.shaded.kryo.Serializer;
 import org.apache.tinkerpop.shaded.kryo.io.Input;
 import org.apache.tinkerpop.shaded.kryo.io.Output;
-import org.javatuples.Pair;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -262,8 +261,8 @@ public final class TinkerIoRegistry extends AbstractIoRegistry {
             for (Map<String, Object> edgeData : edges) {
                 final DetachedEdge detached = new DetachedEdge(edgeData.get(GraphSONTokens.ID),
                         edgeData.get(GraphSONTokens.LABEL).toString(), (Map<String,Object>) edgeData.get(GraphSONTokens.PROPERTIES),
-                        Pair.with(edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString()),
-                        Pair.with(edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString()));
+                        edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString(),
+                        edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString());
                 detached.attach(Attachable.Method.getOrCreate(graph));
             }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/46e6e976/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV1d0.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV1d0.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV1d0.java
index 277bedc..d15a4a7 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV1d0.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV1d0.java
@@ -48,7 +48,6 @@ import org.apache.tinkerpop.shaded.kryo.Kryo;
 import org.apache.tinkerpop.shaded.kryo.Serializer;
 import org.apache.tinkerpop.shaded.kryo.io.Input;
 import org.apache.tinkerpop.shaded.kryo.io.Output;
-import org.javatuples.Pair;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -252,8 +251,8 @@ public final class TinkerIoRegistryV1d0 extends AbstractIoRegistry {
             for (Map<String, Object> edgeData : edges) {
                 final DetachedEdge detached = new DetachedEdge(edgeData.get(GraphSONTokens.ID),
                         edgeData.get(GraphSONTokens.LABEL).toString(), (Map<String,Object>) edgeData.get(GraphSONTokens.PROPERTIES),
-                        Pair.with(edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString()),
-                        Pair.with(edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString()));
+                        edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString(),
+                        edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString());
                 detached.attach(Attachable.Method.getOrCreate(graph));
             }
 


[09/10] tinkerpop git commit: TINKERPOP-1676 Improved speed and memory usage of GraphSON

Posted by sp...@apache.org.
TINKERPOP-1676 Improved speed and memory usage of GraphSON

This change is specific to TinkerGraph and the serialization of vertices/edges/properties. Removed a "middle layer" of JSON to Object serialization which was coercing JSON to Map first and then converting that to the graph elements. Also made deserializers cacheable.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/251f5b7e
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/251f5b7e
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/251f5b7e

Branch: refs/heads/TINKERPOP-1676
Commit: 251f5b7e34e8ebd9a8bc36802e633be8c91eeb5e
Parents: 46e6e97
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue May 23 16:57:12 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 14:52:30 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../io/graphson/AbstractObjectDeserializer.java |   5 +
 .../io/graphson/GraphSONSerializersV2d0.java    | 164 +++++++++++++++----
 .../structure/TinkerIoRegistryV2d0.java         |   5 +
 4 files changed, 145 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/251f5b7e/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 77d612e..f0d7b17 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Improved performance and memory usage of GraphSON when serializing `TinkerGraph` and graph elements.
 * Removed use of `stream()` in `DetachedEdge` and `DetachedVertex`.
 * Deprecated a constructor in `DetachedEdge` that made use of `Pair` in favor of a new one that just uses the objects that were in the `Pair`.
 * Improved error messaging on the `g.addV(Object...)` when passing an invalid arguments.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/251f5b7e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
index bd7f4b6..9e4e102 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
@@ -47,5 +47,10 @@ public abstract class AbstractObjectDeserializer<T> extends StdDeserializer<T> {
         return createObject(mapData);
     }
 
+    @Override
+    public boolean isCachable() {
+        return true;
+    }
+
     public abstract T createObject(final Map<String, Object> data);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/251f5b7e/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index 9a27279..0008d3a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -43,7 +43,9 @@ import org.apache.tinkerpop.shaded.jackson.core.JsonGenerationException;
 import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
 import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
 import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
 import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
 import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
 import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
 import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
@@ -416,52 +418,117 @@ class GraphSONSerializersV2d0 {
 
     //////////////////////////// DESERIALIZERS ///////////////////////////
 
-
-    static class VertexJacksonDeserializer extends AbstractObjectDeserializer<Vertex> {
+    static class VertexJacksonDeserializer extends StdDeserializer<Vertex> {
 
         public VertexJacksonDeserializer() {
             super(Vertex.class);
         }
 
+        public Vertex deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
+
+            Object id = null;
+            String label = null;
+            Map<String, Object> properties = null;
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
+                    jsonParser.nextToken();
+                    id = deserializationContext.readValue(jsonParser, Object.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
+                    jsonParser.nextToken();
+                    label = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    jsonParser.nextToken();
+                    properties = deserializationContext.readValue(jsonParser, propertiesType);
+                }
+            }
+
+            return new DetachedVertex(id, label, properties);
+        }
+
         @Override
-        public Vertex createObject(final Map<String, Object> vertexData) {
-            return new DetachedVertex(
-                    vertexData.get(GraphSONTokens.ID),
-                    vertexData.get(GraphSONTokens.LABEL).toString(),
-                    (Map<String, Object>) vertexData.get(GraphSONTokens.PROPERTIES)
-            );
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class EdgeJacksonDeserializer extends AbstractObjectDeserializer<Edge> {
+    static class EdgeJacksonDeserializer extends StdDeserializer<Edge> {
 
         public EdgeJacksonDeserializer() {
             super(Edge.class);
         }
 
         @Override
-        public Edge createObject(final Map<String, Object> edgeData) {
-            return new DetachedEdge(
-                    edgeData.get(GraphSONTokens.ID),
-                    edgeData.get(GraphSONTokens.LABEL).toString(),
-                    (Map) edgeData.get(GraphSONTokens.PROPERTIES),
-                    Pair.with(edgeData.get(GraphSONTokens.OUT), edgeData.get(GraphSONTokens.OUT_LABEL).toString()),
-                    Pair.with(edgeData.get(GraphSONTokens.IN), edgeData.get(GraphSONTokens.IN_LABEL).toString())
-            );
+        public Edge deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
+
+            Object id = null;
+            String label = null;
+            Object outVId = null;
+            String outVLabel = null;
+            Object inVId = null;
+            String inVLabel = null;
+            Map<String, Object> properties = null;
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
+                    jsonParser.nextToken();
+                    id = deserializationContext.readValue(jsonParser, Object.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
+                    jsonParser.nextToken();
+                    label = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT)) {
+                    jsonParser.nextToken();
+                    outVId = deserializationContext.readValue(jsonParser, Object.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT_LABEL)) {
+                    jsonParser.nextToken();
+                    outVLabel = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN)) {
+                    jsonParser.nextToken();
+                    inVId = deserializationContext.readValue(jsonParser, Object.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN_LABEL)) {
+                    jsonParser.nextToken();
+                    inVLabel = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    jsonParser.nextToken();
+                    properties = deserializationContext.readValue(jsonParser, propertiesType);
+                }
+            }
+
+            return new DetachedEdge(id, label, properties, outVId, outVLabel, inVId, inVLabel);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class PropertyJacksonDeserializer extends AbstractObjectDeserializer<Property> {
+    static class PropertyJacksonDeserializer extends StdDeserializer<Property> {
 
         public PropertyJacksonDeserializer() {
             super(Property.class);
         }
 
         @Override
-        public Property createObject(final Map<String, Object> propData) {
-            return new DetachedProperty(
-                    (String) propData.get(GraphSONTokens.KEY),
-                    propData.get(GraphSONTokens.VALUE));
+        public Property deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String key = null;
+            Object value = null;
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.KEY)) {
+                    jsonParser.nextToken();
+                    key = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    value = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+
+            return new DetachedProperty<>(key, value);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
@@ -485,20 +552,42 @@ class GraphSONSerializersV2d0 {
         }
     }
 
-    static class VertexPropertyJacksonDeserializer extends AbstractObjectDeserializer<VertexProperty> {
+    static class VertexPropertyJacksonDeserializer extends StdDeserializer<VertexProperty> {
 
         protected VertexPropertyJacksonDeserializer() {
             super(VertexProperty.class);
         }
 
         @Override
-        public VertexProperty createObject(final Map<String, Object> propData) {
-            return new DetachedVertexProperty(
-                    propData.get(GraphSONTokens.ID),
-                    (String) propData.get(GraphSONTokens.LABEL),
-                    propData.get(GraphSONTokens.VALUE),
-                    (Map) propData.get(GraphSONTokens.PROPERTIES)
-            );
+        public VertexProperty deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
+
+            Object id = null;
+            String label = null;
+            Object value = null;
+            Map<String, Object> properties = null;
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
+                    jsonParser.nextToken();
+                    id = deserializationContext.readValue(jsonParser, Object.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
+                    jsonParser.nextToken();
+                    label = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    value = deserializationContext.readValue(jsonParser, Object.class);
+                }else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    jsonParser.nextToken();
+                    properties = deserializationContext.readValue(jsonParser, propertiesType);
+                }
+            }
+
+            return new DetachedVertexProperty<>(id, label, value, properties);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
@@ -555,6 +644,11 @@ class GraphSONSerializersV2d0 {
             }
             return t;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     static class IntegerJackonsDeserializer extends StdDeserializer<Integer> {
@@ -567,6 +661,11 @@ class GraphSONSerializersV2d0 {
         public Integer deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             return jsonParser.getIntValue();
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     static class DoubleJackonsDeserializer extends StdDeserializer<Double> {
@@ -579,6 +678,11 @@ class GraphSONSerializersV2d0 {
         public Double deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             return jsonParser.getDoubleValue();
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/251f5b7e/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV2d0.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV2d0.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV2d0.java
index 394216b..280d1af 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV2d0.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerIoRegistryV2d0.java
@@ -218,5 +218,10 @@ public final class TinkerIoRegistryV2d0 extends AbstractIoRegistry {
 
             return graph;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 }


[08/10] tinkerpop git commit: TINKERPOP-1676 More optimizations to GraphSON serializers

Posted by sp...@apache.org.
TINKERPOP-1676 More optimizations to GraphSON serializers

Added some tests where there were previously gaps.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/049c9797
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/049c9797
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/049c9797

Branch: refs/heads/TINKERPOP-1676
Commit: 049c979720a84ea9744725fda5f8d2b371ab1751
Parents: e5d2d2b
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 25 13:29:45 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 14:52:30 2017 -0400

----------------------------------------------------------------------
 .../io/graphson/AbstractObjectDeserializer.java |   5 +-
 .../io/graphson/GraphSONSerializersV2d0.java    |   5 +-
 .../io/graphson/GraphSONTypeDeserializer.java   |   9 +-
 .../io/graphson/JavaTimeSerializersV2d0.java    |   5 +
 .../io/graphson/TraversalSerializersV2d0.java   | 146 +++++++++++++++----
 .../GraphSONMapperEmbeddedTypeTest.java         | 109 ++++++++++++--
 6 files changed, 227 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/049c9797/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
index 9e4e102..5442fa8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/AbstractObjectDeserializer.java
@@ -24,10 +24,13 @@ import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
 import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
 
 import java.io.IOException;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
  * Base class for creating deserializers which parses JSON to a {@code Map} to more easily reconstruct an object.
+ * Generally speaking greater performance can be attained with deserializer development that directly uses the
+ * {@code JsonParser}.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
@@ -42,7 +45,7 @@ public abstract class AbstractObjectDeserializer<T> extends StdDeserializer<T> {
         jsonParser.nextToken();
 
         // This will automatically parse all typed stuff.
-        final Map<String, Object> mapData = deserializationContext.readValue(jsonParser, Map.class);
+        final Map<String, Object> mapData = deserializationContext.readValue(jsonParser, LinkedHashMap.class);
 
         return createObject(mapData);
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/049c9797/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index ffde32c..73bedbb 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -56,6 +56,7 @@ import org.apache.tinkerpop.shaded.jackson.databind.node.ArrayNode;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdKeySerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
 import org.javatuples.Pair;
 
 import java.io.IOException;
@@ -538,6 +539,7 @@ class GraphSONSerializersV2d0 {
     }
 
     static class PathJacksonDeserializer extends StdDeserializer<Path> {
+        private static final JavaType setType = TypeFactory.defaultInstance().constructCollectionType(HashSet.class, String.class);
 
         public PathJacksonDeserializer() {
             super(Path.class);
@@ -547,7 +549,6 @@ class GraphSONSerializersV2d0 {
         public Path deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             final JsonNode n = jsonParser.readValueAsTree();
             final Path p = MutablePath.make();
-            final JavaType setType = deserializationContext.getConfig().getTypeFactory().constructCollectionType(HashSet.class, String.class);
 
             final ArrayNode labels = (ArrayNode) n.get(GraphSONTokens.LABELS);
             final ArrayNode objects = (ArrayNode) n.get(GraphSONTokens.OBJECTS);
@@ -570,6 +571,7 @@ class GraphSONSerializersV2d0 {
     }
 
     static class VertexPropertyJacksonDeserializer extends StdDeserializer<VertexProperty> {
+        private static final JavaType propertiesType = TypeFactory.defaultInstance().constructMapType(HashMap.class, String.class, Object.class);
 
         protected VertexPropertyJacksonDeserializer() {
             super(VertexProperty.class);
@@ -578,7 +580,6 @@ class GraphSONSerializersV2d0 {
         @Override
         public VertexProperty deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             final DetachedVertexProperty vp = DetachedUtil.newDetachedVertexProperty();
-            final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
 
             Map<String, Object> properties;
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/049c9797/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
index ceddcc2..5822cb7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTypeDeserializer.java
@@ -32,8 +32,8 @@ import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
 import org.apache.tinkerpop.shaded.jackson.databind.util.TokenBuffer;
 
 import java.io.IOException;
-import java.util.List;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
 
 /**
  * Contains main logic for the whole JSON to Java deserialization. Handles types embedded with the version 2.0 of GraphSON.
@@ -47,9 +47,8 @@ public class GraphSONTypeDeserializer extends TypeDeserializerBase {
     private final JavaType baseType;
     private final TypeInfo typeInfo;
 
-    private static final JavaType mapJavaType = TypeFactory.defaultInstance().constructType(Map.class);
-    private static final JavaType arrayJavaType = TypeFactory.defaultInstance().constructType(List.class);
-
+    private static final JavaType mapJavaType = TypeFactory.defaultInstance().constructType(LinkedHashMap.class);
+    private static final JavaType arrayJavaType = TypeFactory.defaultInstance().constructType(ArrayList.class);
 
     GraphSONTypeDeserializer(final JavaType baseType, final TypeIdResolver idRes, final String typePropertyName,
                              final TypeInfo typeInfo, final String valuePropertyName){

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/049c9797/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
index 2950a33..9401d51 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV2d0.java
@@ -85,6 +85,11 @@ final class JavaTimeSerializersV2d0 {
         public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
             return parse(jsonParser.getText());
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/049c9797/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
index 54e5d9a..f399cfa 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java
@@ -35,14 +35,19 @@ import org.apache.tinkerpop.gremlin.util.function.Lambda;
 import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
 import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
 import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
+import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
 import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
+import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
 import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
 import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -242,29 +247,40 @@ final class TraversalSerializersV2d0 {
     // DESERIALIZERS //
     //////////////////
 
-    final static class BytecodeJacksonDeserializer extends AbstractObjectDeserializer<Bytecode> {
+    final static class BytecodeJacksonDeserializer extends StdDeserializer<Bytecode> {
+        private static final JavaType listJavaType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, Object.class);
+        private static final JavaType listListJavaType = TypeFactory.defaultInstance().constructCollectionType(ArrayList.class, listJavaType);
 
         public BytecodeJacksonDeserializer() {
             super(Bytecode.class);
         }
 
         @Override
-        public Bytecode createObject(final Map<String, Object> data) {
+        public Bytecode deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             final Bytecode bytecode = new Bytecode();
-            if (data.containsKey(GraphSONTokens.SOURCE)) {
-                final List<List<Object>> instructions = (List) data.get(GraphSONTokens.SOURCE);
-                for (final List<Object> instruction : instructions) {
-                    bytecode.addSource((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
-                }
-            }
-            if (data.containsKey(GraphSONTokens.STEP)) {
-                final List<List<Object>> instructions = (List) data.get(GraphSONTokens.STEP);
-                for (final List<Object> instruction : instructions) {
-                    bytecode.addStep((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.SOURCE)) {
+                    jsonParser.nextToken();
+                    final List<List<Object>> instructions = deserializationContext.readValue(jsonParser, listListJavaType);
+                    for (final List<Object> instruction : instructions) {
+                        bytecode.addSource((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+                    }
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.STEP)) {
+                    jsonParser.nextToken();
+                    final List<List<Object>> instructions = deserializationContext.readValue(jsonParser, listListJavaType);
+                    for (final List<Object> instruction : instructions) {
+                        bytecode.addStep((String) instruction.get(0), Arrays.copyOfRange(instruction.toArray(), 1, instruction.size()));
+                    }
                 }
             }
             return bytecode;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     final static class EnumJacksonDeserializer<A extends Enum> extends StdDeserializer<A> {
@@ -283,18 +299,34 @@ final class TraversalSerializersV2d0 {
             }
             throw new IOException("Unknown enum type: " + enumClass);
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    final static class PJacksonDeserializer extends AbstractObjectDeserializer<P> {
+    final static class PJacksonDeserializer extends StdDeserializer<P> {
 
         public PJacksonDeserializer() {
             super(P.class);
         }
 
         @Override
-        public P createObject(final Map<String, Object> data) {
-            final String predicate = (String) data.get(GraphSONTokens.PREDICATE);
-            final Object value = data.get(GraphSONTokens.VALUE);
+        public P deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String predicate = null;
+            Object value = null;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.PREDICATE)) {
+                    jsonParser.nextToken();
+                    predicate = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    value = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+
             if (predicate.equals(GraphSONTokens.AND) || predicate.equals(GraphSONTokens.OR)) {
                 return predicate.equals(GraphSONTokens.AND) ? new AndP((List<P>) value) : new OrP((List<P>) value);
             } else {
@@ -324,20 +356,38 @@ final class TraversalSerializersV2d0 {
                 }
             }
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    final static class LambdaJacksonDeserializer extends AbstractObjectDeserializer<Lambda> {
+    final static class LambdaJacksonDeserializer extends StdDeserializer<Lambda> {
 
         public LambdaJacksonDeserializer() {
             super(Lambda.class);
         }
 
         @Override
-        public Lambda createObject(final Map<String, Object> data) {
-            final String script = (String) data.get(GraphSONTokens.SCRIPT);
-            final String language = (String) data.get(GraphSONTokens.LANGUAGE);
-            final int arguments = ((Number) data.getOrDefault(GraphSONTokens.ARGUMENTS, -1)).intValue();
-            //
+        public Lambda deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String script = null;
+            String language = null;
+            int arguments = -1;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.SCRIPT)) {
+                    jsonParser.nextToken();
+                    script = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LANGUAGE)) {
+                    jsonParser.nextToken();
+                    language = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.ARGUMENTS)) {
+                    jsonParser.nextToken();
+                    arguments = jsonParser.getIntValue();
+                }
+            }
+
             if (-1 == arguments || arguments > 2)
                 return new Lambda.UnknownArgLambda(script, language, arguments);
             else if (0 == arguments)
@@ -347,29 +397,69 @@ final class TraversalSerializersV2d0 {
             else
                 return new Lambda.TwoArgLambda<>(script, language);
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
-    final static class BindingJacksonDeserializer extends AbstractObjectDeserializer<Bytecode.Binding> {
+    final static class BindingJacksonDeserializer extends StdDeserializer<Bytecode.Binding> {
 
         public BindingJacksonDeserializer() {
             super(Bytecode.Binding.class);
         }
 
         @Override
-        public Bytecode.Binding createObject(final Map<String, Object> data) {
-            return new Bytecode.Binding<>((String) data.get(GraphSONTokens.KEY), data.get(GraphSONTokens.VALUE));
+        public Bytecode.Binding deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            String k = null;
+            Object v = null;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.KEY)) {
+                    jsonParser.nextToken();
+                    k = jsonParser.getText();
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    v = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+            return new Bytecode.Binding<>(k, v);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 
-    static class TraverserJacksonDeserializer extends AbstractObjectDeserializer<Traverser> {
+    static class TraverserJacksonDeserializer extends StdDeserializer<Traverser> {
 
         public TraverserJacksonDeserializer() {
             super(Traverser.class);
         }
 
         @Override
-        public Traverser createObject(final Map<String, Object> data) {
-            return new DefaultRemoteTraverser<>(data.get(GraphSONTokens.VALUE), (Long) data.get(GraphSONTokens.BULK));
+        public Traverser deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            long bulk = 1;
+            Object v = null;
+
+            while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                if (jsonParser.getCurrentName().equals(GraphSONTokens.BULK)) {
+                    jsonParser.nextToken();
+                    bulk = deserializationContext.readValue(jsonParser, Long.class);
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
+                    jsonParser.nextToken();
+                    v = deserializationContext.readValue(jsonParser, Object.class);
+                }
+            }
+
+            return new DefaultRemoteTraverser<>(v, bulk);
+        }
+
+        @Override
+        public boolean isCachable() {
+            return true;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/049c9797/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
index 94ccb70..9079c8a 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperEmbeddedTypeTest.java
@@ -18,10 +18,16 @@
  */
 package org.apache.tinkerpop.gremlin.structure.io.graphson;
 
+import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.util.function.Lambda;
 import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.rules.TestName;
 
 import java.time.Duration;
 import java.time.Instant;
@@ -38,7 +44,9 @@ import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.util.Arrays;
 
+import static org.hamcrest.core.StringStartsWith.startsWith;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeThat;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
@@ -49,89 +57,158 @@ public class GraphSONMapperEmbeddedTypeTest extends AbstractGraphSONTest {
     @Parameterized.Parameters(name = "{0}")
     public static Iterable<Object[]> data() {
         return Arrays.asList(new Object[][]{
-                {GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(true).create().createMapper()},
-                {GraphSONMapper.build().version(GraphSONVersion.V2_0)
+                {"v1", GraphSONMapper.build().version(GraphSONVersion.V1_0).embedTypes(true).create().createMapper()},
+                {"v2", GraphSONMapper.build().version(GraphSONVersion.V2_0)
                         .addCustomModule(GraphSONXModuleV2d0.build().create(false))
                         .typeInfo(TypeInfo.PARTIAL_TYPES).create().createMapper()},
         });
     }
 
-    @Parameterized.Parameter
+    @Parameterized.Parameter(1)
     public ObjectMapper mapper;
 
+
+    @Parameterized.Parameter(0)
+    public String version;
+
+    @Test
+    public void shouldHandleBiFunctionLambda() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Lambda o = (Lambda) Lambda.biFunction("x,y -> 'test'");
+        assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
+    }
+
+    @Test
+    public void shouldHandleComparatorLambda() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Lambda o = (Lambda) Lambda.comparator("x,y -> x <=> y");
+        assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
+    }
+
+    @Test
+    public void shouldHandleConsumerLambda() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Lambda o = (Lambda) Lambda.consumer("x -> x");
+        assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
+    }
+
+    @Test
+    public void shouldHandleFunctionLambda() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Lambda o = (Lambda) Lambda.function("x -> x");
+        assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
+    }
+
     @Test
-    public void shouldHandleDuration()throws Exception  {
+    public void shouldHandlePredicateLambda() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Lambda o = (Lambda) Lambda.predicate("x -> true");
+        assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
+    }
+
+    @Test
+    public void shouldHandleSupplierLambda() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Lambda o = (Lambda) Lambda.supplier("'test'");
+        assertEquals(o, serializeDeserialize(mapper, o, Lambda.class));
+    }
+
+    @Test
+    public void shouldHandleBytecodeBinding() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Bytecode.Binding<String> o = new Bytecode.Binding<>("test", "testing");
+        assertEquals(o, serializeDeserialize(mapper, o, Bytecode.Binding.class));
+    }
+
+    @Test
+    public void shouldHandleTraverser() throws Exception {
+        assumeThat(version, startsWith("v2"));
+
+        final Traverser<String> o = new DefaultRemoteTraverser<>("test", 100);
+        assertEquals(o, serializeDeserialize(mapper, o, Traverser.class));
+    }
+
+    @Test
+    public void shouldHandleDuration() throws Exception  {
         final Duration o = Duration.ZERO;
         assertEquals(o, serializeDeserialize(mapper, o, Duration.class));
     }
+
     @Test
-    public void shouldHandleInstant()throws Exception  {
+    public void shouldHandleInstant() throws Exception  {
         final Instant o = Instant.ofEpochMilli(System.currentTimeMillis());
         assertEquals(o, serializeDeserialize(mapper, o, Instant.class));
     }
 
     @Test
-    public void shouldHandleLocalDate()throws Exception  {
+    public void shouldHandleLocalDate() throws Exception  {
         final LocalDate o = LocalDate.now();
         assertEquals(o, serializeDeserialize(mapper, o, LocalDate.class));
     }
 
     @Test
-    public void shouldHandleLocalDateTime()throws Exception  {
+    public void shouldHandleLocalDateTime() throws Exception  {
         final LocalDateTime o = LocalDateTime.now();
         assertEquals(o, serializeDeserialize(mapper, o, LocalDateTime.class));
     }
 
     @Test
-    public void shouldHandleLocalTime()throws Exception  {
+    public void shouldHandleLocalTime() throws Exception  {
         final LocalTime o = LocalTime.now();
         assertEquals(o, serializeDeserialize(mapper, o, LocalTime.class));
     }
 
     @Test
-    public void shouldHandleMonthDay()throws Exception  {
+    public void shouldHandleMonthDay() throws Exception  {
         final MonthDay o = MonthDay.now();
         assertEquals(o, serializeDeserialize(mapper, o, MonthDay.class));
     }
 
     @Test
-    public void shouldHandleOffsetDateTime()throws Exception  {
+    public void shouldHandleOffsetDateTime() throws Exception  {
         final OffsetDateTime o = OffsetDateTime.now();
         assertEquals(o, serializeDeserialize(mapper, o, OffsetDateTime.class));
     }
 
     @Test
-    public void shouldHandleOffsetTime()throws Exception  {
+    public void shouldHandleOffsetTime() throws Exception  {
         final OffsetTime o = OffsetTime.now();
         assertEquals(o, serializeDeserialize(mapper, o, OffsetTime.class));
     }
 
     @Test
-    public void shouldHandlePeriod()throws Exception  {
+    public void shouldHandlePeriod() throws Exception  {
         final Period o = Period.ofDays(3);
         assertEquals(o, serializeDeserialize(mapper, o, Period.class));
     }
 
     @Test
-    public void shouldHandleYear()throws Exception  {
+    public void shouldHandleYear() throws Exception  {
         final Year o = Year.now();
         assertEquals(o, serializeDeserialize(mapper, o, Year.class));
     }
 
     @Test
-    public void shouldHandleYearMonth()throws Exception  {
+    public void shouldHandleYearMonth() throws Exception  {
         final YearMonth o = YearMonth.now();
         assertEquals(o, serializeDeserialize(mapper, o, YearMonth.class));
     }
 
     @Test
-    public void shouldHandleZonedDateTime()throws Exception  {
+    public void shouldHandleZonedDateTime() throws Exception  {
         final ZonedDateTime o = ZonedDateTime.now();
         assertEquals(o, serializeDeserialize(mapper, o, ZonedDateTime.class));
     }
 
     @Test
-    public void shouldHandleZonedOffset()throws Exception  {
+    public void shouldHandleZonedOffset() throws Exception  {
         final ZoneOffset o  = ZonedDateTime.now().getOffset();
         assertEquals(o, serializeDeserialize(mapper, o, ZoneOffset.class));
     }


[05/10] tinkerpop git commit: TINKERPOP-1676 Cleaned up serialization with detached

Posted by sp...@apache.org.
TINKERPOP-1676 Cleaned up serialization with detached

The DetachedUtil was just there to test out if the performance changes would help and it did it's job nicely, but it was kinda ugly and hung some methods out there in weird way. Cleaned that up with some builder pattern on the detached classes themselves.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f32d725a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f32d725a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f32d725a

Branch: refs/heads/TINKERPOP-1676
Commit: f32d725a080d39ef7bf93c68d8080939f622cb37
Parents: 049c979
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 25 14:03:29 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 14:52:30 2017 -0400

----------------------------------------------------------------------
 .../io/graphson/GraphSONSerializersV2d0.java    | 49 +++++++-------
 .../structure/util/detached/DetachedEdge.java   | 44 ++++++++++--
 .../util/detached/DetachedElement.java          | 11 ---
 .../structure/util/detached/DetachedUtil.java   | 70 --------------------
 .../structure/util/detached/DetachedVertex.java | 38 ++++++++++-
 .../util/detached/DetachedVertexProperty.java   | 41 +++++++++++-
 6 files changed, 136 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f32d725a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index 73bedbb..8d19e4f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -37,7 +37,6 @@ import org.apache.tinkerpop.gremlin.structure.util.Comparators;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedUtil;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -430,26 +429,26 @@ class GraphSONSerializersV2d0 {
         }
 
         public Vertex deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            final DetachedVertex v = DetachedUtil.newDetachedVertex();
+            final DetachedVertex.Builder v = DetachedVertex.build();
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                 if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setId(v, deserializationContext.readValue(jsonParser, Object.class));
+                    v.setId(deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setLabel(v, jsonParser.getText());
+                    v.setLabel(jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
                     jsonParser.nextToken();
                     while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                         jsonParser.nextToken();
                         while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
-                            DetachedUtil.addProperty(v, (DetachedVertexProperty) deserializationContext.readValue(jsonParser, VertexProperty.class));
+                            v.addProperty((DetachedVertexProperty) deserializationContext.readValue(jsonParser, VertexProperty.class));
                         }
                     }
                 }
             }
 
-            return v;
+            return v.create();
         }
 
         @Override
@@ -466,41 +465,41 @@ class GraphSONSerializersV2d0 {
 
         @Override
         public Edge deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            final DetachedEdge e = DetachedUtil.newDetachedEdge();
-            final DetachedVertex inV = DetachedUtil.newDetachedVertex();
-            final DetachedVertex outV = DetachedUtil.newDetachedVertex();
+            final DetachedEdge.Builder e = DetachedEdge.build();
+            final DetachedVertex.Builder inV = DetachedVertex.build();
+            final DetachedVertex.Builder outV = DetachedVertex.build();
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                 if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setId(e, deserializationContext.readValue(jsonParser, Object.class));
+                    e.setId(deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setLabel(e, jsonParser.getText());
+                    e.setLabel(jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setId(outV, deserializationContext.readValue(jsonParser, Object.class));
+                    outV.setId(deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT_LABEL)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setLabel(outV, jsonParser.getText());
+                    outV.setLabel(jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setId(inV, deserializationContext.readValue(jsonParser, Object.class));
+                    inV.setId(deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN_LABEL)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setLabel(inV,jsonParser.getText());
+                    inV.setLabel(jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
                     jsonParser.nextToken();
                     while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                         jsonParser.nextToken();
-                        DetachedUtil.addProperty(e, (DetachedProperty) deserializationContext.readValue(jsonParser, Property.class));
+                        e.addProperty(deserializationContext.readValue(jsonParser, Property.class));
                     }
                 }
             }
 
-            DetachedUtil.setInV(e, inV);
-            DetachedUtil.setOutV(e, outV);
+            e.setInV(inV.create());
+            e.setOutV(outV.create());
 
-            return e;
+            return e.create();
         }
 
         @Override
@@ -579,27 +578,27 @@ class GraphSONSerializersV2d0 {
 
         @Override
         public VertexProperty deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            final DetachedVertexProperty vp = DetachedUtil.newDetachedVertexProperty();
+            final DetachedVertexProperty.Builder vp = DetachedVertexProperty.build();
 
             Map<String, Object> properties;
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                 if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setId(vp, deserializationContext.readValue(jsonParser, Object.class));
+                    vp.setId(deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setLabel(vp, jsonParser.getText());
+                    vp.setLabel(jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
                     jsonParser.nextToken();
-                    DetachedUtil.setValue(vp, deserializationContext.readValue(jsonParser, Object.class));
+                    vp.setValue(deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
                     jsonParser.nextToken();
                     properties = deserializationContext.readValue(jsonParser, propertiesType);
-                    properties.entrySet().iterator().forEachRemaining(kv -> DetachedUtil.addProperty(vp, new DetachedProperty(kv.getKey(), kv.getValue())));
+                    properties.entrySet().iterator().forEachRemaining(kv -> vp.addProperty(new DetachedProperty(kv.getKey(), kv.getValue())));
                 }
             }
 
-            return vp;
+            return vp.create();
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f32d725a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
index 40b6e34..367dbc9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
@@ -51,7 +51,7 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
     private DetachedVertex outVertex;
     private DetachedVertex inVertex;
 
-    DetachedEdge() {}
+    private DetachedEdge() {}
 
     protected DetachedEdge(final Edge edge, final boolean withProperties) {
         super(edge);
@@ -155,11 +155,45 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
         this.properties.put(p.key(), Collections.singletonList(p));
     }
 
-    void internalSetOutV(final DetachedVertex v) {
-        outVertex = v;
+    /**
+     * Provides a way to construct an immutable {@link DetachedEdge}.
+     */
+    public static DetachedEdge.Builder build() {
+        return new Builder(new DetachedEdge());
     }
 
-    void internalSetInV(final DetachedVertex v) {
-        inVertex = v;
+    public static class Builder {
+        private DetachedEdge e;
+
+        private Builder(final DetachedEdge e) {
+            this.e = e;
+        }
+
+        public Builder addProperty(final Property p) {
+            e.internalAddProperty(p);
+            return this;
+        }
+
+        public Builder setId(final Object id) {
+            e.id = id;
+            return this;
+        }
+
+        public Builder setLabel(final String label) {
+            e.label = label;
+            return this;
+        }
+
+        public void setOutV(final DetachedVertex v) {
+            e.outVertex = v;
+        }
+
+        public void setInV(final DetachedVertex v) {
+            e.inVertex = v;
+        }
+
+        public DetachedEdge create() {
+            return e;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f32d725a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
index 4e40303..8826bfd 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
@@ -25,12 +25,9 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -111,12 +108,4 @@ public abstract class DetachedElement<E> implements Element, Serializable, Attac
     }
 
     abstract void internalAddProperty(final Property p);
-
-    void internalSetId(final Object id) {
-        this.id = id;
-    }
-
-    void inernalSetLabel(final String label) {
-        this.label = label;
-    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f32d725a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java
deleted file mode 100644
index f2c658d..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.tinkerpop.gremlin.structure.util.detached;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public final class DetachedUtil {
-
-    private DetachedUtil() {}
-
-    /**
-     * Provides a way to mutate something that is "detached". This method is really for internal usage as there
-     * typically is not need for application developers to mutate a "detached" element.
-     */
-    public static void addProperty(final DetachedElement e, final DetachedProperty p) {
-        e.internalAddProperty(p);
-    }
-    public static void addProperty(final DetachedVertex v, final DetachedVertexProperty vp) {
-        v.internalAddProperty(vp);
-    }
-
-    public static void setId(final DetachedElement e, final Object id) {
-        e.internalSetId(id);
-    }
-
-    public static void setLabel(final DetachedElement e, final String label) {
-        e.inernalSetLabel(label);
-    }
-
-    public static void setValue(final DetachedVertexProperty vp, final Object value) {
-        vp.internalSetValue(value);
-    }
-
-    public static DetachedVertex newDetachedVertex() {
-        return new DetachedVertex();
-    }
-
-    public static DetachedVertexProperty newDetachedVertexProperty() {
-        return new DetachedVertexProperty();
-    }
-
-    public static DetachedEdge newDetachedEdge() {
-        return new DetachedEdge();
-    }
-
-    public static void setInV(final DetachedEdge e, final DetachedVertex v) {
-        e.internalSetInV(v);
-    }
-
-    public static void setOutV(final DetachedEdge e, final DetachedVertex v) {
-        e.internalSetOutV(v);
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f32d725a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
index 15e956b..3f0b670 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
@@ -25,7 +25,6 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
-import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
@@ -35,7 +34,6 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * Represents a {@link Vertex} that is disconnected from a {@link Graph}.  "Disconnection" can mean detachment from
@@ -55,7 +53,7 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
     private static final String VALUE = "value";
     private static final String PROPERTIES = "properties";
 
-    DetachedVertex() {}
+    private DetachedVertex() {}
 
     protected DetachedVertex(final Vertex vertex, final boolean withProperties) {
         super(vertex);
@@ -154,4 +152,38 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
 
         this.properties.get(p.key()).add(p);
     }
+
+    /**
+     * Provides a way to construct an immutable {@link DetachedVertex}.
+     */
+    public static DetachedVertex.Builder build() {
+        return new Builder(new DetachedVertex());
+    }
+
+    public static class Builder {
+        private DetachedVertex v;
+
+        private Builder(final DetachedVertex v) {
+            this.v = v;
+        }
+
+        public Builder addProperty(final DetachedVertexProperty vp) {
+            v.internalAddProperty(vp);
+            return this;
+        }
+
+        public Builder setId(final Object id) {
+            v.id = id;
+            return this;
+        }
+
+        public Builder setLabel(final String label) {
+            v.label = label;
+            return this;
+        }
+
+        public DetachedVertex create() {
+            return v;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f32d725a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
index f682e04..b64be7c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
@@ -39,7 +39,7 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V>
     protected V value;
     protected transient DetachedVertex vertex;
 
-    DetachedVertexProperty() {}
+    private DetachedVertexProperty() {}
 
     protected DetachedVertexProperty(final VertexProperty<V> vertexProperty, final boolean withProperties) {
         super(vertexProperty);
@@ -132,7 +132,42 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V>
         this.properties.put(p.key(), Collections.singletonList(p));
     }
 
-    void internalSetValue(final V value) {
-        this.value = value;
+    /**
+     * Provides a way to construct an immutable {@link DetachedEdge}.
+     */
+    public static DetachedVertexProperty.Builder build() {
+        return new Builder(new DetachedVertexProperty());
+    }
+
+    public static class Builder {
+        private DetachedVertexProperty vp;
+
+        private Builder(final DetachedVertexProperty e) {
+            this.vp = e;
+        }
+
+        public Builder addProperty(final Property p) {
+            vp.internalAddProperty(p);
+            return this;
+        }
+
+        public Builder setId(final Object id) {
+            vp.id = id;
+            return this;
+        }
+
+        public Builder setLabel(final String label) {
+            vp.label = label;
+            return this;
+        }
+
+        public Builder setValue(final Object value) {
+            vp.value = value;
+            return this;
+        }
+
+        public DetachedVertexProperty create() {
+            return vp;
+        }
     }
 }


[07/10] tinkerpop git commit: TINKERPOP-1676 Removed properties from graphson serialization of Path

Posted by sp...@apache.org.
TINKERPOP-1676 Removed properties from graphson serialization of Path

Path should not have properties on elements (if they are present). That is inconsistent with gryo and was unintentially allowed.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e5d2d2bc
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e5d2d2bc
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e5d2d2bc

Branch: refs/heads/TINKERPOP-1676
Commit: e5d2d2bc000654fd026521219cf30bac265139a3
Parents: 02b0073
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed May 24 13:38:16 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 14:52:30 2017 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 docs/src/dev/io/graphson.asciidoc               | 126 +------------------
 .../upgrade/release-3.2.x-incubating.asciidoc   |  12 ++
 .../io/graphson/GraphSONSerializersV2d0.java    |  33 +++--
 4 files changed, 42 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5d2d2bc/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index f0d7b17..750b4dd 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.5 (Release Date: NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Fixed inconsistency in GraphSON serialization of `Path` where properties of graph elements were being included when serialized.
 * Improved performance and memory usage of GraphSON when serializing `TinkerGraph` and graph elements.
 * Removed use of `stream()` in `DetachedEdge` and `DetachedVertex`.
 * Deprecated a constructor in `DetachedEdge` that made use of `Pair` in favor of a new one that just uses the objects that were in the `Pair`.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5d2d2bc/docs/src/dev/io/graphson.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/io/graphson.asciidoc b/docs/src/dev/io/graphson.asciidoc
index fe56c27..e4c671d 100644
--- a/docs/src/dev/io/graphson.asciidoc
+++ b/docs/src/dev/io/graphson.asciidoc
@@ -149,12 +149,12 @@ file.withWriter { writer ->
   writer.write(toJson(Operator.sum, "Operator"))
   writer.write(toJson(Order.incr, "Order"))
   writer.write(toJson(Pop.all, "Pop"))
-  writer.write(toJson(Pick.any, "Pick"))
+  writer.write(toJson(org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent.Pick.any, "Pick"))
   writer.write(toJson(org.apache.tinkerpop.gremlin.util.function.Lambda.function("{ it.get() }"), "Lambda"))
   tm = g.V().hasLabel('person').out().out().tree().profile().next()
   metrics = new org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics(tm.getMetrics(0));
   metrics.addNested(new org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics(tm.getMetrics(1)));
-  writer.write(toJson(m, "Metrics"))
+  writer.write(toJson(metrics, "Metrics"))
   writer.write(toJson(P.gt(0), "P"))
   writer.write(toJson(P.gt(0).and(P.lt(10)), "P and"))
   writer.write(toJson(P.gt(0).or(P.within(-1, -10, -100)), "P or"))
@@ -1662,97 +1662,7 @@ Path
           "@type" : "g:Int32",
           "@value" : 1
         },
-        "label" : "person",
-        "properties" : {
-          "name" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 0
-              },
-              "value" : "marko",
-              "label" : "name"
-            }
-          } ],
-          "location" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 6
-              },
-              "value" : "san diego",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 1997
-                },
-                "endTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2001
-                }
-              }
-            }
-          }, {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 7
-              },
-              "value" : "santa cruz",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2001
-                },
-                "endTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2004
-                }
-              }
-            }
-          }, {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 8
-              },
-              "value" : "brussels",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2004
-                },
-                "endTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2005
-                }
-              }
-            }
-          }, {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 9
-              },
-              "value" : "santa fe",
-              "label" : "location",
-              "properties" : {
-                "startTime" : {
-                  "@type" : "g:Int32",
-                  "@value" : 2005
-                }
-              }
-            }
-          } ]
-        }
+        "label" : "person"
       }
     }, {
       "@type" : "g:Vertex",
@@ -1761,20 +1671,7 @@ Path
           "@type" : "g:Int32",
           "@value" : 10
         },
-        "label" : "software",
-        "properties" : {
-          "name" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 4
-              },
-              "value" : "gremlin",
-              "label" : "name"
-            }
-          } ]
-        }
+        "label" : "software"
       }
     }, {
       "@type" : "g:Vertex",
@@ -1783,20 +1680,7 @@ Path
           "@type" : "g:Int32",
           "@value" : 11
         },
-        "label" : "software",
-        "properties" : {
-          "name" : [ {
-            "@type" : "g:VertexProperty",
-            "@value" : {
-              "id" : {
-                "@type" : "g:Int64",
-                "@value" : 5
-              },
-              "value" : "tinkergraph",
-              "label" : "name"
-            }
-          } ]
-        }
+        "label" : "software"
       }
     } ]
   }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5d2d2bc/docs/src/upgrade/release-3.2.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.2.x-incubating.asciidoc b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
index a2045e4..36e0aae 100644
--- a/docs/src/upgrade/release-3.2.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.2.x-incubating.asciidoc
@@ -32,6 +32,18 @@ Please see the link:https://github.com/apache/tinkerpop/blob/3.2.5/CHANGELOG.asc
 Upgrading for Users
 ~~~~~~~~~~~~~~~~~~~
 
+GraphSON Path Serialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Serialization of `Path` with GraphSON was inconsistent with Gryo in that all the properties on any elements of
+the `Path` were being included. With Gryo that, correctly, was not happening as that could be extraordinarily
+expensive. GraphSON serialization has now been modified to properly not include properties. That change can cause
+breaks in application code if that application code tries to access properties on elements in a `Path` as they
+will no longer be there. Applications that require the properties will need to alter their Gremlin to better
+restrict the data they want to retrieve.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1676[TINKERPOP-1676]
+
 Authentication Configuration
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5d2d2bc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index bdf3fe5..ffde32c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -35,6 +35,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.Comparators;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedUtil;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
@@ -47,9 +48,11 @@ import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException;
 import org.apache.tinkerpop.shaded.jackson.core.JsonToken;
 import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
 import org.apache.tinkerpop.shaded.jackson.databind.JavaType;
+import org.apache.tinkerpop.shaded.jackson.databind.JsonNode;
 import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
 import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
 import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer;
+import org.apache.tinkerpop.shaded.jackson.databind.node.ArrayNode;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdKeySerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer;
 import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
@@ -241,8 +244,6 @@ class GraphSONSerializersV2d0 {
 
             jsonGenerator.writeEndObject();
         }
-
-
     }
 
     final static class PathJacksonSerializer extends StdScalarSerializer<Path> {
@@ -256,8 +257,10 @@ class GraphSONSerializersV2d0 {
                 throws IOException, JsonGenerationException {
             jsonGenerator.writeStartObject();
 
-            jsonGenerator.writeObjectField(GraphSONTokens.LABELS, path.labels());
-            jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, path.objects());
+            // paths shouldn't serialize with properties if the path contains graph elements
+            final Path p = DetachedFactory.detach(path, false);
+            jsonGenerator.writeObjectField(GraphSONTokens.LABELS, p.labels());
+            jsonGenerator.writeObjectField(GraphSONTokens.OBJECTS, p.objects());
 
             jsonGenerator.writeEndObject();
         }
@@ -534,24 +537,36 @@ class GraphSONSerializersV2d0 {
         }
     }
 
-    static class PathJacksonDeserializer extends AbstractObjectDeserializer<Path> {
+    static class PathJacksonDeserializer extends StdDeserializer<Path> {
 
         public PathJacksonDeserializer() {
             super(Path.class);
         }
 
         @Override
-        public Path createObject(final Map<String, Object> pathData) {
+        public Path deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final JsonNode n = jsonParser.readValueAsTree();
             final Path p = MutablePath.make();
+            final JavaType setType = deserializationContext.getConfig().getTypeFactory().constructCollectionType(HashSet.class, String.class);
 
-            final List labels = (List) pathData.get(GraphSONTokens.LABELS);
-            final List objects = (List) pathData.get(GraphSONTokens.OBJECTS);
+            final ArrayNode labels = (ArrayNode) n.get(GraphSONTokens.LABELS);
+            final ArrayNode objects = (ArrayNode) n.get(GraphSONTokens.OBJECTS);
 
             for (int i = 0; i < objects.size(); i++) {
-                p.extend(objects.get(i), new HashSet((List) labels.get(i)));
+                final JsonParser po = objects.get(i).traverse();
+                po.nextToken();
+                final JsonParser pl = labels.get(i).traverse();
+                pl.nextToken();
+                p.extend(deserializationContext.readValue(po, Object.class), deserializationContext.readValue(pl, setType));
             }
+
             return p;
         }
+
+        @Override
+        public boolean isCachable() {
+            return true;
+        }
     }
 
     static class VertexPropertyJacksonDeserializer extends StdDeserializer<VertexProperty> {


[10/10] tinkerpop git commit: TINKERPOP-1676 Performance enhancement to graphson serialization

Posted by sp...@apache.org.
TINKERPOP-1676 Performance enhancement to graphson serialization

Focuses on speeding up serialization of graph elements. Prevent use of generic maps and stream graphson data directly into "detached" elements. Not using intermediate maps cut down on memory usage and a bunch of jackson reflection calls (still not sure what they were for and why they were not made to be more efficient). It did mean some ugly changes to "detached" stuff. Will need to maybe refactor some more, but the basic premise seems to be proven.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/02b00736
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/02b00736
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/02b00736

Branch: refs/heads/TINKERPOP-1676
Commit: 02b007366b434918fe1181f99d80689c1c03684b
Parents: 251f5b7
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue May 23 20:13:46 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 25 14:52:30 2017 -0400

----------------------------------------------------------------------
 .../io/graphson/GraphSONSerializersV2d0.java    | 71 ++++++++++----------
 .../structure/util/detached/DetachedEdge.java   | 18 ++++-
 .../util/detached/DetachedElement.java          | 15 ++++-
 .../structure/util/detached/DetachedUtil.java   | 70 +++++++++++++++++++
 .../structure/util/detached/DetachedVertex.java | 19 ++++--
 .../util/detached/DetachedVertexProperty.java   | 14 +++-
 6 files changed, 161 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/02b00736/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
index 0008d3a..bdf3fe5 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONSerializersV2d0.java
@@ -36,6 +36,7 @@ import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.Comparators;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedUtil;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -425,25 +426,26 @@ class GraphSONSerializersV2d0 {
         }
 
         public Vertex deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
-
-            Object id = null;
-            String label = null;
-            Map<String, Object> properties = null;
+            final DetachedVertex v = DetachedUtil.newDetachedVertex();
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                 if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
                     jsonParser.nextToken();
-                    id = deserializationContext.readValue(jsonParser, Object.class);
+                    DetachedUtil.setId(v, deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
                     jsonParser.nextToken();
-                    label = jsonParser.getText();
+                    DetachedUtil.setLabel(v, jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
                     jsonParser.nextToken();
-                    properties = deserializationContext.readValue(jsonParser, propertiesType);
+                    while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                        jsonParser.nextToken();
+                        while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
+                            DetachedUtil.addProperty(v, (DetachedVertexProperty) deserializationContext.readValue(jsonParser, VertexProperty.class));
+                        }
+                    }
                 }
             }
 
-            return new DetachedVertex(id, label, properties);
+            return v;
         }
 
         @Override
@@ -460,41 +462,41 @@ class GraphSONSerializersV2d0 {
 
         @Override
         public Edge deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
-
-            Object id = null;
-            String label = null;
-            Object outVId = null;
-            String outVLabel = null;
-            Object inVId = null;
-            String inVLabel = null;
-            Map<String, Object> properties = null;
+            final DetachedEdge e = DetachedUtil.newDetachedEdge();
+            final DetachedVertex inV = DetachedUtil.newDetachedVertex();
+            final DetachedVertex outV = DetachedUtil.newDetachedVertex();
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                 if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
                     jsonParser.nextToken();
-                    id = deserializationContext.readValue(jsonParser, Object.class);
+                    DetachedUtil.setId(e, deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
                     jsonParser.nextToken();
-                    label = jsonParser.getText();
+                    DetachedUtil.setLabel(e, jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT)) {
                     jsonParser.nextToken();
-                    outVId = deserializationContext.readValue(jsonParser, Object.class);
+                    DetachedUtil.setId(outV, deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.OUT_LABEL)) {
                     jsonParser.nextToken();
-                    outVLabel = jsonParser.getText();
+                    DetachedUtil.setLabel(outV, jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN)) {
                     jsonParser.nextToken();
-                    inVId = deserializationContext.readValue(jsonParser, Object.class);
+                    DetachedUtil.setId(inV, deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.IN_LABEL)) {
                     jsonParser.nextToken();
-                    inVLabel = jsonParser.getText();
+                    DetachedUtil.setLabel(inV,jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
                     jsonParser.nextToken();
-                    properties = deserializationContext.readValue(jsonParser, propertiesType);
+                    while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
+                        jsonParser.nextToken();
+                        DetachedUtil.addProperty(e, (DetachedProperty) deserializationContext.readValue(jsonParser, Property.class));
+                    }
                 }
             }
 
-            return new DetachedEdge(id, label, properties, outVId, outVLabel, inVId, inVLabel);
+            DetachedUtil.setInV(e, inV);
+            DetachedUtil.setOutV(e, outV);
+
+            return e;
         }
 
         @Override
@@ -560,29 +562,28 @@ class GraphSONSerializersV2d0 {
 
         @Override
         public VertexProperty deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            final DetachedVertexProperty vp = DetachedUtil.newDetachedVertexProperty();
             final JavaType propertiesType = deserializationContext.getConfig().getTypeFactory().constructMapType(HashMap.class, String.class, Object.class);
 
-            Object id = null;
-            String label = null;
-            Object value = null;
-            Map<String, Object> properties = null;
+            Map<String, Object> properties;
             while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
                 if (jsonParser.getCurrentName().equals(GraphSONTokens.ID)) {
                     jsonParser.nextToken();
-                    id = deserializationContext.readValue(jsonParser, Object.class);
+                    DetachedUtil.setId(vp, deserializationContext.readValue(jsonParser, Object.class));
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.LABEL)) {
                     jsonParser.nextToken();
-                    label = jsonParser.getText();
+                    DetachedUtil.setLabel(vp, jsonParser.getText());
                 } else if (jsonParser.getCurrentName().equals(GraphSONTokens.VALUE)) {
                     jsonParser.nextToken();
-                    value = deserializationContext.readValue(jsonParser, Object.class);
-                }else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
+                    DetachedUtil.setValue(vp, deserializationContext.readValue(jsonParser, Object.class));
+                } else if (jsonParser.getCurrentName().equals(GraphSONTokens.PROPERTIES)) {
                     jsonParser.nextToken();
                     properties = deserializationContext.readValue(jsonParser, propertiesType);
+                    properties.entrySet().iterator().forEachRemaining(kv -> DetachedUtil.addProperty(vp, new DetachedProperty(kv.getKey(), kv.getValue())));
                 }
             }
 
-            return new DetachedVertexProperty<>(id, label, value, properties);
+            return vp;
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/02b00736/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
index 1284ca7..40b6e34 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedEdge.java
@@ -51,9 +51,7 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
     private DetachedVertex outVertex;
     private DetachedVertex inVertex;
 
-    private DetachedEdge() {
-
-    }
+    DetachedEdge() {}
 
     protected DetachedEdge(final Edge edge, final boolean withProperties) {
         super(edge);
@@ -150,4 +148,18 @@ public class DetachedEdge extends DetachedElement<Edge> implements Edge {
     public <V> Iterator<Property<V>> properties(final String... propertyKeys) {
         return (Iterator) super.properties(propertyKeys);
     }
+
+    @Override
+    void internalAddProperty(final Property p) {
+        if (null == properties) properties = new HashMap<>();
+        this.properties.put(p.key(), Collections.singletonList(p));
+    }
+
+    void internalSetOutV(final DetachedVertex v) {
+        outVertex = v;
+    }
+
+    void internalSetInV(final DetachedVertex v) {
+        inVertex = v;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/02b00736/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
index f9c8c73..4e40303 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedElement.java
@@ -25,9 +25,12 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.util.Attachable;
 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
 import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -40,7 +43,7 @@ public abstract class DetachedElement<E> implements Element, Serializable, Attac
 
     protected Object id;
     protected String label;
-    protected Map<String, List<? extends Property>> properties = null;
+    protected Map<String, List<Property>> properties = null;
 
     protected DetachedElement() {
 
@@ -106,4 +109,14 @@ public abstract class DetachedElement<E> implements Element, Serializable, Attac
     public E get() {
         return (E) this;
     }
+
+    abstract void internalAddProperty(final Property p);
+
+    void internalSetId(final Object id) {
+        this.id = id;
+    }
+
+    void inernalSetLabel(final String label) {
+        this.label = label;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/02b00736/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java
new file mode 100644
index 0000000..f2c658d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedUtil.java
@@ -0,0 +1,70 @@
+/*
+ * 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.tinkerpop.gremlin.structure.util.detached;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class DetachedUtil {
+
+    private DetachedUtil() {}
+
+    /**
+     * Provides a way to mutate something that is "detached". This method is really for internal usage as there
+     * typically is not need for application developers to mutate a "detached" element.
+     */
+    public static void addProperty(final DetachedElement e, final DetachedProperty p) {
+        e.internalAddProperty(p);
+    }
+    public static void addProperty(final DetachedVertex v, final DetachedVertexProperty vp) {
+        v.internalAddProperty(vp);
+    }
+
+    public static void setId(final DetachedElement e, final Object id) {
+        e.internalSetId(id);
+    }
+
+    public static void setLabel(final DetachedElement e, final String label) {
+        e.inernalSetLabel(label);
+    }
+
+    public static void setValue(final DetachedVertexProperty vp, final Object value) {
+        vp.internalSetValue(value);
+    }
+
+    public static DetachedVertex newDetachedVertex() {
+        return new DetachedVertex();
+    }
+
+    public static DetachedVertexProperty newDetachedVertexProperty() {
+        return new DetachedVertexProperty();
+    }
+
+    public static DetachedEdge newDetachedEdge() {
+        return new DetachedEdge();
+    }
+
+    public static void setInV(final DetachedEdge e, final DetachedVertex v) {
+        e.internalSetInV(v);
+    }
+
+    public static void setOutV(final DetachedEdge e, final DetachedVertex v) {
+        e.internalSetOutV(v);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/02b00736/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
index d3fbd8e..15e956b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertex.java
@@ -22,8 +22,10 @@ import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
@@ -53,8 +55,7 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
     private static final String VALUE = "value";
     private static final String PROPERTIES = "properties";
 
-    private DetachedVertex() {
-    }
+    DetachedVertex() {}
 
     protected DetachedVertex(final Vertex vertex, final boolean withProperties) {
         super(vertex);
@@ -67,7 +68,7 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
             if (propertyIterator.hasNext()) {
                 this.properties = new HashMap<>();
                 propertyIterator.forEachRemaining(property -> {
-                    final List<VertexProperty<?>> list = (List<VertexProperty<?>>) this.properties.getOrDefault(property.key(), new ArrayList<>());
+                    final List<Property> list = this.properties.getOrDefault(property.key(), new ArrayList<>());
                     list.add(DetachedFactory.detach(property, true));
                     this.properties.put(property.key(), list);
                 });
@@ -80,7 +81,7 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
         if (properties != null && !properties.isEmpty()) {
             this.properties = new HashMap<>();
             properties.entrySet().iterator().forEachRemaining(entry ->
-                this.properties.put(entry.getKey(), IteratorUtils.<VertexProperty>list(IteratorUtils.map(((List<Object>) entry.getValue()).iterator(),
+                this.properties.put(entry.getKey(), IteratorUtils.<Property>list(IteratorUtils.map(((List<Object>) entry.getValue()).iterator(),
                         m -> VertexProperty.class.isAssignableFrom(m.getClass())
                                 ? (VertexProperty) m
                                 : new DetachedVertexProperty<>(((Map) m).get(ID), entry.getKey(), ((Map) m).get(VALUE), (Map<String, Object>) ((Map) m).getOrDefault(PROPERTIES, new HashMap<>()), this)))));
@@ -143,4 +144,14 @@ public class DetachedVertex extends DetachedElement<Vertex> implements Vertex {
     public void remove() {
         throw Vertex.Exceptions.vertexRemovalNotSupported();
     }
+
+    @Override
+    void internalAddProperty(final Property p) {
+        if (null == properties) properties = new HashMap<>();
+
+        if (!properties.containsKey(p.key()))
+            properties.put(p.key(), new ArrayList<>());
+
+        this.properties.get(p.key()).add(p);
+    }
 }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/02b00736/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
index 069c14c..f682e04 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/detached/DetachedVertexProperty.java
@@ -18,7 +18,6 @@
  */
 package org.apache.tinkerpop.gremlin.structure.util.detached;
 
-import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
@@ -40,8 +39,7 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V>
     protected V value;
     protected transient DetachedVertex vertex;
 
-    private DetachedVertexProperty() {
-    }
+    DetachedVertexProperty() {}
 
     protected DetachedVertexProperty(final VertexProperty<V> vertexProperty, final boolean withProperties) {
         super(vertexProperty);
@@ -127,4 +125,14 @@ public class DetachedVertexProperty<V> extends DetachedElement<VertexProperty<V>
     public <U> Iterator<Property<U>> properties(final String... propertyKeys) {
         return (Iterator) super.properties(propertyKeys);
     }
+
+    @Override
+    void internalAddProperty(final Property p) {
+        if (null == properties) properties = new HashMap<>();
+        this.properties.put(p.key(), Collections.singletonList(p));
+    }
+
+    void internalSetValue(final V value) {
+        this.value = value;
+    }
 }