You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2015/06/18 19:21:31 UTC

incubator-tinkerpop git commit: Cloning and MatchAlgorithm now work -- fixes a test that fails in OLAP when using CountMatchAlgorithm. Added a new MatchTest test that tests count().as('b') behavior.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master e00721d86 -> 94e993320


Cloning and MatchAlgorithm now work -- fixes a test that fails in OLAP when using CountMatchAlgorithm. Added a new MatchTest test that tests count().as('b') behavior.


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

Branch: refs/heads/master
Commit: 94e9933208313fc94f4321fb4ca28b9505758e27
Parents: e00721d
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Jun 18 11:21:22 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Jun 18 11:21:22 2015 -0600

----------------------------------------------------------------------
 .../process/traversal/step/map/MatchStep.java   | 58 ++++++++++++++------
 .../traversal/step/map/GroovyMatchTest.groovy   |  9 ++-
 .../process/traversal/step/map/MatchTest.java   | 19 ++++++-
 3 files changed, 66 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/94e99332/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 691fe8b..23fca2f 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
@@ -56,6 +56,7 @@ import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -64,6 +65,8 @@ import java.util.stream.Stream;
  */
 public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>> implements TraversalParent, Scoping {
 
+    private static final Supplier<MatchAlgorithm> MATCH_ALGORITHM = CountMatchAlgorithm::new;
+
     public enum Conjunction {AND, OR}
 
     private List<Traversal.Admin<Object, Object>> conjunctionTraversals = new ArrayList<>();
@@ -73,7 +76,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
     private Set<String> scopeKeys = null;
     private final Conjunction conjunction;
     private final String startKey;
-    private final MatchAlgorithm matchAlgorithm = new GreedyMatchAlgorithm();
+    private MatchAlgorithm matchAlgorithm = MATCH_ALGORITHM.get();
 
     public MatchStep(final Traversal.Admin traversal, final String startKey, final Conjunction conjunction, final Traversal... conjunctionTraversals) {
         super(traversal);
@@ -181,7 +184,13 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
     @Override
     public void reset() {
         super.reset();
-        //this.first = true;
+        this.first = true;
+    }
+
+    public MatchAlgorithm getMatchAlgorithm() {
+        if (!this.matchAlgorithm.initialized())  // this is important in clone()ing situations where you need the match algorithm to reinitialize
+            this.matchAlgorithm.initialize(this.conjunctionTraversals);
+        return this.matchAlgorithm;
     }
 
     @Override
@@ -191,7 +200,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         for (final Traversal.Admin<Object, Object> traversal : this.conjunctionTraversals) {
             clone.conjunctionTraversals.add(clone.integrateChild(traversal.clone()));
         }
-        // TODO: does it need to clone the match algorithm?
+        clone.matchAlgorithm = MATCH_ALGORITHM.get();
         return clone;
     }
 
@@ -227,7 +236,6 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
             Traverser.Admin traverser = null;
             if (this.first) {
                 this.first = false;
-                this.matchAlgorithm.initialize(this.conjunctionTraversals);
             } else {
                 for (final Traversal.Admin<?, ?> conjunctionTraversal : this.conjunctionTraversals) {
                     if (conjunctionTraversal.hasNext()) {
@@ -242,7 +250,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                 return IteratorUtils.of(traverser.split(this.getBindings(traverser), this));
 
             if (this.conjunction == Conjunction.AND) {
-                this.matchAlgorithm.apply(traverser).addStart(traverser); // determine which sub-pattern the traverser should try next
+                this.getMatchAlgorithm().apply(traverser).addStart(traverser); // determine which sub-pattern the traverser should try next
             } else {
                 for (final Traversal.Admin<?, ?> conjunctionTraversal : this.conjunctionTraversals) {
                     final Traverser split = traverser.split();
@@ -255,10 +263,6 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
 
     @Override
     protected Iterator<Traverser<Map<String, E>>> computerAlgorithm() throws NoSuchElementException {
-        if (this.first) {
-            this.first = false;
-            this.matchAlgorithm.initialize(this.conjunctionTraversals);
-        }
         final Traverser.Admin traverser = this.starts.next();
         if (hasMatched(this.conjunction, traverser)) {
             traverser.setStepId(this.getNextStep().getId());
@@ -266,7 +270,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         }
 
         if (this.conjunction == Conjunction.AND) {
-            final Traversal.Admin<Object, Object> conjunctionTraversal = this.matchAlgorithm.apply(traverser); // determine which sub-pattern the traverser should try next
+            final Traversal.Admin<Object, Object> conjunctionTraversal = this.getMatchAlgorithm().apply(traverser); // determine which sub-pattern the traverser should try next
             traverser.setStepId(conjunctionTraversal.getStartStep().getId()); // go down the traversal match sub-pattern
             return IteratorUtils.of(traverser);
         } else {
@@ -307,7 +311,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         protected Traverser<Object> processNextStart() throws NoSuchElementException {
             final Traverser.Admin<Object> traverser = this.starts.next();
             traverser.path().addLabel(this.getId());
-            MatchStep.this.matchAlgorithm.recordStart(traverser, this.getTraversal());
+            ((MatchStep<?, ?>) this.getTraversal().getParent()).getMatchAlgorithm().recordStart(traverser, this.getTraversal());
             // TODO: sideEffect check?
             return null == this.selectKey ? traverser : traverser.split(traverser.path().getSingle(Pop.last, this.selectKey), this);
         }
@@ -370,17 +374,19 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                 final Traverser.Admin traverser = this.starts.next();
                 // no end label
                 if (null == this.matchKey) {
-                    if (this.traverserStepIdSetByChild) traverser.setStepId(MatchStep.this.getId());
-                    MatchStep.this.matchAlgorithm.recordEnd(traverser, this.getTraversal());
+                    if (this.traverserStepIdSetByChild)
+                        traverser.setStepId(((MatchStep<?, ?>) this.getTraversal().getParent()).getId());
+                    ((MatchStep<?, ?>) this.getTraversal().getParent()).getMatchAlgorithm().recordEnd(traverser, this.getTraversal());
                     return traverser;
                 }
                 // TODO: sideEffect check?
                 // path check
                 final Path path = traverser.path();
                 if (!path.hasLabel(this.matchKey) || traverser.get().equals(path.getSingle(Pop.first, this.matchKey))) {
-                    if (this.traverserStepIdSetByChild) traverser.setStepId(MatchStep.this.getId());
+                    if (this.traverserStepIdSetByChild)
+                        traverser.setStepId(((MatchStep<?, ?>) this.getTraversal().getParent()).getId());
                     traverser.path().addLabel(this.matchKey);
-                    MatchStep.this.matchAlgorithm.recordEnd(traverser, this.getTraversal());
+                    ((MatchStep<?, ?>) this.getTraversal().getParent()).getMatchAlgorithm().recordEnd(traverser, this.getTraversal());
                     return traverser;
                 }
             }
@@ -402,6 +408,8 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
 
     public interface MatchAlgorithm extends Function<Traverser.Admin<Object>, Traversal.Admin<Object, Object>>, Serializable {
 
+        public static Function<List<Traversal.Admin<Object, Object>>, IllegalStateException> UNMATCHABLE_PATTERN = traversals -> new IllegalStateException("The provided match pattern is unsolvable: " + traversals);
+
         public static Set<String> getRequiredLabels(final Traversal.Admin<Object, Object> traversal) {
             final Step<?, ?> startStep = traversal.getStartStep();
             if (startStep instanceof Scoping)
@@ -410,6 +418,8 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                 throw new IllegalArgumentException("The provided start step must be a scoping step: " + startStep);
         }
 
+        public boolean initialized();
+
         public void initialize(final List<Traversal.Admin<Object, Object>> traversals);
 
         public default void recordStart(final Traverser.Admin<Object> traverser, final Traversal.Admin<Object, Object> traversal) {
@@ -426,9 +436,16 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         private List<Traversal.Admin<Object, Object>> traversals;
         private List<String> traversalLabels = new ArrayList<>();
         private List<Set<String>> requiredLabels = new ArrayList<>();
+        private boolean initialized = false;
+
+        @Override
+        public boolean initialized() {
+            return this.initialized;
+        }
 
         @Override
         public void initialize(final List<Traversal.Admin<Object, Object>> traversals) {
+            this.initialized = true;
             this.traversals = traversals;
             for (final Traversal.Admin<Object, Object> traversal : this.traversals) {
                 this.traversalLabels.add(traversal.getStartStep().getId());
@@ -444,7 +461,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                     return this.traversals.get(i);
                 }
             }
-            throw new IllegalStateException("The provided match pattern is unsolvable: " + this.traversals);
+            throw UNMATCHABLE_PATTERN.apply(this.traversals);
         }
     }
 
@@ -454,9 +471,16 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         private List<Integer[]> counts = new ArrayList<>();
         private List<String> traversalLabels = new ArrayList<>();
         private List<Set<String>> requiredLabels = new ArrayList<>();
+        private boolean initialized = false;
+
+        @Override
+        public boolean initialized() {
+            return this.initialized;
+        }
 
         @Override
         public void initialize(final List<Traversal.Admin<Object, Object>> traversals) {
+            this.initialized = true;
             this.traversals = traversals;
             for (int i = 0; i < this.traversals.size(); i++) {
                 final Traversal.Admin<Object, Object> traversal = this.traversals.get(i);
@@ -474,7 +498,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
                     return this.traversals.get(indexCounts[0]);
                 }
             }
-            throw new IllegalStateException("The provided match pattern is unsolvable: " + this.traversals);
+            throw UNMATCHABLE_PATTERN.apply(this.traversals);
         }
 
         public void recordEnd(final Traverser.Admin<Object> traverser, final Traversal.Admin<Object, Object> traversal) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/94e99332/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
index 2cc1879..4477226 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
@@ -223,7 +223,7 @@ public abstract class GroovyMatchTest {
         @Override
         public Traversal<Vertex, Map<String, Object>> get_g_V_matchXa_whereXa_neqXcXX__a_created_b__orXa_knows_vadas__a_0knows_and_a_hasXlabel_personXX__b_0created_c__b_0created_count_isXgtX1XXX_select_byXidX() {
             TraversalScriptHelper.compute("""
-                g.V().match('a',
+                g.V.match('a',
                     where('a', neq('c')),
                     __.as('a').out('created').as('b'),
                     or(
@@ -235,6 +235,13 @@ public abstract class GroovyMatchTest {
                     .select.by(id);
             """,g)
         }
+
+        @Override
+        public Traversal<Vertex,Map<String,Object>> get_g_V_asXaX_out_asXbX_matchXa_out_count_c__b_in_count_cX() {
+            TraversalScriptHelper.compute("""
+                g.V.as('a').out.as('b').match(__.as('a').out.count.as('c'), __.as('b').in.count.as('c'))
+            """,g)
+        }
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/94e99332/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
index 05d5ae0..36087fe 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
@@ -27,7 +27,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -105,6 +104,9 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
     // nested or/and with patterns in order that won't execute serially
     public abstract Traversal<Vertex,Map<String,Object>> get_g_V_matchXa_whereXa_neqXcXX__a_created_b__orXa_knows_vadas__a_0knows_and_a_hasXlabel_personXX__b_0created_c__b_0created_count_isXgtX1XXX_select_byXidX();
 
+    // uses local barrier count() and no start key
+    public abstract Traversal<Vertex,Map<String,Object>> get_g_V_asXaX_out_asXbX_matchXa_out_count_c__b_in_count_cX();
+
     @Test
     @LoadGraphWith(MODERN)
     public void g_V_matchXa_out_bX() throws Exception {
@@ -333,6 +335,14 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
                 "a", convertToVertexId("josh"), "b", convertToVertexId("lop"), "c", convertToVertexId("peter")),traversal);
     }
 
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_asXaX_out_asXbX_matchXa_out_count_c__b_in_count_cX() {
+        final Traversal<Vertex,Map<String,Object>> traversal = get_g_V_asXaX_out_asXbX_matchXa_out_count_c__b_in_count_cX();
+        printTraversalForm(traversal);
+        checkResults(makeMapList(3, "a",convertToVertex(graph,"marko"),"c",3l,"b",convertToVertex(graph,"lop")),traversal);
+    }
+
     public static class Traversals extends MatchTest {
         @Override
         public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa_out_bX() {
@@ -489,12 +499,17 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
                     as("a").out("created").as("b"),
                     or(
                             as("a").out("knows").has("name", "vadas"),
-                            as("a").in("knows").and().as("a").has(T.label,"person")
+                            as("a").in("knows").and().as("a").has(T.label, "person")
                     ),
                     as("b").in("created").as("c"),
                     as("b").in("created").count().is(P.gt(1)))
                     .select().by(T.id);
         }
 
+        @Override
+        public Traversal<Vertex,Map<String,Object>> get_g_V_asXaX_out_asXbX_matchXa_out_count_c__b_in_count_cX() {
+            return g.V().as("a").out().as("b").match(as("a").out().count().as("c"), as("b").in().count().as("c"));
+        }
+
     }
 }