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/23 20:59:37 UTC
[2/2] tinkerpop git commit: TINKERPOP-1676 Improved speed and memory
usage of GraphSON
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/b1870c22
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/b1870c22
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/b1870c22
Branch: refs/heads/TINKERPOP-1676
Commit: b1870c225f971792ce61f417537f6f7b71bbc011
Parents: deb2fec
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue May 23 16:57:12 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue May 23 16:57:12 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/b1870c22/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 1f89598..3ff6cea 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`.
* Reduced memory usage for TinkerGraph deserialization in GraphSON by streaming vertices and edges.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b1870c22/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/b1870c22/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/b1870c22/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;
+ }
}
}