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"));
+ }
+
}
}