added a lazy barrier to OLTP MatchStep (added a TODO note that in the future we 
may want to make MatchStep a LocalBarrierStep). Tweaked up the OLTP 
PrunePathStrategy optimization to only do lazy barriers if the parent is NOT a 
MatchStep (as the MatchStep is a lazy barrier now). Lightened up the 
IdentityRemoveStrategy sensitivty as recommended by @tdwilmes ... Epic stuff.


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

Branch: refs/heads/TINKERPOP-1278
Commit: 983538d75d55150d5290492cf386eb46ad95db55
Parents: 43c6108
Author: Marko A. Rodriguez <okramma...@gmail.com>
Authored: Sun Jul 10 12:48:06 2016 -0600
Committer: Marko A. Rodriguez <okramma...@gmail.com>
Committed: Sun Jul 10 12:48:06 2016 -0600

----------------------------------------------------------------------
 .../process/traversal/step/map/MatchStep.java   | 22 +++++++-----
 .../optimization/PrunePathStrategy.java         | 14 ++++----
 .../process/traversal/util/PathUtil.java        | 14 +++++---
 .../IdentityRemovalStrategyTest.java            |  2 +-
 .../optimization/PrunePathStrategyTest.java     | 13 ++++----
 .../structure/TinkerGraphPlayTest.java          | 35 ++++++++------------
 6 files changed, 52 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/983538d7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
index 6983bd1..813b85c 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
@@ -38,7 +38,9 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.step.util.ComputerAwareSte
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.ProfileStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConnectiveStrategy;
+import 
org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PrunePathStrategy;
 import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
 import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.PathUtil;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
@@ -313,28 +315,33 @@ public final class MatchStep<S, E> extends 
ComputerAwareStep<S, Map<String, E>>
         return false;
     }
 
+    private final TraverserSet standardAlgorithmBarrier = new TraverserSet();
+
     @Override
     protected Iterator<Traverser.Admin<Map<String, E>>> standardAlgorithm() 
