make TinkerGraph cloneable
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/a44e8815 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/a44e8815 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/a44e8815 Branch: refs/heads/master Commit: a44e881533a29231752ed4884d3a87c63bf4befc Parents: 132011f Author: Michael Pollmeier <mich...@michaelpollmeier.com> Authored: Mon Sep 4 20:02:26 2017 +1200 Committer: Michael Pollmeier <mich...@michaelpollmeier.com> Committed: Thu Sep 21 14:08:27 2017 +1200 ---------------------------------------------------------------------- .../tinkergraph/structure/TinkerGraph.java | 17 ++++++++++- .../tinkergraph/structure/TinkerGraphTest.java | 30 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a44e8815/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java ---------------------------------------------------------------------- diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java index 5563665..6501663 100644 --- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java +++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java @@ -30,9 +30,13 @@ import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.structure.io.Io; import org.apache.tinkerpop.gremlin.structure.io.IoCore; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion; +import org.apache.tinkerpop.gremlin.structure.io.gryo.GryoVersion; +import org.apache.tinkerpop.gremlin.structure.util.Attachable; import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; import org.apache.tinkerpop.gremlin.structure.util.GraphFactory; import org.apache.tinkerpop.gremlin.structure.util.StringFactory; +import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory; import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputer; import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputerView; import org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.strategy.optimization.TinkerGraphCountStrategy; @@ -70,7 +74,7 @@ import java.util.stream.Stream; @Graph.OptIn(Graph.OptIn.SUITE_GROOVY_ENVIRONMENT) @Graph.OptIn(Graph.OptIn.SUITE_GROOVY_ENVIRONMENT_INTEGRATE) @Graph.OptIn(Graph.OptIn.SUITE_GROOVY_ENVIRONMENT_PERFORMANCE) -public final class TinkerGraph implements Graph { +public final class TinkerGraph implements Graph, Cloneable { static { TraversalStrategies.GlobalCache.registerStrategies(TinkerGraph.class, TraversalStrategies.GlobalCache.getStrategies(Graph.class).clone().addStrategies( @@ -378,6 +382,17 @@ public final class TinkerGraph implements Graph { } } + /** + * make a deep clone of the graph/vertices/edges that preserves ids + */ + @Override + public TinkerGraph clone() { + final TinkerGraph cloned = new TinkerGraph(configuration); + vertices().forEachRemaining(v -> DetachedFactory.detach(v, true).attach(Attachable.Method.create(cloned))); + edges().forEachRemaining(e -> DetachedFactory.detach(e, true).attach(Attachable.Method.create(cloned))); + return cloned; + } + public class TinkerGraphFeatures implements Features { private final TinkerGraphGraphFeatures graphFeatures = new TinkerGraphGraphFeatures(); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a44e8815/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphTest.java ---------------------------------------------------------------------- diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphTest.java index a85b0ee..cb4f4d7 100644 --- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphTest.java +++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphTest.java @@ -68,6 +68,7 @@ import java.util.function.Consumer; import java.util.function.Supplier; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -593,6 +594,35 @@ public class TinkerGraphTest { } } + @Test + public void shouldClone() { + final TinkerGraph g = TinkerGraph.open(); + + final Vertex marko = g.addVertex("name", "marko", "age", 29); + final Vertex stephen = g.addVertex("name", "stephen", "age", 35); + marko.addEdge("knows", stephen); + + final TinkerGraph g2 = g.clone(); + final Vertex michael = g2.addVertex("name", "michael"); + michael.addEdge("likes", marko); + michael.addEdge("likes", stephen); + g2.traversal().V().property("newProperty", "someValue").toList(); + g2.traversal().E().property("newProperty", "someValue").toList(); + + assertEquals("original graph should be unchanged", new Long(2), g.traversal().V().count().next()); + assertEquals("original graph should be unchanged", new Long(1), g.traversal().E().count().next()); + assertEquals("original graph should be unchanged", new Long(0), g.traversal().V().has("newProperty").count().next()); + + assertEquals("cloned graph should contain new elements", new Long(3), g2.traversal().V().count().next()); + assertEquals("cloned graph should contain new elements", new Long(3), g2.traversal().E().count().next()); + assertEquals("cloned graph should contain new property", new Long(3), g2.traversal().V().has("newProperty").count().next()); + assertEquals("cloned graph should contain new property", new Long(3), g2.traversal().E().has("newProperty").count().next()); + + assertNotSame("cloned elements should reference to different objects", + g.traversal().V().has("name", "stephen").next(), + g2.traversal().V().has("name", "stephen").next()); + } + /** * Coerces a {@code Color} to a {@link TinkerGraph} during serialization. Demonstrates how custom serializers * can be developed that can coerce one value to another during serialization.