You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/09/28 17:38:16 UTC
[16/41] tinkerpop git commit: added lots of good stuff that all
revolves around SubgraphStategy. InlineFilterStrategy tries to inline
filters. Epic. And/OrStep are now FilterSteps - epic. Lots of cleanup and
simplification of SubgraphStrategy cause of it
added lots of good stuff that all revolves around SubgraphStategy. InlineFilterStrategy tries to inline filters. Epic. And/OrStep are now FilterSteps - epic. Lots of cleanup and simplification of SubgraphStrategy cause of it.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/afcf8dff
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/afcf8dff
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/afcf8dff
Branch: refs/heads/TINKERPOP-790
Commit: afcf8dff97fdbca16adc33e4aa7244868cb1591f
Parents: 7a228ca
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Sep 23 16:03:37 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Sep 27 12:45:49 2016 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 8 +-
docs/src/reference/the-traversal.asciidoc | 21 +++-
.../process/traversal/TraversalStrategies.java | 3 +-
.../process/traversal/step/filter/AndStep.java | 19 +---
.../traversal/step/filter/ConnectiveStep.java | 2 +-
.../process/traversal/step/filter/NotStep.java | 2 +-
.../process/traversal/step/filter/OrStep.java | 14 +--
.../strategy/decoration/ConnectiveStrategy.java | 11 +-
.../strategy/decoration/SubgraphStrategy.java | 102 +++++--------------
.../optimization/InlineFilterStrategy.java | 100 ++++++++++++++++++
.../StandardVerificationStrategy.java | 18 +++-
.../process/traversal/util/TraversalHelper.java | 16 ++-
.../decoration/SubgraphStrategyTest.java | 67 +++++++++++-
.../optimization/InlineFilterStrategyTest.java | 78 ++++++++++++++
.../decoration/SubgraphStrategyProcessTest.java | 7 +-
.../TinkerGraphGroovyTranslatorProvider.java | 8 ++
16 files changed, 346 insertions(+), 130 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 0c546c5..fb1160f 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,13 +26,17 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
TinkerPop 3.2.3 (Release Date: NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Added `TraversalHelper.applySingleLevelStrategies()` which will apply a subset of strategies but not walk the child tree.
+* Added the concept that hidden labels using during traversal compilation are removed at the end during `StandardVerificationStrategy`. (*breaking*)
+* Added `InlineFilterStrategy` which will determine if a `TraversalFilterStep` or `AndStep` children are filters and if so, inline them.
+* Removed `IdentityRemovalStrategy` from the default listing as its not worth the clock cycles.
+* Removed the "!" symbol in `NotStep.toString()` as it is confusing and the `NotStep`-name is sufficient.
* Fixed a bug in `TraversalVertexProgram` (OLAP) around ordering and connectives (i.e. `and()` and `or()`).
* Added `AbstractGremlinProcessTest.checkOrderedResults()` to make testing ordered results easier.
* `AbstractLambdaTraversal` now supports a `bypassTraversal` where it is possible for strategies to redefine such lambda traversals.
* Added an internal utility `ClassFilterStep` which determines if the traverser object's class is an instance of the provided class.
-* `ConnectiveStrategy` will concatenate two traversals instead of and'ing them if they are both filter-based.
+* `ConnectiveStep` extends `FilterStep` and thus, is more appropriately categorized in the step hierarchy.
* `PropertyMapStep` supports a provided traversal for accessing the properties of the element.
-* `SubgraphStrategy` no longer `filter()`-wraps if the criteria is a chain of filters or connectives.
* `SubgraphStrategy` now supports vertex property filtering.
* Fixed a bug in Gremlin-Python `P` where predicates reversed the order of the predicates.
* Added tests to `DedupTest` for the `dedup(Scope, String...)` overload.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/docs/src/reference/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index 5d2c915..4f7bff5 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -2631,4 +2631,23 @@ This strategy is implemented such that the vertices attached to an `Edge` must b
<1> Get all vertices and their vertex property locations.
<2> Create a `SubgraphStrategy` where vertex properties must not have an `endTime`-property (thus, the current location).
-<3> Get all vertices and their current vertex property locations.
\ No newline at end of file
+<3> Get all vertices and their current vertex property locations.
+
+The example below uses all three filters: vertex, edge, and vertex property. People vertices must have lived in more than three places,
+edges must be labeled "develops," and vertex properties must be the persons current location or a non-location property.
+
+[gremlin-groovy]
+----
+graph = TinkerFactory.createTheCrew()
+g = graph.traversal().withStrategies(SubgraphStrategy.build().
+ vertices(or(hasNot('location'),properties('location').count().is(gt(3)))).
+ edges(hasLabel('develops')).
+ vertexProperties(or(hasLabel(neq('location')),hasNot('endTime'))).create())
+g.V().valueMap(true)
+g.E().valueMap(true)
+g.V().outE().inV().
+ path().
+ by('name').
+ by().
+ by('name')
+----
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
index 4b89833..a01eef6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
@@ -26,6 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.Adja
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.IdentityRemovalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.IncidentToAdjacentStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.InlineFilterStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.MatchPredicateStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.OrderLimitStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathProcessorStrategy;
@@ -204,8 +205,8 @@ public interface TraversalStrategies extends Serializable, Cloneable {
ConnectiveStrategy.instance(),
IncidentToAdjacentStrategy.instance(),
AdjacentToIncidentStrategy.instance(),
+ InlineFilterStrategy.instance(),
FilterRankingStrategy.instance(),
- IdentityRemovalStrategy.instance(),
MatchPredicateStrategy.instance(),
RepeatUnrollStrategy.instance(),
RangeByIsCountStrategy.instance(),
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AndStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AndStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AndStep.java
index 9bc6f4d..5d9d124 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AndStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/AndStep.java
@@ -22,8 +22,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import java.util.NoSuchElementException;
-
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -34,18 +32,11 @@ public final class AndStep<S> extends ConnectiveStep<S> {
}
@Override
- protected Traverser.Admin<S> processNextStart() throws NoSuchElementException {
- while (true) {
- final Traverser.Admin<S> start = this.starts.next();
- boolean alive = true;
- for (final Traversal.Admin<S, ?> traversal : this.traversals) {
- if (!TraversalUtil.test(start, traversal)) {
- alive = false;
- break;
- }
- }
- if (alive)
- return start;
+ protected boolean filter(final Traverser.Admin<S> traverser) {
+ for (final Traversal.Admin<S, ?> traversal : this.traversals) {
+ if (!TraversalUtil.test(traverser, traversal))
+ return false;
}
+ return true;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ConnectiveStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ConnectiveStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ConnectiveStep.java
index 6eac30b..08d3b2f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ConnectiveStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/ConnectiveStep.java
@@ -33,7 +33,7 @@ import java.util.stream.Stream;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public abstract class ConnectiveStep<S> extends AbstractStep<S, S> implements TraversalParent {
+public abstract class ConnectiveStep<S> extends FilterStep<S> implements TraversalParent {
public enum Connective {AND, OR}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/NotStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/NotStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/NotStep.java
index 83059ce..bdf9eec 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/NotStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/NotStep.java
@@ -64,7 +64,7 @@ public final class NotStep<S> extends FilterStep<S> implements TraversalParent {
@Override
public String toString() {
- return StringFactory.stepString(this, "!" + this.notTraversal);
+ return StringFactory.stepString(this, this.notTraversal);
}
@Override
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
index 70dc430..72866a1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/OrStep.java
@@ -22,8 +22,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import java.util.NoSuchElementException;
-
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -34,13 +32,11 @@ public final class OrStep<S> extends ConnectiveStep<S> {
}
@Override
- protected Traverser.Admin<S> processNextStart() throws NoSuchElementException {
- while (true) {
- final Traverser.Admin<S> start = this.starts.next();
- for (final Traversal.Admin<S, ?> traversal : this.traversals) {
- if (TraversalUtil.test(start, traversal))
- return start;
- }
+ protected boolean filter(final Traverser.Admin<S> traverser) {
+ for (final Traversal.Admin<S, ?> traversal : this.traversals) {
+ if (TraversalUtil.test(traverser, traversal))
+ return true;
}
+ return false;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ConnectiveStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ConnectiveStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ConnectiveStrategy.java
index 8627a70..754fb03 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ConnectiveStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/ConnectiveStrategy.java
@@ -104,14 +104,9 @@ public final class ConnectiveStrategy extends AbstractTraversalStrategy<Traversa
}
processConnectiveMarker(leftTraversal);
- if (connectiveStep instanceof AndStep) {
- if (TraversalHelper.filterOnlyTraversal(leftTraversal) && TraversalHelper.filterOnlyTraversal(rightTraversal)) {
- TraversalHelper.insertTraversal((Step) connectiveStep, rightTraversal, traversal);
- TraversalHelper.insertTraversal((Step) connectiveStep, leftTraversal, traversal);
- } else
- TraversalHelper.replaceStep((Step) connectiveStep, new AndStep(traversal, leftTraversal, rightTraversal), traversal);
-
- } else
+ if (connectiveStep instanceof AndStep)
+ TraversalHelper.replaceStep((Step) connectiveStep, new AndStep(traversal, leftTraversal, rightTraversal), traversal);
+ else
TraversalHelper.replaceStep((Step) connectiveStep, new OrStep(traversal, leftTraversal, rightTraversal), traversal);
});
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
index d961209..6ff69b2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
@@ -39,6 +39,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyMapStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyValueStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SideEffectStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
@@ -75,19 +76,11 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
private final Traversal.Admin<Edge, ?> edgeCriterion;
private final Traversal.Admin<VertexProperty, ?> vertexPropertyCriterion;
- private final boolean vertexCriterionIsAllFilter;
- private final boolean edgeCriterionIsAllFilter;
- private final boolean vertexPropertyCriterionIsAllFilter;
-
private static final Set<Class<? extends DecorationStrategy>> POSTS = Collections.singleton(ConnectiveStrategy.class);
private final String MARKER = Graph.Hidden.hide(UUID.randomUUID().toString());
private SubgraphStrategy(final Traversal<Vertex, ?> vertexCriterion, final Traversal<Edge, ?> edgeCriterion, final Traversal<VertexProperty, ?> vertexPropertyCriterion) {
- this.vertexCriterionIsAllFilter = isAllFilters(vertexCriterion);
- this.edgeCriterionIsAllFilter = isAllFilters(edgeCriterion);
- this.vertexPropertyCriterionIsAllFilter = isAllFilters(vertexPropertyCriterion);
-
this.vertexCriterion = null == vertexCriterion ? null : vertexCriterion.asAdmin();
@@ -96,26 +89,15 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
this.edgeCriterion = null == edgeCriterion ? null : edgeCriterion.asAdmin();
} else {
final Traversal.Admin<Edge, ?> vertexPredicate;
- if (this.vertexCriterionIsAllFilter) {
- final Traversal.Admin<Edge, Vertex> left = __.<Edge>inV().asAdmin();
- final Traversal.Admin<Edge, Vertex> right = __.<Edge>outV().asAdmin();
- TraversalHelper.insertTraversal(0, this.vertexCriterion.clone(), left);
- TraversalHelper.insertTraversal(0, this.vertexCriterion.clone(), right);
- vertexPredicate = __.<Edge>and(left, right).asAdmin();
- } else
- vertexPredicate = __.<Edge>and(
- __.inV().filter(this.vertexCriterion.clone()),
- __.outV().filter(this.vertexCriterion.clone())).asAdmin();
+ vertexPredicate = __.<Edge>and(
+ __.inV().filter(this.vertexCriterion.clone()),
+ __.outV().filter(this.vertexCriterion.clone())).asAdmin();
// if there is a vertex predicate then there is an implied edge filter on vertices even if there is no
// edge predicate provided by the user.
- if (null == edgeCriterion)
- this.edgeCriterion = vertexPredicate;
- else if (this.edgeCriterionIsAllFilter) {
- this.edgeCriterion = edgeCriterion.asAdmin();
- TraversalHelper.insertTraversal(this.edgeCriterion.getSteps().size() - 1, vertexPredicate, this.edgeCriterion);
- } else
- this.edgeCriterion = edgeCriterion.asAdmin().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
+ this.edgeCriterion = null == edgeCriterion ?
+ vertexPredicate :
+ edgeCriterion.asAdmin().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
}
this.vertexPropertyCriterion = null == vertexPropertyCriterion ? null : vertexPropertyCriterion.asAdmin();
@@ -128,16 +110,6 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
this.metadataLabelStartStep(this.vertexPropertyCriterion);
}
- private static final boolean isAllFilters(final Traversal<?, ?> traversal) {
- if (null == traversal)
- return false;
- for (final Step<?, ?> step : traversal.asAdmin().getSteps()) {
- if (!(step instanceof FilterStep || step instanceof ConnectiveStep))
- return false;
- }
- return true;
- }
-
private final void metadataLabelStartStep(final Traversal.Admin<?, ?> traversal) {
traversal.getStartStep().addLabel(MARKER);
for (final Step<?, ?> step : traversal.getSteps()) {
@@ -150,7 +122,7 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
private static final char processesPropertyType(Step step) {
while (!(step instanceof EmptyStep)) {
- if (step instanceof FilterStep || step instanceof ConnectiveStep)
+ if (step instanceof FilterStep || step instanceof SideEffectStep)
step = step.getPreviousStep();
else if (step instanceof GraphStep && ((GraphStep) step).returnsVertex())
return 'v';
@@ -169,10 +141,8 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
@Override
public void apply(final Traversal.Admin<?, ?> traversal) {
// do not apply subgraph strategy to already created subgraph filter branches (or else you get infinite recursion)
- if (traversal.getStartStep().getLabels().contains(MARKER)) {
- traversal.getStartStep().removeLabel(MARKER);
+ if (traversal.getStartStep().getLabels().contains(MARKER))
return;
- }
//
final List<GraphStep> graphSteps = TraversalHelper.getStepsOfAssignableClass(GraphStep.class, traversal);
final List<VertexStep> vertexSteps = TraversalHelper.getStepsOfAssignableClass(VertexStep.class, traversal);
@@ -183,7 +153,7 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
vertexStepsToInsertFilterAfter.addAll(TraversalHelper.getStepsOfAssignableClass(AddVertexStep.class, traversal));
vertexStepsToInsertFilterAfter.addAll(TraversalHelper.getStepsOfAssignableClass(AddVertexStartStep.class, traversal));
vertexStepsToInsertFilterAfter.addAll(graphSteps.stream().filter(GraphStep::returnsVertex).collect(Collectors.toList()));
- applyCriterion(vertexStepsToInsertFilterAfter, traversal, this.vertexCriterion, this.vertexCriterionIsAllFilter);
+ applyCriterion(vertexStepsToInsertFilterAfter, traversal, this.vertexCriterion);
}
if (null != this.edgeCriterion) {
@@ -191,7 +161,7 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
edgeStepsToInsertFilterAfter.addAll(TraversalHelper.getStepsOfAssignableClass(AddEdgeStep.class, traversal));
edgeStepsToInsertFilterAfter.addAll(graphSteps.stream().filter(GraphStep::returnsEdge).collect(Collectors.toList()));
edgeStepsToInsertFilterAfter.addAll(vertexSteps.stream().filter(VertexStep::returnsEdge).collect(Collectors.toList()));
- applyCriterion(edgeStepsToInsertFilterAfter, traversal, this.edgeCriterion, this.edgeCriterionIsAllFilter);
+ applyCriterion(edgeStepsToInsertFilterAfter, traversal, this.edgeCriterion);
}
// turn g.V().out() to g.V().outE().inV() only if there is an edge predicate otherwise
@@ -199,10 +169,7 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
if (step.returnsEdge())
continue;
if (null != this.vertexCriterion && null == edgeCriterion) {
- if (this.vertexCriterionIsAllFilter)
- TraversalHelper.insertTraversal((Step) step, this.vertexCriterion.clone(), traversal);
- else
- TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, (Traversal) this.vertexCriterion.clone()), step, traversal);
+ TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, (Traversal) this.vertexCriterion.clone()), step, traversal);
} else {
final VertexStep<Edge> someEStep = new VertexStep<>(traversal, Edge.class, step.getDirection(), step.getEdgeLabels());
final Step<Edge, Vertex> someVStep = step.getDirection() == Direction.BOTH ?
@@ -218,15 +185,9 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
}
if (null != this.edgeCriterion)
- if (this.edgeCriterionIsAllFilter)
- TraversalHelper.insertTraversal(someEStep, this.edgeCriterion.clone(), traversal);
- else
- TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.edgeCriterion.clone()), someEStep, traversal);
+ TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.edgeCriterion.clone()), someEStep, traversal);
if (null != this.vertexCriterion)
- if (this.edgeCriterionIsAllFilter)
- TraversalHelper.insertTraversal(someVStep, this.vertexCriterion.clone(), traversal);
- else
- TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.vertexCriterion.clone()), someVStep, traversal);
+ TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.vertexCriterion.clone()), someVStep, traversal);
}
@@ -237,12 +198,8 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
if (null != this.vertexPropertyCriterion) {
final OrStep<Object> checkPropertyCriterion = new OrStep(traversal,
new DefaultTraversal<>().addStep(new ClassFilterStep<>(traversal, VertexProperty.class, false)),
- this.vertexPropertyCriterionIsAllFilter ?
- this.vertexPropertyCriterion.clone() :
- new DefaultTraversal<>().addStep(new TraversalFilterStep<>(traversal, this.vertexPropertyCriterion.clone())));
- final Traversal.Admin nonCheckPropertyCriterion = this.vertexPropertyCriterionIsAllFilter ?
- this.vertexPropertyCriterion.clone() :
- new DefaultTraversal<>().addStep(new TraversalFilterStep<>(traversal, this.vertexPropertyCriterion.clone()));
+ new DefaultTraversal<>().addStep(new TraversalFilterStep<>(traversal, this.vertexPropertyCriterion.clone())));
+ final Traversal.Admin nonCheckPropertyCriterion = new DefaultTraversal<>().addStep(new TraversalFilterStep<>(traversal, this.vertexPropertyCriterion.clone()));
// turn all ElementValueTraversals into filters
for (final Step<?, ?> step : traversal.getSteps()) {
@@ -317,10 +274,6 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
}
}
}
- // when there is no filter()-wrap, the marked steps exist at the same traversal level
- for (final Step step : traversal.getSteps()) {
- step.removeLabel(MARKER);
- }
}
@Override
@@ -346,24 +299,15 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
}
private void applyCriterion(final List<Step> stepsToApplyCriterionAfter, final Traversal.Admin traversal,
- final Traversal.Admin<? extends Element, ?> criterion, final boolean isAllFilter) {
+ final Traversal.Admin<? extends Element, ?> criterion) {
for (final Step<?, ?> step : stepsToApplyCriterionAfter) {
- if (isAllFilter) {
- final Traversal.Admin<? extends Element, ?> criterionClone = criterion.clone();
- for (final String label : step.getLabels()) {
- step.removeLabel(label);
- criterionClone.getEndStep().addLabel(label);
- }
- TraversalHelper.insertTraversal((Step) step, criterionClone, traversal);
- } else {
- // re-assign the step label to the criterion because the label should apply seamlessly after the filter
- final Step filter = new TraversalFilterStep<>(traversal, criterion.clone());
- for (final String label : step.getLabels()) {
- step.removeLabel(label);
- filter.addLabel(label);
- }
- TraversalHelper.insertAfterStep(filter, step, traversal);
+ // re-assign the step label to the criterion because the label should apply seamlessly after the filter
+ final Step filter = new TraversalFilterStep<>(traversal, criterion.clone());
+ for (final String label : step.getLabels()) {
+ step.removeLabel(label);
+ filter.addLabel(label);
}
+ TraversalHelper.insertAfterStep(filter, step, traversal);
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
new file mode 100644
index 0000000..beeca95
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategy.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
+
+import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.optimization.GraphFilterStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.FilterStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class InlineFilterStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements TraversalStrategy.OptimizationStrategy {
+
+ private static final InlineFilterStrategy INSTANCE = new InlineFilterStrategy();
+ private static final Set<Class<? extends OptimizationStrategy>> POSTS = new HashSet<>(Arrays.asList(
+ FilterRankingStrategy.class,
+ GraphFilterStrategy.class));
+
+ private InlineFilterStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ boolean changed = true; // recursively walk child traversals trying to inline them into the current traversal line.
+ while (changed) {
+ changed = false;
+ for (final TraversalFilterStep<?> step : TraversalHelper.getStepsOfAssignableClass(TraversalFilterStep.class, traversal)) {
+ final Traversal.Admin<?, ?> childTraversal = step.getLocalChildren().get(0);
+ if (TraversalHelper.allStepsInstanceOf(childTraversal, FilterStep.class, true)) {
+ changed = true;
+ TraversalHelper.applySingleLevelStrategies(childTraversal, traversal.getStrategies(), InlineFilterStrategy.class);
+ final Step<?, ?> finalStep = childTraversal.getEndStep();
+ TraversalHelper.insertTraversal((Step) step, childTraversal, traversal);
+ traversal.removeStep(step);
+ for (final String label : step.getLabels()) {
+ finalStep.addLabel(label);
+ }
+ }
+ }
+ for (final AndStep<?> step : TraversalHelper.getStepsOfAssignableClass(AndStep.class, traversal)) {
+ if (!step.getLocalChildren().stream().filter(t -> !TraversalHelper.allStepsInstanceOf(t, FilterStep.class, true)).findAny().isPresent()) {
+ changed = true;
+ final List<Traversal.Admin<?, ?>> childTraversals = (List) step.getLocalChildren();
+ Step<?, ?> finalStep = null;
+ for (int i = childTraversals.size() - 1; i >= 0; i--) {
+ final Traversal.Admin<?, ?> childTraversal = childTraversals.get(i);
+ TraversalHelper.applySingleLevelStrategies(childTraversal, traversal.getStrategies(), InlineFilterStrategy.class);
+ if (null == finalStep)
+ finalStep = childTraversal.getEndStep();
+ TraversalHelper.insertTraversal((Step) step, childTraversals.get(i), traversal);
+
+ }
+ traversal.removeStep(step);
+ if (null != finalStep) {
+ for (final String label : step.getLabels()) {
+ finalStep.addLabel(label);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public Set<Class<? extends OptimizationStrategy>> applyPost() {
+ return POSTS;
+ }
+
+ public static InlineFilterStrategy instance() {
+ return INSTANCE;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
index 95aa2e7..4f272cc 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/StandardVerificationStrategy.java
@@ -29,8 +29,10 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierS
import org.apache.tinkerpop.gremlin.process.traversal.step.util.RequirementsStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.Graph;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -50,20 +52,28 @@ public final class StandardVerificationStrategy extends AbstractTraversalStrateg
throw new VerificationException("VertexComputing steps must be executed with a GraphComputer: " + TraversalHelper.getStepsOfAssignableClass(VertexComputing.class, traversal), traversal);
}
- traversal.getSteps().forEach(step -> {
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ final Set<String> hiddenLabels = new HashSet<>();
+ for (String label : step.getLabels()) {
+ if (Graph.Hidden.isHidden(label))
+ hiddenLabels.add(label);
+ }
+ for(final String label : hiddenLabels) {
+ step.removeLabel(label);
+ }
if (step instanceof ReducingBarrierStep && step.getTraversal().getParent() instanceof RepeatStep && step.getTraversal().getParent().getGlobalChildren().get(0).getSteps().contains(step))
throw new VerificationException("The parent of a reducing barrier can not be repeat()-step: " + step, traversal);
- });
+ }
// The ProfileSideEffectStep must be the last step, 2nd last step when accompanied by the cap step,
// or 3rd to last when the traversal ends with a RequirementsStep.
- final Step<?,?> endStep = traversal.asAdmin().getEndStep();
+ final Step<?, ?> endStep = traversal.asAdmin().getEndStep();
if (TraversalHelper.hasStepOfClass(ProfileSideEffectStep.class, traversal) &&
!(endStep instanceof ProfileSideEffectStep ||
(endStep instanceof SideEffectCapStep && endStep.getPreviousStep() instanceof ProfileSideEffectStep) ||
(endStep instanceof RequirementsStep && (
endStep.getPreviousStep() instanceof SideEffectCapStep ||
- endStep.getPreviousStep() instanceof ProfileSideEffectStep)))) {
+ endStep.getPreviousStep() instanceof ProfileSideEffectStep)))) {
throw new VerificationException("When specified, the profile()-Step must be the last step or followed only by the cap()-step and/or requirements step.", traversal);
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
index 2000a92..697dc2a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
@@ -22,6 +22,8 @@ import org.apache.tinkerpop.gremlin.process.computer.traversal.step.map.Traversa
import org.apache.tinkerpop.gremlin.process.traversal.Scope;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
@@ -30,7 +32,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.filter.FilterStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.NotStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
@@ -571,11 +572,20 @@ public final class TraversalHelper {
}
}
- public static boolean filterOnlyTraversal(final Traversal.Admin<?, ?> traversal) {
+ public static boolean allStepsInstanceOf(final Traversal.Admin<?, ?> traversal, final Class<?> classToCheck, boolean checkIsInstanceOf) {
for (final Step step : traversal.getSteps()) {
- if (!(step instanceof FilterStep) && !(step instanceof ConnectiveStep))
+ boolean isInstance = classToCheck.isInstance(step);
+ if ((isInstance && !checkIsInstanceOf) || (!isInstance && checkIsInstanceOf))
return false;
}
return true;
}
+
+ public static void applySingleLevelStrategies(final Traversal.Admin<?, ?> traversal, final TraversalStrategies traversalStrategies, final Class<? extends TraversalStrategy> stopAfterStrategy) {
+ for (final TraversalStrategy<?> strategy : traversalStrategies.toList()) {
+ strategy.apply(traversal);
+ if (null != stopAfterStrategy && stopAfterStrategy.isInstance(strategy))
+ break;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java
index 86fdb67..2e89f6b 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyTest.java
@@ -18,8 +18,10 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.AndStep;
@@ -27,11 +29,26 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilte
import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.InlineFilterStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.StandardVerificationStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import java.util.Arrays;
+
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasLabel;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.inV;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.is;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outV;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -39,11 +56,51 @@ import static org.junit.Assert.assertTrue;
/**
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
+@RunWith(Parameterized.class)
public class SubgraphStrategyTest {
+ @Parameterized.Parameter(value = 0)
+ public Traversal original;
+
+ @Parameterized.Parameter(value = 1)
+ public Traversal optimized;
+
+
+ void applySubgraphStrategyTest(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(SubgraphStrategy.build().
+ vertices(__.and(has("name", "marko"), has("age", 29))).
+ edges(hasLabel("knows")).
+ vertexProperties(__.<VertexProperty, Long>values().count().and(is(P.lt(10)), is(0))).create());
+ strategies.addStrategies(InlineFilterStrategy.instance());
+ strategies.addStrategies(StandardVerificationStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
+ }
+
+ @Test
+ public void doTest() {
+ applySubgraphStrategyTest(original);
+ assertEquals(optimized, original);
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+
+ return Arrays.asList(new Traversal[][]{
+ {__.outE(), __.outE().hasLabel("knows").and(
+ inV().has("name", "marko").has("age", 29),
+ outV().has("name", "marko").has("age", 29))},
+ {__.V(), __.V().has("name", "marko").has("age", 29)},
+ {__.V().has("location", "santa fe"), __.V().has("name", "marko").has("age", 29).has("location", "santa fe")},
+ {__.V().where(has("location", "santa fe")), __.V().has("name", "marko").has("age", 29).has("location", "santa fe")},
+ {__.V().where(has("location", "santa fe")).values("location"), __.V().has("name", "marko").has("age", 29).has("location", "santa fe").properties("location").filter(values().count().is(P.lt(10)).is(0)).value()}
+ });
+ }
+
@Test
public void shouldAddFilterAfterVertex() {
- final SubgraphStrategy strategy = SubgraphStrategy.build().vertexCriterion(__.identity()).create();
+ final SubgraphStrategy strategy = SubgraphStrategy.build().vertices(__.identity()).create();
final Traversal t = __.inV();
strategy.apply(t.asAdmin());
final EdgeVertexStep edgeVertexStep = (EdgeVertexStep) t.asAdmin().getStartStep();
@@ -55,7 +112,7 @@ public class SubgraphStrategyTest {
@Test
public void shouldAddFilterAfterEdge() {
- final SubgraphStrategy strategy = SubgraphStrategy.build().edgeCriterion(__.identity()).create();
+ final SubgraphStrategy strategy = SubgraphStrategy.build().edges(__.identity()).create();
final Traversal t = __.inE();
strategy.apply(t.asAdmin());
final VertexStep vertexStep = (VertexStep) t.asAdmin().getStartStep();
@@ -67,7 +124,7 @@ public class SubgraphStrategyTest {
@Test
public void shouldAddBothFiltersAfterVertex() {
- final SubgraphStrategy strategy = SubgraphStrategy.build().edgeCriterion(__.identity()).vertexCriterion(__.identity()).create();
+ final SubgraphStrategy strategy = SubgraphStrategy.build().edges(__.identity()).vertices(__.identity()).create();
final Traversal t = __.inE();
strategy.apply(t.asAdmin());
final VertexStep vertexStep = (VertexStep) t.asAdmin().getStartStep();
@@ -80,8 +137,8 @@ public class SubgraphStrategyTest {
@Test
public void shouldNotRetainMetadataLabelMarkers() {
final SubgraphStrategy strategy = SubgraphStrategy.build().vertices(__.<Vertex>out().hasLabel("person")).create();
- final Traversal.Admin<?, ?> t = __.out().inE().asAdmin();
- t.setStrategies(t.getStrategies().clone().addStrategies(strategy));
+ final Traversal.Admin<?, ?> t = out().inE().asAdmin();
+ t.setStrategies(t.getStrategies().clone().addStrategies(strategy, StandardVerificationStrategy.instance()));
t.applyStrategies();
assertEquals(t.getSteps().get(0).getClass(), VertexStep.class);
assertEquals(t.getSteps().get(1).getClass(), TraversalFilterStep.class);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
new file mode 100644
index 0000000..b77ecc2
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/InlineFilterStrategyTest.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.and;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.filter;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@RunWith(Parameterized.class)
+public class InlineFilterStrategyTest {
+
+ @Parameterized.Parameter(value = 0)
+ public Traversal original;
+
+ @Parameterized.Parameter(value = 1)
+ public Traversal optimized;
+
+
+ void applyInlineFilterStrategy(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(InlineFilterStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
+ }
+
+ @Test
+ public void doTest() {
+ applyInlineFilterStrategy(original);
+ assertEquals(optimized, original);
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+
+ return Arrays.asList(new Traversal[][]{
+ {filter(out("knows")), filter(out("knows"))},
+ {filter(has("age", P.gt(10))).as("a"), has("age", P.gt(10)).as("a")},
+ {filter(has("age", P.gt(10)).as("b")).as("a"), has("age", P.gt(10)).as("b","a")},
+ {filter(has("age", P.gt(10))), has("age", P.gt(10))},
+ {filter(and(has("age", P.gt(10)), has("name", "marko"))), has("age", P.gt(10)).has("name", "marko")},
+ {and(has("age", P.gt(10)), filter(has("age", 22))), has("age", P.gt(10)).has("age", 22)},
+ {and(has("age", P.gt(10)).as("a"), and(filter(has("age", 22).as("b")).as("c"), has("name", "marko").as("d"))), has("age", P.gt(10)).as("a").has("age", 22).as("b","c").has("name", "marko").as("d")},
+ {and(has("age", P.gt(10)), and(out("knows"), has("name", "marko"))), has("age", P.gt(10)).and(out("knows"), has("name", "marko"))}
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
index 29910a7..1a854bd 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.InlineFilterStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import org.apache.tinkerpop.gremlin.structure.Column;
import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -378,12 +379,14 @@ public class SubgraphStrategyProcessTest extends AbstractGremlinProcessTest {
GraphTraversalSource sg = create(SubgraphStrategy.build().vertexProperties(has("startTime", P.gt(2005))).create());
checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().properties("location").value());
checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().values("location"));
- assertFalse(TraversalHelper.hasStepOfAssignableClassRecursively(TraversalFilterStep.class, sg.V().properties("location").value().iterate().asAdmin()));
+ if (sg.getStrategies().getStrategy(InlineFilterStrategy.class).isPresent())
+ assertFalse(TraversalHelper.hasStepOfAssignableClassRecursively(TraversalFilterStep.class, sg.V().properties("location").value().iterate().asAdmin()));
// check to make sure edge properties are not analyzed
sg = create(SubgraphStrategy.build().vertexProperties(has("startTime", P.gt(2005))).create());
checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().as("a").properties("location").as("b").select("a").outE().properties().select("b").value().dedup());
checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().as("a").values("location").as("b").select("a").outE().properties().select("b").dedup());
- assertFalse(TraversalHelper.hasStepOfAssignableClassRecursively(TraversalFilterStep.class, sg.V().as("a").values("location").as("b").select("a").outE().properties().select("b").dedup().iterate().asAdmin()));
+ if (sg.getStrategies().getStrategy(InlineFilterStrategy.class).isPresent())
+ assertFalse(TraversalHelper.hasStepOfAssignableClassRecursively(TraversalFilterStep.class, sg.V().as("a").values("location").as("b").select("a").outE().properties().select("b").dedup().iterate().asAdmin()));
//
sg = create(SubgraphStrategy.build().vertices(has("name", P.neq("stephen"))).vertexProperties(has("startTime", P.gt(2005))).create());
checkResults(Arrays.asList("baltimore", "oakland", "seattle", "aachen"), sg.V().properties("location").value());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/afcf8dff/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
index f7a9357..a014efa 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/process/groovy/jsr223/TinkerGraphGroovyTranslatorProvider.java
@@ -24,6 +24,10 @@ import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslator;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionComputerTest;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PageRankTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PeerPressureTest;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProfileTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.TranslationStrategy;
@@ -47,9 +51,13 @@ public class TinkerGraphGroovyTranslatorProvider extends TinkerGraphProvider {
"g_VX1X_out_injectXv2X_name",
"shouldNeverPropagateANoBulkTraverser",
"shouldNeverPropagateANullValuedTraverser",
+ OrderTest.Traversals.class.getCanonicalName(),
+ ProfileTest.Traversals.class.getCanonicalName(),
ProgramTest.Traversals.class.getCanonicalName(),
TraversalInterruptionTest.class.getCanonicalName(),
TraversalInterruptionComputerTest.class.getCanonicalName(),
+ PageRankTest.Traversals.class.getCanonicalName(),
+ PeerPressureTest.Traversals.class.getCanonicalName(),
ElementIdStrategyProcessTest.class.getCanonicalName()));