throws NoSuchElementException {
         while (true) {
-            Traverser.Admin traverser = null;
+
             if (this.first) {
                 this.first = false;
                 this.initializeMatchAlgorithm(TraversalEngine.Type.STANDARD);
-            } else {
+            } else if (this.standardAlgorithmBarrier.isEmpty()) {
                 for (final Traversal.Admin<?, ?> matchTraversal : 
this.matchTraversals) {
-                    if (matchTraversal.hasNext()) {
-                        traverser = matchTraversal.getEndStep().next();
-                        break;
+                    while (matchTraversal.hasNext() &&
+                            this.standardAlgorithmBarrier.size() < 
PrunePathStrategy.MAX_BARRIER_SIZE) { // TODO: perhaps make MatchStep a 
LocalBarrierStep ??
+                        
this.standardAlgorithmBarrier.add(matchTraversal.getEndStep().next());
                     }
                 }
             }
-            if (null == traverser) {
+            final Traverser.Admin traverser;
+            if (this.standardAlgorithmBarrier.isEmpty()) {
                 traverser = this.starts.next();
                 if (!traverser.getTags().contains(this.getId())) {
                     traverser.getTags().add(this.getId()); // so the traverser 
never returns to this branch ever again
                     if (!this.hasPathLabel(traverser.path(), 
this.matchStartLabels))
                         
traverser.addLabels(Collections.singleton(this.computedStartLabel)); // if the 
traverser doesn't have a legal start, then provide it the pre-computed one
                 }
+            } else {
+                traverser = this.standardAlgorithmBarrier.remove();
             }
             ///
             if (!this.isDuplicate(traverser)) {
@@ -499,7 +506,7 @@ public final class MatchStep<S, E> extends 
ComputerAwareStep<S, Map<String, E>>
             MatchStep parent = ((MatchStep) 
this.getTraversal().getParent().asStep());
             if (null != parent.getKeepLabels()) {
                 final Set<String> keepers = new HashSet<>();
-                for (final Traversal.Admin<?, ?> traversal : 
(List<Traversal.Admin<?, ?>>)parent.getRemainingTraversals(traverser)) {
+                for (final Traversal.Admin<?, ?> traversal : 
(List<Traversal.Admin<?, ?>>) parent.getRemainingTraversals(traverser)) {
                     keepers.addAll(PathUtil.getReferencedLabels(traversal));
                 }
                 keepers.addAll(parent.getKeepLabels());
@@ -511,7 +518,6 @@ public final class MatchStep<S, E> extends 
ComputerAwareStep<S, Map<String, E>>
         protected Traverser.Admin<Object> processNextStart() throws 
NoSuchElementException {
 
 
-
             while (true) {
                 final Traverser.Admin traverser = this.starts.next();
                 // no end label

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/983538d7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
index efd2949..b8a5b39 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
@@ -38,17 +38,16 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
  * @author Ted Wilmes (http://twilmes.org)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class PrunePathStrategy extends 
AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements 
TraversalStrategy.OptimizationStrategy {
 
-    public static Integer MAX_BARRIER_SIZE = 1000;
+    public static Integer MAX_BARRIER_SIZE = 2500;
 
     private static final PrunePathStrategy INSTANCE = new PrunePathStrategy();
     // these strategies do strong rewrites involving path labeling and thus, 
should run prior to PrunePathStrategy
@@ -74,7 +73,7 @@ public final class PrunePathStrategy extends 
AbstractTraversalStrategy<Traversal
         final boolean hasPathStep = TraversalHelper.anyStepRecursively(step -> 
step.getRequirements().contains(TraverserRequirement.PATH), traversal);
         if (hasPathStep) {
             for (final Step<?, ?> step : traversal.getSteps()) {
-                if(step instanceof PathProcessor) {
+                if (step instanceof PathProcessor) {
                     ((PathProcessor) step).setKeepLabels(null);
                 }
             }
@@ -104,7 +103,7 @@ public final class PrunePathStrategy extends 
AbstractTraversalStrategy<Traversal
                 } else
                     ((PathProcessor) currentStep).setKeepLabels(new 
HashSet<>(keepLabels));
 
-                if (currentStep.getTraversal().getParent().asStep() instanceof 
MatchStep) {
+                if (currentStep.getTraversal().getParent() instanceof 
MatchStep) {
                     pathProcessor.setKeepLabels(((MatchStep) 
currentStep.getTraversal().getParent().asStep()).getMatchStartLabels());
                     pathProcessor.getKeepLabels().addAll(((MatchStep) 
currentStep.getTraversal().getParent().asStep()).getMatchEndLabels());
                 }
@@ -112,7 +111,8 @@ public final class PrunePathStrategy extends 
AbstractTraversalStrategy<Traversal
                 // OLTP barrier optimization that will try and bulk traversers 
after a path processor step to thin the stream
                 if (!onGraphComputer &&
                         !(currentStep.getNextStep() instanceof 
ReducingBarrierStep) &&
-                        !(currentStep.getNextStep() instanceof 
NoOpBarrierStep))
+                        !(currentStep.getNextStep() instanceof 
NoOpBarrierStep) &&
+                        !(currentStep.getTraversal().getParent() instanceof 
MatchStep))
                     TraversalHelper.insertAfterStep(new 
NoOpBarrierStep<>(traversal, MAX_BARRIER_SIZE), currentStep, traversal);
             }
         }
@@ -123,7 +123,7 @@ public final class PrunePathStrategy extends 
AbstractTraversalStrategy<Traversal
         Step<?, ?> parent = traversal.getParent().asStep();
         final List<Pair<Step, Set<String>>> parentKeeperPairs = new 
ArrayList<>();
         while (!parent.equals(EmptyStep.instance())) {
-            parentKeeperPairs.add(new Pair<>(parent, 
PathUtil.whichLabelsReferencedFromHereForward(parent, foundLabels)));
+            parentKeeperPairs.add(new Pair<>(parent, 
PathUtil.whichLabelsReferencedFromHereForward(parent)));
             parent = parent.getTraversal().getParent().asStep();
         }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/983538d7/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
index 87ecc9e..64e418f 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
@@ -35,12 +35,16 @@ import java.util.Set;
  */
 public class PathUtil {
 
+    private PathUtil() {
+        // static public methods only
+    }
+
     public static Set<String> getReferencedLabelsAfterStep(Step<?, ?> step) {
-        if(step.getNextStep().equals(EmptyStep.instance())) {
+        if (step.getNextStep().equals(EmptyStep.instance())) {
             return Collections.emptySet();
         }
         final Set<String> labels = new HashSet<>();
-        while(!(step = step.getNextStep()).equals(EmptyStep.instance())) {
+        while (!(step = step.getNextStep()).equals(EmptyStep.instance())) {
             labels.addAll(PathUtil.getReferencedLabels(step));
         }
         return labels;
@@ -54,11 +58,11 @@ public class PathUtil {
         return referencedLabels;
     }
 
-    public static Set<String> whichLabelsReferencedFromHereForward(Step<?, ?> 
step, final Set<String> labels) {
+    public static Set<String> whichLabelsReferencedFromHereForward(Step<?, ?> 
step) {
         final Set<String> found = new HashSet<>();
-        while(!step.equals(EmptyStep.instance())) {
+        while (!step.equals(EmptyStep.instance())) {
             final Set<String> referencedLabels = getReferencedLabels(step);
-            for(final String refLabel : referencedLabels) {
+            for (final String refLabel : referencedLabels) {
                 found.add(refLabel);
             }
             step = step.getNextStep();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/983538d7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
index 065dc53..b14798e 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
@@ -95,7 +95,7 @@ public class IdentityRemovalStrategyTest {
 
             return new Iterator<GraphTraversal>() {
 
-                final int minIdentities = 3;
+                final int minIdentities = 5;
                 final int maxIdentities = 10;
                 final Integer[] starts = IntStream.range(0, 
1000).boxed().toArray(Integer[]::new);
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/983538d7/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
----------------------------------------------------------------------
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
index 97c6f50..44cc333 100644
--- 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
@@ -51,6 +51,7 @@ import static org.junit.Assert.assertEquals;
 
 /**
  * @author Ted Wilmes (http://twilmes.org)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 @RunWith(Parameterized.class)
 public class PrunePathStrategyTest {
@@ -166,16 +167,16 @@ public class PrunePathStrategyTest {
                 
{__.V().select("a").map(select("c").map(select("b"))).select("c"),
                         "[[b, c], [[b, c], [[c]]], []]", null},
                 
{__.V().select("a").map(select("b").repeat(select("c"))).select("a"),
-                    "[[a, b, c], [[a, c], [[a, c]]], []]", null},
+                        "[[a, b, c], [[a, c], [[a, c]]], []]", null},
                 
{__.V().select("c").map(select("c").map(select("c"))).select("c"), "[[c], [[c], 
[[c]]], []]", null},
                 
{__.V().select("c").map(select("c").map(select("c"))).select("b"), "[[b, c], 
[[b, c], [[b]]], []]", null},
-                 
{__.V().select("a").map(select("c").map(select("b"))).select("c"),
+                
{__.V().select("a").map(select("c").map(select("b"))).select("c"),
                         "[[b, c], [[b, c], [[c]]], []]", null},
-                 
{__.V().select("a").map(select("b").repeat(select("c"))).select("a"),
-                "[[a, b, c], [[a, c], [[a, c]]], []]", null},
-                
{__.V().out("created").project("a","b").by("name").by(__.in("created").count()).order().by(select("b")).select("a"),
 "[[[a]], []]", null},
+                
{__.V().select("a").map(select("b").repeat(select("c"))).select("a"),
+                        "[[a, b, c], [[a, c], [[a, c]]], []]", null},
+                {__.V().out("created").project("a", 
"b").by("name").by(__.in("created").count()).order().by(select("b")).select("a"),
 "[[[a]], []]", null},
                 {__.order().by("weight", 
Order.decr).store("w").by("weight").filter(values("weight").as("cw").
-                        select("w").by(limit(Scope.local, 
1)).as("mw").where("cw", 
eq("mw"))).project("from","to","weight").by(__.outV()).by(__.inV()).by("weight"),
+                        select("w").by(limit(Scope.local, 
1)).as("mw").where("cw", eq("mw"))).project("from", "to", 
"weight").by(__.outV()).by(__.inV()).by("weight"),
                         "[[[cw, mw], []]]", null}
         });
     }

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/983538d7/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
----------------------------------------------------------------------
diff --git 
a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
 
b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index e6a6c85..5bf3c48 100644
--- 
a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ 
b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -31,7 +31,6 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLIo;
-
 import org.apache.tinkerpop.gremlin.util.TimeUtil;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -39,15 +38,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.List;
 import java.util.function.Supplier;
 
-import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
-import static org.apache.tinkerpop.gremlin.process.traversal.P.gte;
 import static org.apache.tinkerpop.gremlin.process.traversal.P.lt;
 import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.and;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
 import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.choose;
@@ -60,7 +55,6 @@ import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
 import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
 import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
 import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
-import static 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.where;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)
@@ -71,23 +65,22 @@ public class TinkerGraphPlayTest {
     @Test
     @Ignore
     public void testPlay8() throws Exception {
-        Graph graph = TinkerFactory.createModern();
-        GraphTraversalSource g = 
graph.traversal().withComputer();//GraphTraversalSource.computer());
-        
//System.out.println(g.V().outE("knows").identity().inV().count().is(P.eq(5)).explain());
-        
//System.out.println(g.V().hasLabel("person").fold().order(Scope.local).by("age").toList());
-        
//System.out.println(g.V().repeat(out()).times(2).profile("m").explain());
-        final Traversal<?, ?> traversal = 
g.V().hasLabel("person").<Number>project("a", 
"b").by(__.outE().count()).by("age");
-        System.out.println(traversal.explain());
-        
//System.out.println(g.V().hasLabel("person").pageRank().by("rank").by(bothE()).values("rank").profile("m").explain());
-        //System.out.println(traversal.asAdmin().clone().toString());
-        // final Traversal<?,?> clone = traversal.asAdmin().clone();
-        // clone.asAdmin().applyStrategies();
-        // System.out.println(clone);
-        System.out.println(traversal.asAdmin().toList());
-        //System.out.println(traversal.asAdmin().getSideEffects().get("m") + " 
");
-        
//System.out.println(g.V().pageRank().order().by(PageRankVertexProgram.PAGE_RANK).valueMap().toList());
+        Graph graph = TinkerGraph.open();
+        graph.io(GraphMLIo.build()).readGraph("../data/grateful-dead.xml");
+        //Graph graph = TinkerFactory.createModern();
+
+        GraphTraversalSource g = 
graph.traversal().withStrategies(PrunePathStrategy.instance());
+        GraphTraversalSource h = 
graph.traversal().withoutStrategies(PrunePathStrategy.class);
+
+        for (final GraphTraversalSource source : Arrays.asList(h, g)) {
+            System.out.println(source.V().match(
+                    __.as("a").out().as("b"),
+                    __.as("b").out().as("c"),
+                    
__.as("c").out().as("d")).select("d").count().profile().next());
+        }
     }
 
+
     @Test
     @Ignore
     public void benchmarkGroup() throws Exception {

Reply via email to