added more test patterns to PathRestractionStrategy ... tweaked up NativeNeo4jCypherCheck as not all results need to return everything matched.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/632a67d8 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/632a67d8 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/632a67d8 Branch: refs/heads/TINKERPOP-1278 Commit: 632a67d817a10ba11b80f2b27ee09654b2c1c1cc Parents: 01fd5dc Author: Marko A. Rodriguez <okramma...@gmail.com> Authored: Mon Jul 11 10:46:04 2016 -0600 Committer: Marko A. Rodriguez <okramma...@gmail.com> Committed: Mon Jul 11 10:46:04 2016 -0600 ---------------------------------------------------------------------- .../optimization/PathRetractionStrategy.java | 3 +- .../PathRetractionStrategyTest.java | 4 ++ .../neo4j/process/NativeNeo4jCypherCheck.java | 60 ++++++++++++-------- 3 files changed, 42 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/632a67d8/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategy.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategy.java index ee697f3..2ff22ba 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategy.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategy.java @@ -26,7 +26,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.LambdaHolder; import org.apache.tinkerpop.gremlin.process.traversal.step.PathProcessor; import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep; import org.apache.tinkerpop.gremlin.process.traversal.step.filter.DedupGlobalStep; -import org.apache.tinkerpop.gremlin.process.traversal.step.map.MapStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep; import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep; @@ -107,6 +106,8 @@ public final class PathRetractionStrategy extends AbstractTraversalStrategy<Trav // OLTP barrier optimization that will try and bulk traversers after a path processor step to thin the stream if (!onGraphComputer && + !(currentStep instanceof MatchStep) && + !(currentStep instanceof Barrier) && !(currentStep.getNextStep() instanceof Barrier) && !(currentStep.getTraversal().getParent() instanceof MatchStep)) TraversalHelper.insertAfterStep(new NoOpBarrierStep<>(traversal, this.standardBarrierSize), currentStep, traversal); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/632a67d8/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategyTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategyTest.java index 4404cfd..0063289 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategyTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PathRetractionStrategyTest.java @@ -142,6 +142,10 @@ public class PathRetractionStrategyTest { {__.V().as("a").out().as("b").select("a").out().out(), "[[]]", __.V().as("a").out().as("b").select("a").barrier(DEFAULT_STANDARD_BARRIER_SIZE).out().out()}, {__.V().as("a").out().as("b").select("a").count(), "[[]]", __.V().as("a").out().as("b").select("a").count()}, {__.V().as("a").out().as("b").select("a").barrier().count(), "[[]]", __.V().as("a").out().as("b").select("a").barrier().count()}, + {__.V().as("a").out().as("b").dedup("a", "b").out(), "[[]]", __.V().as("a").out().as("b").dedup("a", "b").out()}, + {__.V().as("a").out().as("b").match(as("a").out().as("b")), "[[a, b]]", __.V().as("a").out().as("b").match(as("a").out().as("b"))}, + {__.V().as("a").out().as("b").match(as("a").out().as("b")).select("a"), "[[a], []]", __.V().as("a").out().as("b").match(as("a").out().as("b")).select("a").barrier(DEFAULT_STANDARD_BARRIER_SIZE)}, + {__.V().as("a").out().as("b").match(as("a").out().as("b")).select("a").out().dedup("a"), "[[a], [a], []]", __.V().as("a").out().as("b").match(as("a").out().as("b")).select("a").barrier(DEFAULT_STANDARD_BARRIER_SIZE).out().dedup("a")}, {__.V().as("a").out().as("b").where(P.gt("a")).out().out(), "[[]]", __.V().as("a").out().as("b").where(P.gt("a")).barrier(DEFAULT_STANDARD_BARRIER_SIZE).out().out()}, {__.V().as("a").out().as("b").where(P.gt("a")).count(), "[[]]", __.V().as("a").out().as("b").where(P.gt("a")).count()}, {__.V().as("a").out().as("b").select("a").as("c").where(P.gt("b")).out(), "[[b], []]", __.V().as("a").out().as("b").select("a").as("c").barrier(DEFAULT_STANDARD_BARRIER_SIZE).where(P.gt("b")).barrier(DEFAULT_STANDARD_BARRIER_SIZE).out()}, http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/632a67d8/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherCheck.java ---------------------------------------------------------------------- diff --git a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherCheck.java b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherCheck.java index 07ff06e..390c749 100644 --- a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherCheck.java +++ b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherCheck.java @@ -42,7 +42,9 @@ import java.util.function.Supplier; import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as; import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.where; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * @author Marko A. Rodriguez (http://markorodriguez.com) @@ -142,72 +144,82 @@ public class NativeNeo4jCypherCheck extends AbstractNeo4jGremlinTest { final List<Supplier<GraphTraversal<?, ?>>> traversals = Arrays.asList( () -> g.V().match( as("a").in("sungBy").as("b"), - as("a").in("writtenBy").as("b")).select("a","b").by("name"), - () -> n.cypher("MATCH (a)<-[:sungBy]-(b), (a)<-[:writtenBy]-(b) RETURN a, b").select("a","b").by("name"), + as("a").in("writtenBy").as("b")).select("a", "b").by("name"), + () -> n.cypher("MATCH (a)<-[:sungBy]-(b), (a)<-[:writtenBy]-(b) RETURN a.name, b.name"), /// () -> g.V().match( as("a").out("followedBy").as("b"), - as("b").out("followedBy").as("a")).select("a","b").by("name"), - () -> n.cypher("MATCH (a)-[:followedBy]->(b), (b)-[:followedBy]->(a) RETURN a, b").select("a","b").by("name"), + as("b").out("followedBy").as("a")).select("a", "b").by("name"), + () -> n.cypher("MATCH (a)-[:followedBy]->(b), (b)-[:followedBy]->(a) RETURN a.name, b.name"), /// () -> g.V().match( as("a").out("followedBy").count().as("b"), as("a").in("followedBy").count().as("b"), as("b").is(P.gt(10))).select("a").by("name"), - () -> n.cypher("MATCH (a)-[:followedBy]->(b) WITH a, COUNT(b) AS bc WHERE bc > 10 MATCH (a)<-[:followedBy]-(c) WITH a, bc, COUNT(c) AS cc WHERE bc = cc RETURN a").select("a").by("name"), + () -> n.cypher("MATCH (a)-[:followedBy]->(b) WITH a, COUNT(b) AS bc WHERE bc > 10 MATCH (a)<-[:followedBy]-(c) WITH a, bc, COUNT(c) AS cc WHERE bc = cc RETURN a.name"), /// - () -> g.V().match( + /*() -> g.V().match( as("a").in("sungBy").count().as("b"), as("a").in("sungBy").as("c"), as("c").out("followedBy").as("d"), as("d").out("sungBy").as("e"), as("e").in("sungBy").count().as("b"), where("a", P.neq("e"))).select("a", "e").by("name"), - () -> n.cypher("MATCH (a)<-[:sungBy]-()-[:followedBy]->()-[:sungBy]->(e) WHERE a <> e WITH a, e MATCH (a)<-[:sungBy]-(b) WITH a, e, COUNT(DISTINCT b) as bc MATCH (e)<-[:sungBy]-(f) WITH a, e, bc, COUNT(DISTINCT f) as fc WHERE bc = fc RETURN a, e").select("a", "e").by("name"), - /// + () -> n.cypher("MATCH (a)<-[:sungBy]-()-[:followedBy]->()-[:sungBy]->(e) WHERE a <> e WITH a, e MATCH (a)<-[:sungBy]-(b) WITH a, e, COUNT(DISTINCT b) as bc MATCH (e)<-[:sungBy]-(f) WITH a, e, bc, COUNT(DISTINCT f) as fc WHERE bc = fc RETURN a.name, e.name"), + *//// () -> g.V().match( as("a").in("followedBy").as("b"), as("a").out("sungBy").as("c"), - as("a").out("writtenBy").as("d")).select("a","b","c","d").by("name"), - () -> n.cypher("MATCH (a)<-[:followedBy]-(b), (a)-[:sungBy]->(c), (a)-[:writtenBy]->(d) RETURN a, b, c, d").select("a","b","c","d").by("name"), + as("b").out("sungBy").as("c")).select("a", "b"), + () -> n.cypher("MATCH (a)<-[:followedBy]-(b), (a)-[:sungBy]->(c), (b)-[:sungBy]->(c) RETURN a, b"), /// () -> g.V().match( as("a").in("followedBy").as("b"), as("a").out("sungBy").as("c"), as("a").out("writtenBy").as("d"), - where("c", P.neq("d"))).select("a","b","c","d").by("name"), - () -> n.cypher("MATCH (a)<-[:followedBy]-(b), (a)-[:sungBy]->(c), (a)-[:writtenBy]->(d) WHERE c <> d RETURN a, b, c, d").select("a","b","c","d").by("name"), + as("b").out("sungBy").as("c"), + as("b").out("writtenBy").as("d"), + where("c", P.neq("d"))).select("a", "b").by("name"), + () -> n.cypher("MATCH (a)<-[:followedBy]-(b), (a)-[:sungBy]->(c), (a)-[:writtenBy]->(d), (b)-[:sungBy]->(c), (b)-[:writtenBy]->(d) WHERE c <> d RETURN a.name, b.name"), /// () -> g.V().match( as("a").in("sungBy").as("b"), as("a").in("writtenBy").as("b"), as("b").out("followedBy").as("c"), as("c").out("sungBy").as("a"), - as("c").out("writtenBy").as("a")).select("a", "b", "c").by("name"), - () -> n.cypher("MATCH (a)<-[:sungBy]-(b), (a)<-[:writtenBy]-(b), (b)-[:followedBy]->(c), (c)-[:sungBy]->(a), (c)-[:writtenBy]->(a) RETURN a, b, c").select("a", "b", "c").by("name"), + as("c").out("writtenBy").as("a")).select("a").by("name"), + () -> n.cypher("MATCH (a)<-[:sungBy]-(b), (a)<-[:writtenBy]-(b), (b)-[:followedBy]->(c), (c)-[:sungBy]->(a), (c)-[:writtenBy]->(a) RETURN a.name"), /// () -> g.V().match( as("a").has("name", "Garcia").has(T.label, "artist"), as("a").in("writtenBy").as("b"), as("b").out("followedBy").as("c"), as("c").out("writtenBy").as("d"), - as("d").where(P.neq("a"))).select("a","b","c","d").by("name"), - () -> n.cypher("MATCH (a)<-[:writtenBy]-(b), (b)-[:followedBy]->(c), (c)-[:writtenBy]->(d) WHERE a <> d AND a.name = 'Garcia' AND 'artist' IN labels(a) RETURN a, b, c, d").select("a","b","c","d").by("name"), + as("d").where(P.neq("a"))).select("a", "d").by("name"), + () -> n.cypher("MATCH (a)<-[:writtenBy]-(b), (b)-[:followedBy]->(c), (c)-[:writtenBy]->(d) WHERE a <> d AND a.name = 'Garcia' AND 'artist' IN labels(a) RETURN a.name, d.name"), /// () -> g.V().match( + as("a").out("followed").as("b"), + as("b").out("followed").as("c")).select("a").by("name"), + () -> n.cypher("MATCH ((a)-[:followedBy]->(b), (b)-[:followedBy]->(c) RETURN a.name") + /// + /*() -> g.V().match( as("a").out("followedBy").as("b"), as("a").has(T.label, "song").has("performances", P.gt(10)), as("a").out("writtenBy").as("c"), as("b").out("writtenBy").as("c")).select("a", "b", "c").by("name"), - () -> n.cypher("MATCH (a)-[:followedBy]->(b), (a)-[:writtenBy]->(c), (b)-[:writtenBy]->(c) WHERE a.performances > 10 AND 'song' IN labels(a) RETURN a, b, c").select("a","b","c").by("name") + () -> n.cypher("MATCH (a)-[:followedBy]->(b), (a)-[:writtenBy]->(c), (b)-[:writtenBy]->(c) WHERE a.performances > 10 AND 'song' IN labels(a) RETURN a, b, c").select("a","b","c").by("name")*/ ); - int counter = 0; - for (final Supplier<GraphTraversal<?, ?>> traversal : traversals) { - logger.info("pre-strategy: {}", traversal.get()); - logger.info("post-strategy: {}", traversal.get().iterate()); - logger.info(TimeUtil.clockWithResult(25, () -> traversal.get().count().next()).toString()); - if (++counter % 2 == 0) + + for (int i = 0; i < traversals.size(); i = i + 2) { + final Supplier<GraphTraversal<?, ?>> gremlin = traversals.get(i); + final Supplier<GraphTraversal<?, ?>> cypher = traversals.get(i + 1); + for (final Supplier<GraphTraversal<?, ?>> sub : Arrays.asList(cypher, gremlin)) { + logger.info("pre-strategy: {}", sub.get()); + logger.info("post-strategy: {}", sub.get().iterate()); + logger.info(TimeUtil.clockWithResult(25, () -> sub.get().count().next()).toString()); logger.info("------------------"); + } } }