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 2025/06/06 19:07:29 UTC
(tinkerpop) branch GValueManager3.8-wip updated: wip-tests
This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch GValueManager3.8-wip
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/GValueManager3.8-wip by this push:
new cb5133e247 wip-tests
cb5133e247 is described below
commit cb5133e24744e69c5870b77838407545bf236c0b
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Fri Jun 6 15:07:06 2025 -0400
wip-tests
---
.../gremlin/process/traversal/GValueManager.java | 40 +++--
.../traversal/strategy/GValueManagerVerifier.java | 12 +-
.../AdjacentToIncidentStrategyTest.java | 12 +-
.../ByModulatorOptimizationStrategyTest.java | 14 +-
.../strategy/optimization/CountStrategyTest.java | 196 ++++++++++-----------
.../optimization/EarlyLimitStrategyTest.java | 2 +-
.../optimization/FilterRankingStrategyTest.java | 12 +-
.../optimization/IdentityRemovalStrategyTest.java | 15 +-
8 files changed, 141 insertions(+), 162 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java
index 4757f926e3..a9483c95af 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/GValueManager.java
@@ -170,7 +170,7 @@ public final class GValueManager implements Serializable, Cloneable {
final Set<GValue> gvalues = new HashSet<>();
for (StepContract contract : stepRegistry.values()) {
extractGValues(contract).stream().
- filter(gv -> gv.getName() != null).forEach(gvalues::add);
+ filter(GValue::isVariable).forEach(gvalues::add);
}
return Collections.unmodifiableSet(gvalues);
}
@@ -212,10 +212,18 @@ public final class GValueManager implements Serializable, Cloneable {
}
/**
- * Determines whether the GValueManager contains any registered GValues, steps, or predicates.
+ * Determines whether the manager has step registrations.
*/
- public boolean isEmpty() {
- return gValueRegistry.isEmpty() && stepRegistry.isEmpty();
+ public boolean hasStepRegistrations() {
+ return stepRegistry.isEmpty();
+ }
+
+ /**
+ * Determines whether the manager has step registrations. This call is not consistent until {@link #lock()} is
+ * called.
+ */
+ public boolean hasVariables() {
+ return variableNames().isEmpty();
}
/**
@@ -272,10 +280,6 @@ public final class GValueManager implements Serializable, Cloneable {
}
}
- private Collection<GValue<?>> extractPredicateGValues(final P predicate) {
- return predicate.getGValueRegistry().getGValues();
- }
-
private Collection<GValue<?>> extractGValues(final StepContract contract) {
if (contract instanceof RangeContract) {
return extractGValue((RangeContract<GValue<Long>>) contract);
@@ -309,7 +313,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final RangeContract<GValue<Long>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
if (contract.getHighRange().isVariable()) {
results.add(contract.getHighRange());
}
@@ -335,7 +339,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final MergeElementContract<GValue<Map<?,?>>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
if (contract.getMergeMap() != null) {
results.add(contract.getMergeMap());
}
@@ -353,7 +357,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final ElementIdsContract<GValue<?>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
for (GValue gValue: contract.getIds()) {
if (gValue.isVariable()) {
results.add(gValue);
@@ -367,7 +371,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final AddVertexContract<GValue<String>, ?, GValue<?>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
if (contract.getLabel() != null) {
results.add(contract.getLabel());
}
@@ -382,7 +386,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final AddEdgeContract<GValue<String>, GValue<Vertex>, ?, GValue<?>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
if (contract.getLabel() != null) {
results.add(contract.getLabel());
}
@@ -405,7 +409,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final AddPropertyContract<?, GValue<?>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
results.add(contract.getValue());
for (GValue<?> value : contract.getProperties().values()) {
results.add(value);
@@ -418,7 +422,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final EdgeLabelContract<GValue<String>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
for (GValue gValue: contract.getEdgeLabels()) {
if (gValue.getName() != null) {
results.add(gValue);
@@ -432,7 +436,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final CallContract<GValue<Map<?,?>>> contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
if (contract.getStaticParams().getName() != null) {
results.add(contract.getStaticParams());
}
@@ -455,7 +459,7 @@ public final class GValueManager implements Serializable, Cloneable {
* manager.
*/
private Collection<GValue<?>> extractGValue(final HasContainerHolder contract) {
- Collection<GValue<?>> results = new ArrayList();
+ final Collection<GValue<?>> results = new ArrayList();
for (P<?> predicate : contract.getPredicates()) {
if (predicate != null) {
results.addAll(predicate.getGValueRegistry().getGValues());
@@ -466,7 +470,7 @@ public final class GValueManager implements Serializable, Cloneable {
private void registerGValues(final Collection<GValue<?>> gValues) {
for (GValue<?> gValue : gValues) {
- if (gValue.getName() != null) {
+ if (gValue.isVariable()) {
gValueRegistry.put(gValue.getName(), gValue);
}
}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java
index ba5028767a..3989d3cadf 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/GValueManagerVerifier.java
@@ -24,7 +24,6 @@ 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.step.GValue;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.stepContract.EdgeLabelContract;
import org.apache.tinkerpop.gremlin.process.traversal.step.stepContract.RangeContract;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.FilterRankingStrategy;
@@ -34,7 +33,6 @@ import org.apache.tinkerpop.gremlin.util.CollectionUtil;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -43,7 +41,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
/**
* Provides utilities to verify the state and behavior of {@code GValueManager} during and after traversal strategy
@@ -204,15 +201,18 @@ public class GValueManagerVerifier {
}
/**
- * Returns this instance cast to the implementing class type
+ * Returns this instance cast to the implementing class type.
*/
protected abstract T self();
/**
- * Verifies that GValueManager is empty
+ * Verifies that GValueManager is empty, specifically meaning that there are no variables in the manager. There
+ * might yet be unnamed {@link GValue} instances but since we don't bind to those and they are usually incident
+ * to something like {@code V(1, x=2, 3)} where one variable implies that all arguments must be converted to
+ * {@link GValue} you can have scenarios where there is a mix.
*/
public T managerIsEmpty() {
- assertThat("GValueManager should be empty", manager.isEmpty(), is(true));
+ assertThat(String.format("GValueManager should be empty but contains [%s]", manager.gValues()), manager.hasVariables(), is(true));
return self();
}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java
index 85929d4ccf..02ef89b8a5 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/AdjacentToIncidentStrategyTest.java
@@ -60,13 +60,6 @@ public class AdjacentToIncidentStrategyTest {
@Parameterized.Parameter(value = 1)
public Traversal optimized;
- void applyAdjacentToIncidentStrategy(final Traversal traversal) {
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(AdjacentToIncidentStrategy.instance());
- traversal.asAdmin().setStrategies(strategies);
- traversal.asAdmin().applyStrategies();
- }
-
@Parameterized.Parameters(name = "{0}")
public static Iterable<Object[]> generateTestParameters() {
return Arrays.asList(new Traversal[][]{
@@ -94,9 +87,10 @@ public class AdjacentToIncidentStrategyTest {
@Test
public void doTest() {
final String repr = translator.translate(original.getBytecode()).getScript();
- applyAdjacentToIncidentStrategy(original);
+ GValueManagerVerifier.verify(original.asAdmin(), AdjacentToIncidentStrategy.instance())
+ .afterApplying()
+ .managerIsEmpty();
assertEquals(repr, optimized, original);
- assertThat(optimized.asAdmin().getGValueManager().isEmpty(), is(true));
}
}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java
index 53f87ff294..f97b3e7f6b 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ByModulatorOptimizationStrategyTest.java
@@ -25,6 +25,7 @@ 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.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.GValueManagerVerifier;
import org.apache.tinkerpop.gremlin.process.traversal.translator.GroovyTranslator;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.structure.T;
@@ -37,6 +38,8 @@ import java.util.List;
import static org.apache.tinkerpop.gremlin.process.traversal.Operator.assign;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
/**
@@ -177,17 +180,12 @@ public class ByModulatorOptimizationStrategyTest {
return originalAndOptimized;
}
- private void applyByModulatorOptimizationStrategy(final Traversal traversal) {
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(ByModulatorOptimizationStrategy.instance());
- traversal.asAdmin().setStrategies(strategies);
- traversal.asAdmin().applyStrategies();
- }
-
@Test
public void doTest() {
final String repr = translator.translate(original.getBytecode()).getScript();
- applyByModulatorOptimizationStrategy(original);
+ GValueManagerVerifier.verify(original.asAdmin(), ByModulatorOptimizationStrategy.instance())
+ .afterApplying()
+ .managerIsEmpty();
assertEquals(repr, optimized, original);
}
}
\ No newline at end of file
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java
index 8fc6eae9ef..cc299bd177 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/CountStrategyTest.java
@@ -73,114 +73,106 @@ public class CountStrategyTest {
@Parameterized.Parameters(name = "{0}")
public static Iterable<Object[]> generateTestParameters() {
-
- return Arrays.asList(new Traversal[][]{
- {__.count().is(0), __.limit(1).count().is(0)},
- {__.count().is(1), __.limit(2).count().is(1)},
- {__.count().is(-1), __.limit(0).count().is(-1)}, // -1 for RangeGlobalStep means no upper limit
- {__.count().is(-2), __.limit(0).count().is(-2)},
- {__.count().is(-2023), __.limit(0).count().is(-2023)},
- {__.count().is(P.between(0, 10)), __.limit(10).count().is(P.between(0, 10))},
- {__.count().is(P.between(5, 10)), __.limit(10).count().is(P.between(5, 10))},
- {__.count().is(P.gt(10).or(lt(5))), __.limit(11).count().is(P.gt(10).or(lt(5)))},
- {__.out().count().is(0), __.out().limit(1).count().is(0)},
- {__.outE().count().is(lt(1)), __.outE().limit(1).count().is(lt(1))},
- {__.both().count().is(lte(0)), __.both().limit(1).count().is(lte(0))},
- {__.map(__.out().count().is(0)), __.map(__.out().limit(1).count().is(0))},
- {__.map(__.outE().count().is(lt(1))), __.map(__.outE().limit(1).count().is(lt(1)))},
- {__.map(__.both().count().is(lte(0))), __.map(__.both().limit(1).count().is(lte(0)))},
- {__.filter(__.out().count().is(0)), __.not(__.out())},
- {__.filter(__.outE().count().is(lt(1))), __.not(__.outE())},
- {__.filter(__.both().count().is(lte(0))), __.not(__.both())},
- {__.filter(__.out().out().count().is(0)), __.not(__.out().out())},
- {__.store("x").count().is(0).as("a"), __.store("x").limit(1).count().is(0).as("a")},
- {__.out().count().as("a").is(0), __.out().limit(1).count().as("a").is(0)},
- {__.out().count().is(neq(4)), __.out().limit(5).count().is(neq(4))},
- {__.out().count().is(lte(3)), __.out().limit(4).count().is(lte(3))},
- {__.out().count().is(lt(3)), __.out().limit(3).count().is(lt(3))},
- {__.out().count().is(gt(2)), __.out().limit(3).count().is(gt(2))},
- {__.out().count().is(gte(2)), __.out().limit(2).count().is(gte(2))},
- {__.out().count().is(inside(2, 4)), __.out().limit(4).count().is(inside(2, 4))},
- {__.out().count().is(outside(2, 4)), __.out().limit(5).count().is(outside(2, 4))},
- {__.out().count().is(within(2, 6, 4)), __.out().limit(7).count().is(within(2, 6, 4))},
- {__.out().count().is(without(2, 6, 4)), __.out().limit(6).count().is(without(2, 6, 4))},
- {__.map(__.count().is(0)), __.map(__.limit(1).count().is(0))},
- {__.flatMap(__.count().is(0)), __.flatMap(__.limit(1).count().is(0))},
- {__.flatMap(__.count().is(0)).as("a"), __.flatMap(__.count().is(0)).as("a")}, // no change
- {__.filter(__.count().is(0)).as("a"), __.not(__.identity()).as("a")},
- {__.filter(__.count().is(0)), __.not(__.identity())},
- {__.sideEffect(__.count().is(0)), __.sideEffect(__.not(__.identity()))},
- {__.branch(__.count().is(0)), __.branch(__.limit(1).count().is(0))},
- {__.count().is(0).store("x"), __.limit(1).count().is(0).store("x")},
- {__.repeat(__.out()).until(__.outE().count().is(0)), __.repeat(__.out()).until(__.not(__.outE()))},
- {__.repeat(__.out()).until(__.out().out().values("name").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.values("name")))},
- {__.repeat(__.out()).until(__.out().out().properties("age").has("x").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.properties("age").has("x")))},
- {__.repeat(__.out()).emit(__.outE().count().is(0)), __.repeat(__.out()).emit(__.not(__.outE()))},
- {__.where(__.outE().hasLabel("created").count().is(0)), __.not(__.outE().hasLabel("created"))},
- {__.where(__.out().outE().hasLabel("created").count().is(0)), __.not(__.out().outE().hasLabel("created"))},
- {__.where(__.out().outE().hasLabel("created").count().is(0).store("x")), __.where(__.out().outE().hasLabel("created").limit(1).count().is(0).store("x"))},
- {__.where(__.or(__.out("none").out().count().is(0), __.has("none"))), __.where(__.or(__.not(__.out("none").out()), __.has("none"))) },
- {__.where(__.or(__.out("none").out().count().is(0), __.has("none").count().is(0))), __.where(__.or(__.not(__.out("none").out()), __.not(__.has("none")))) },
- {__.where(__.or(__.out("none").out(), __.has("none").count().is(0))), __.where(__.or(__.out("none").out(), __.not(__.has("none")))) },
- {__.filter(__.out().count().is(gt(-1))), __.filter(__.out().limit(0).count().is(gt(-1)))},
- {__.filter(__.out().count().is(gte(-1))), __.filter(__.out().limit(0).count().is(gte(-1)))},
- {__.filter(__.out().count().is(gte(0))), __.filter(__.out().limit(0).count().is(gte(0)))},
- {__.filter(__.out().count().is(lt(-1))), __.filter(__.out().limit(0).count().is(lt(-1)))},
- {__.filter(__.out().count().is(lt(0))), __.filter(__.out().limit(0).count().is(lt(0)))},
- {__.filter(__.out().count().is(lt(2))), __.filter(__.out().limit(2).count().is(lt(2)))},
- {__.filter(__.out().count().is(lte(-1))), __.filter(__.out().limit(0).count().is(lte(-1)))},
- {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
- {__.filter(__.out().count().is(eq(-1))), __.filter(__.out().limit(0).count().is(eq(-1)))},
- {__.filter(__.out().count().is(neq(-1))), __.filter(__.out().limit(0).count().is(neq(-1)))},
- {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
- {__.filter(__.out().count().is(lt(-3).and(gt(0)))), __.filter(__.out().limit(1).count().is(lt(-3).and(gt(0))))},
- {__.filter(__.out().count().is(lt(1).and(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).and(gt(-5))))},
- {__.filter(__.out().count().is(gt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).and(lt(1))))},
- {__.filter(__.out().count().is(gt(-5).and(gt(7)))), __.filter(__.out().limit(8).count().is(gt(-5).and(gt(7))))},
- {__.filter(__.out().count().is(lt(1).or(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).or(gt(-5))))},
- {__.filter(__.out().count().is(lt(1).or(gt(3)))), __.filter(__.out().limit(4).count().is(lt(1).or(gt(3))))},
- {__.filter(__.out().count().is(gt(3).or(lt(-51)))), __.filter(__.out().limit(4).count().is(gt(3).or(lt(-51))))},
- {__.filter(__.out().count().is(gt(-5).or(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).or(lt(1))))},
- {__.filter(__.out().count().is(lt(10).and(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).and(gt(1))))},
- {__.filter(__.out().count().is(gt(1).and(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).and(lt(10))))},
- {__.filter(__.out().count().is(lt(10).or(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).or(gt(1))))},
- {__.filter(__.out().count().is(gt(1).or(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).or(lt(10))))},
- {__.filter(__.out().count().is(lt(5).and(gt(10)))), __.filter(__.out().limit(11).count().is(lt(5).and(gt(10))))},
- {__.filter(__.out().count().is(gt(10).and(lt(5)))), __.filter(__.out().limit(11).count().is(gt(10).and(lt(5))))},
- {__.filter(__.out().count().is(lt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(lt(-5).and(lt(1))))},
- {__.filter(__.out().count().is(lt(-5).and(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).and(lt(-1))))},
- {__.filter(__.out().count().is(lt(-5).or(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).or(lt(-1))))},
- {__.where(__.in("knows").count().is(inside(-1,1).and(lt(-1)))), __.where(__.in("knows").limit(1).count().is(inside(-1,1).and(lt(-1))))}, // TINKERPOP-2893
- {__.where(__.inV().count().is(outside(-1,-2))), __.where(__.inV().limit(0).count().is(outside(-1,-2)))}, // TINKERPOP-2892
- {__.filter(__.bothE().count().is(gt(0))), __.filter(__.bothE())},
- {__.filter(__.bothE().count().is(gte(1))), __.filter(__.bothE())},
- {__.filter(__.bothE().count().is(gt(1))), __.filter(__.bothE().limit(2).count().is(gt(1)))},
- {__.filter(__.bothE().count().is(gte(2))), __.filter(__.bothE().limit(2).count().is(gte(2)))},
- {__.and(__.out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out()), __.not(__.in()))},
- {__.and(__.out().count().is(0), __.in().count().is(1)), __.and(__.not(__.out()), __.in().limit(2).count().is(1))},
- {__.and(__.out().count().is(1), __.in().count().is(0)), __.and(__.out().limit(2).count().is(1), __.not(__.in()))},
- {__.and(__.out().out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out().out()), __.not(__.in()))},
- {__.or(__.out().count().is(0), __.in().count().is(0)), __.or(__.not(__.out()), __.not(__.in()))},
- {__.path().filter(__.count().is(gte(0.5))).limit(5), __.path().identity().limit(5)}, // unfortunately we can't just remove the filter step
- {__.path().filter(__.unfold().count().is(gte(0.5))), __.path().filter(__.unfold())},
- {__.path().filter(__.unfold().count().is(gte(1.5))), __.path().filter(__.unfold().limit(2).count().is(gte(1.5)))},
- });
- }
-
- void applyCountStrategy(final Traversal traversal) {
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(CountStrategy.instance());
- traversal.asAdmin().setStrategies(strategies);
- traversal.asAdmin().applyStrategies();
+ return Arrays.asList(new Traversal[][]{
+ {__.count().is(0), __.limit(1).count().is(0)},
+ {__.count().is(1), __.limit(2).count().is(1)},
+ {__.count().is(-1), __.limit(0).count().is(-1)}, // -1 for RangeGlobalStep means no upper limit
+ {__.count().is(-2), __.limit(0).count().is(-2)},
+ {__.count().is(-2023), __.limit(0).count().is(-2023)},
+ {__.count().is(P.between(0, 10)), __.limit(10).count().is(P.between(0, 10))},
+ {__.count().is(P.between(5, 10)), __.limit(10).count().is(P.between(5, 10))},
+ {__.count().is(P.gt(10).or(lt(5))), __.limit(11).count().is(P.gt(10).or(lt(5)))},
+ {__.out().count().is(0), __.out().limit(1).count().is(0)},
+ {__.outE().count().is(lt(1)), __.outE().limit(1).count().is(lt(1))},
+ {__.both().count().is(lte(0)), __.both().limit(1).count().is(lte(0))},
+ {__.map(__.out().count().is(0)), __.map(__.out().limit(1).count().is(0))},
+ {__.map(__.outE().count().is(lt(1))), __.map(__.outE().limit(1).count().is(lt(1)))},
+ {__.map(__.both().count().is(lte(0))), __.map(__.both().limit(1).count().is(lte(0)))},
+ {__.filter(__.out().count().is(0)), __.not(__.out())},
+ {__.filter(__.outE().count().is(lt(1))), __.not(__.outE())},
+ {__.filter(__.both().count().is(lte(0))), __.not(__.both())},
+ {__.filter(__.out().out().count().is(0)), __.not(__.out().out())},
+ {__.store("x").count().is(0).as("a"), __.store("x").limit(1).count().is(0).as("a")},
+ {__.out().count().as("a").is(0), __.out().limit(1).count().as("a").is(0)},
+ {__.out().count().is(neq(4)), __.out().limit(5).count().is(neq(4))},
+ {__.out().count().is(lte(3)), __.out().limit(4).count().is(lte(3))},
+ {__.out().count().is(lt(3)), __.out().limit(3).count().is(lt(3))},
+ {__.out().count().is(gt(2)), __.out().limit(3).count().is(gt(2))},
+ {__.out().count().is(gte(2)), __.out().limit(2).count().is(gte(2))},
+ {__.out().count().is(inside(2, 4)), __.out().limit(4).count().is(inside(2, 4))},
+ {__.out().count().is(outside(2, 4)), __.out().limit(5).count().is(outside(2, 4))},
+ {__.out().count().is(within(2, 6, 4)), __.out().limit(7).count().is(within(2, 6, 4))},
+ {__.out().count().is(without(2, 6, 4)), __.out().limit(6).count().is(without(2, 6, 4))},
+ {__.map(__.count().is(0)), __.map(__.limit(1).count().is(0))},
+ {__.flatMap(__.count().is(0)), __.flatMap(__.limit(1).count().is(0))},
+ {__.flatMap(__.count().is(0)).as("a"), __.flatMap(__.count().is(0)).as("a")}, // no change
+ {__.filter(__.count().is(0)).as("a"), __.not(__.identity()).as("a")},
+ {__.filter(__.count().is(0)), __.not(__.identity())},
+ {__.sideEffect(__.count().is(0)), __.sideEffect(__.not(__.identity()))},
+ {__.branch(__.count().is(0)), __.branch(__.limit(1).count().is(0))},
+ {__.count().is(0).store("x"), __.limit(1).count().is(0).store("x")},
+ {__.repeat(__.out()).until(__.outE().count().is(0)), __.repeat(__.out()).until(__.not(__.outE()))},
+ {__.repeat(__.out()).until(__.out().out().values("name").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.values("name")))},
+ {__.repeat(__.out()).until(__.out().out().properties("age").has("x").count().is(0)), __.repeat(__.out()).until(__.out().out().not(__.properties("age").has("x")))},
+ {__.repeat(__.out()).emit(__.outE().count().is(0)), __.repeat(__.out()).emit(__.not(__.outE()))},
+ {__.where(__.outE().hasLabel("created").count().is(0)), __.not(__.outE().hasLabel("created"))},
+ {__.where(__.out().outE().hasLabel("created").count().is(0)), __.not(__.out().outE().hasLabel("created"))},
+ {__.where(__.out().outE().hasLabel("created").count().is(0).store("x")), __.where(__.out().outE().hasLabel("created").limit(1).count().is(0).store("x"))},
+ {__.where(__.or(__.out("none").out().count().is(0), __.has("none"))), __.where(__.or(__.not(__.out("none").out()), __.has("none"))) },
+ {__.where(__.or(__.out("none").out().count().is(0), __.has("none").count().is(0))), __.where(__.or(__.not(__.out("none").out()), __.not(__.has("none")))) },
+ {__.where(__.or(__.out("none").out(), __.has("none").count().is(0))), __.where(__.or(__.out("none").out(), __.not(__.has("none")))) },
+ {__.filter(__.out().count().is(gt(-1))), __.filter(__.out().limit(0).count().is(gt(-1)))},
+ {__.filter(__.out().count().is(gte(-1))), __.filter(__.out().limit(0).count().is(gte(-1)))},
+ {__.filter(__.out().count().is(gte(0))), __.filter(__.out().limit(0).count().is(gte(0)))},
+ {__.filter(__.out().count().is(lt(-1))), __.filter(__.out().limit(0).count().is(lt(-1)))},
+ {__.filter(__.out().count().is(lt(0))), __.filter(__.out().limit(0).count().is(lt(0)))},
+ {__.filter(__.out().count().is(lt(2))), __.filter(__.out().limit(2).count().is(lt(2)))},
+ {__.filter(__.out().count().is(lte(-1))), __.filter(__.out().limit(0).count().is(lte(-1)))},
+ {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
+ {__.filter(__.out().count().is(eq(-1))), __.filter(__.out().limit(0).count().is(eq(-1)))},
+ {__.filter(__.out().count().is(neq(-1))), __.filter(__.out().limit(0).count().is(neq(-1)))},
+ {__.filter(__.out().count().is(lte(1))), __.filter(__.out().limit(2).count().is(lte(1)))},
+ {__.filter(__.out().count().is(lt(-3).and(gt(0)))), __.filter(__.out().limit(1).count().is(lt(-3).and(gt(0))))},
+ {__.filter(__.out().count().is(lt(1).and(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).and(gt(-5))))},
+ {__.filter(__.out().count().is(gt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).and(lt(1))))},
+ {__.filter(__.out().count().is(gt(-5).and(gt(7)))), __.filter(__.out().limit(8).count().is(gt(-5).and(gt(7))))},
+ {__.filter(__.out().count().is(lt(1).or(gt(-5)))), __.filter(__.out().limit(1).count().is(lt(1).or(gt(-5))))},
+ {__.filter(__.out().count().is(lt(1).or(gt(3)))), __.filter(__.out().limit(4).count().is(lt(1).or(gt(3))))},
+ {__.filter(__.out().count().is(gt(3).or(lt(-51)))), __.filter(__.out().limit(4).count().is(gt(3).or(lt(-51))))},
+ {__.filter(__.out().count().is(gt(-5).or(lt(1)))), __.filter(__.out().limit(1).count().is(gt(-5).or(lt(1))))},
+ {__.filter(__.out().count().is(lt(10).and(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).and(gt(1))))},
+ {__.filter(__.out().count().is(gt(1).and(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).and(lt(10))))},
+ {__.filter(__.out().count().is(lt(10).or(gt(1)))), __.filter(__.out().limit(10).count().is(lt(10).or(gt(1))))},
+ {__.filter(__.out().count().is(gt(1).or(lt(10)))), __.filter(__.out().limit(10).count().is(gt(1).or(lt(10))))},
+ {__.filter(__.out().count().is(lt(5).and(gt(10)))), __.filter(__.out().limit(11).count().is(lt(5).and(gt(10))))},
+ {__.filter(__.out().count().is(gt(10).and(lt(5)))), __.filter(__.out().limit(11).count().is(gt(10).and(lt(5))))},
+ {__.filter(__.out().count().is(lt(-5).and(lt(1)))), __.filter(__.out().limit(1).count().is(lt(-5).and(lt(1))))},
+ {__.filter(__.out().count().is(lt(-5).and(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).and(lt(-1))))},
+ {__.filter(__.out().count().is(lt(-5).or(lt(-1)))), __.filter(__.out().limit(0).count().is(lt(-5).or(lt(-1))))},
+ {__.where(__.in("knows").count().is(inside(-1,1).and(lt(-1)))), __.where(__.in("knows").limit(1).count().is(inside(-1,1).and(lt(-1))))}, // TINKERPOP-2893
+ {__.where(__.inV().count().is(outside(-1,-2))), __.where(__.inV().limit(0).count().is(outside(-1,-2)))}, // TINKERPOP-2892
+ {__.filter(__.bothE().count().is(gt(0))), __.filter(__.bothE())},
+ {__.filter(__.bothE().count().is(gte(1))), __.filter(__.bothE())},
+ {__.filter(__.bothE().count().is(gt(1))), __.filter(__.bothE().limit(2).count().is(gt(1)))},
+ {__.filter(__.bothE().count().is(gte(2))), __.filter(__.bothE().limit(2).count().is(gte(2)))},
+ {__.and(__.out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out()), __.not(__.in()))},
+ {__.and(__.out().count().is(0), __.in().count().is(1)), __.and(__.not(__.out()), __.in().limit(2).count().is(1))},
+ {__.and(__.out().count().is(1), __.in().count().is(0)), __.and(__.out().limit(2).count().is(1), __.not(__.in()))},
+ {__.and(__.out().out().count().is(0), __.in().count().is(0)), __.and(__.not(__.out().out()), __.not(__.in()))},
+ {__.or(__.out().count().is(0), __.in().count().is(0)), __.or(__.not(__.out()), __.not(__.in()))},
+ {__.path().filter(__.count().is(gte(0.5))).limit(5), __.path().identity().limit(5)}, // unfortunately we can't just remove the filter step
+ {__.path().filter(__.unfold().count().is(gte(0.5))), __.path().filter(__.unfold())},
+ {__.path().filter(__.unfold().count().is(gte(1.5))), __.path().filter(__.unfold().limit(2).count().is(gte(1.5)))},
+ });
}
@Test
public void doTest() {
final String repr = translator.translate(original.getBytecode()).getScript();
- applyCountStrategy(original);
+ GValueManagerVerifier.verify(original.asAdmin(), CountStrategy.instance())
+ .afterApplying()
+ .managerIsEmpty();
assertEquals(repr, optimized, original);
-
- assertThat(optimized.asAdmin().getGValueManager().isEmpty(), is(true));
}
}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java
index 244c1bfd3f..f4415b42eb 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/EarlyLimitStrategyTest.java
@@ -124,7 +124,7 @@ public class EarlyLimitStrategyTest {
this.original.asAdmin().applyStrategies();
assertEquals(repr, this.optimized, this.original);
- assertThat(optimized.asAdmin().getGValueManager().isEmpty(), is(true));
+ assertThat(original.asAdmin().getGValueManager().hasVariables(), is(true));
}
}
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
index 47cc08d444..6329122414 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategyTest.java
@@ -57,6 +57,8 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.or;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.properties;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
/**
@@ -228,13 +230,9 @@ public class FilterRankingStrategyTest {
@Test
public void doTest() {
final String repr = translator.translate(original.getBytecode()).getScript();
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(FilterRankingStrategy.instance());
- for (final TraversalStrategy strategy : this.otherStrategies) {
- strategies.addStrategies(strategy);
- }
- this.original.asAdmin().setStrategies(strategies);
- this.original.asAdmin().applyStrategies();
+ GValueManagerVerifier.verify(original.asAdmin(), FilterRankingStrategy.instance(), otherStrategies)
+ .afterApplying()
+ .managerIsEmpty();
assertEquals(repr, this.optimized, this.original);
}
}
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 c0ead528bb..d18d97e8c8 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
@@ -20,10 +20,9 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
import org.apache.tinkerpop.gremlin.process.traversal.Translator;
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.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.GValueManagerVerifier;
import org.apache.tinkerpop.gremlin.process.traversal.translator.GroovyTranslator;
-import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -72,15 +71,9 @@ public class IdentityRemovalStrategyTest {
@Test
public void doTest() {
final String repr = translator.translate(original.getBytecode()).getScript();
- applyIdentityRemovalStrategy(original);
+ GValueManagerVerifier.verify(original.asAdmin(), IdentityRemovalStrategy.instance())
+ .afterApplying()
+ .managerIsEmpty();
assertEquals(repr, optimized, original);
}
-
- private void applyIdentityRemovalStrategy(final Traversal traversal) {
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(IdentityRemovalStrategy.instance());
- traversal.asAdmin().setStrategies(strategies);
- traversal.asAdmin().applyStrategies();
-
- }
}