You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by co...@apache.org on 2025/09/05 22:22:09 UTC
(tinkerpop) branch repeatLimit updated (ca58a971dc -> 40183f519c)
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a change to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
from ca58a971dc TINKERPOP-3166 Implement asNumber() step (#3153)
new 78b223f8cd Q's first attempt to change limit in repeat to per-iteration counters.
new cd5a485b6b Fixed RangeGlobalStep requirements.
new c6df173625 Change to nested loop requirement.
new 83ba4d1fed Modify counter key to account for nested repeats. Added temporary playground test for various traversals. Added information for logging.
new a0e79cd9f3 Draft code for logging, different test case.
new 2fd547bb40 Account for traversals with varying path lengths.
new 2c4b4e6896 Added more tests.
new 969c9abab8 Handle scenario where repeat contains out.limit.
new 7553687eda Only throw FastNoSuchElementException when not using iteration counts.
new 25ce55657d Added more tests.
new e460f9b85c Fix typo.
new 2fbda20828 Revert changes to StringFactory. Fixed bug with loop name.
new 4af663175e Fixed getLoopNames logic.
new bc0c835bd2 Added feature tests.
new 98f9c7ac28 Set loop name for computer algorithm.
new 96882afcab Troubleshooting graph computer.
new c7f5c06a25 Fixed standard algo.
new ac95eebb8b Moved tests to new file.
new 40183f519c Replaced tests with ones against modern graph.
The 19 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../process/traversal/step/branch/RepeatStep.java | 64 ++-
.../traversal/step/filter/RangeGlobalStep.java | 90 +++-
.../traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java | 7 +
.../traverser/B_LP_NL_O_S_SE_SL_Traverser.java | 1 +
.../traverser/B_NL_O_S_SE_SL_Traverser.java | 7 +
.../traverser/LP_NL_O_OB_P_S_SE_SL_Traverser.java | 1 +
.../traverser/LP_NL_O_OB_S_SE_SL_Traverser.java | 1 +
.../traverser/NL_O_OB_S_SE_SL_Traverser.java | 1 +
.../gremlin/test/features/filter/Range.feature | 121 +++++
.../structure/TinkerGraphRepeatLimitTest.java | 569 +++++++++++++++++++++
10 files changed, 838 insertions(+), 24 deletions(-)
create mode 100644 tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphRepeatLimitTest.java
(tinkerpop) 08/19: Handle scenario where repeat contains out.limit.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 969c9abab81e142a0346daa118f666cd1b66125a
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 22:14:35 2025 -0700
Handle scenario where repeat contains out.limit.
---
.../process/traversal/step/branch/RepeatStep.java | 23 +++++++++++++++++++++-
.../traversal/step/filter/RangeGlobalStep.java | 10 +++++++---
.../traverser/B_LP_NL_O_S_SE_SL_Traverser.java | 1 +
.../traverser/LP_NL_O_OB_P_S_SE_SL_Traverser.java | 1 +
.../traverser/LP_NL_O_OB_S_SE_SL_Traverser.java | 1 +
.../traverser/NL_O_OB_S_SE_SL_Traverser.java | 1 +
.../tinkergraph/structure/TinkerGraphPlayTest.java | 15 ++++++++++++++
7 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index b37d51ab3c..2aa7ca9355 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -26,6 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.ComputerAwareSte
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -235,9 +236,13 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
while (true) {
if (this.repeatTraversal.getEndStep().hasNext()) {
- return this.repeatTraversal.getEndStep();
+ Traverser.Admin<S> result = this.repeatTraversal.getEndStep().next();
+ System.out.printf("RepeatStep returning result: %s Path: %s%n",
+ ((Vertex) result.get()).property("id").value(), result.path());
+ return IteratorUtils.of(result);
} else {
final Traverser.Admin<S> start = this.starts.next();
+
String ln;
if (this.loopName != null) {
ln = this.getId();
@@ -246,11 +251,19 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
}
start.initialiseLoops(this.getId(), ln);
+ System.out.printf("RepeatStep processing start: %s Path: %s Loops: %d%n",
+ ((Vertex) start.get()).property("id").value(), start.path(), start.loops());
if (doUntil(start, true)) {
+ System.out.printf("RepeatStep until condition met, exiting: %s%n",
+ ((Vertex) start.get()).property("id").value());
start.resetLoops();
return IteratorUtils.of(start);
}
+
+ System.out.printf("RepeatStep adding to repeat traversal: %s%n",
+ ((Vertex) start.get()).property("id").value());
this.repeatTraversal.addStart(start);
+
if (doEmit(start, true)) {
final Traverser.Admin<S> emitSplit = start.split();
emitSplit.resetLoops();
@@ -342,11 +355,19 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
final RepeatStep<S> repeatStep = (RepeatStep<S>) this.getTraversal().getParent();
while (true) {
final Traverser.Admin<S> start = this.starts.next();
+ System.out.printf("RepeatEndStep processing: %s Path: %s Loops: %d%n",
+ ((Vertex) start.get()).property("id").value(), start.path(), start.loops());
start.incrLoops();
+ System.out.printf("RepeatEndStep after incrLoops: %s Loops: %d%n",
+ ((Vertex) start.get()).property("id").value(), start.loops());
if (repeatStep.doUntil(start, false)) {
+ System.out.printf("RepeatEndStep until condition met, resetting loops: %s%n",
+ ((Vertex) start.get()).property("id").value());
start.resetLoops();
return IteratorUtils.of(start);
} else {
+ System.out.printf("RepeatEndStep continuing repeat: %s%n",
+ ((Vertex) start.get()).property("id").value());
if (!repeatStep.untilFirst && !repeatStep.emitFirst)
repeatStep.repeatTraversal.addStart(start);
else
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 2b7c7431c7..07dd40e277 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -82,11 +82,15 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// TODO: account scenario where parent is not repeat step?
Step<?, ?> ps = pt.asStep();
String pid = ps.getId();
+ int loops = traverser.loops(pid);
+ System.out.printf("Parent: %s PID: %s Loops: %d TraverserLoops: %d%n", ps, pid, loops, traverser.loops());
sb.append(pid).append(":");
- sb.append(traverser.loops(pid)).append(":");
+ sb.append(loops).append(":");
t = ps.getTraversal();
}
sb.append(this.getId()).append(":").append(traverser.loops());
+// Object pathHead = traverser.path().get(0);
+// sb.append(":").append(pathHead.toString());
// Create counter key that isolates between different repeat step contexts
String iterationKey = sb.toString();
@@ -96,8 +100,8 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
}
if (this.high != -1 && currentCounter.get() >= this.high) {
- System.out.printf("FastNoSuchElementException for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
- throw FastNoSuchElementException.instance();
+ System.out.printf("Filtering out traverser (reached high limit): %s Counter: %d%n", traverser.path(), currentCounter.get());
+ return false;
}
long avail = traverser.bulk();
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_S_SE_SL_Traverser.java
index 401bfd279a..1d30928564 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_S_SE_SL_Traverser.java
@@ -62,6 +62,7 @@ public class B_LP_NL_O_S_SE_SL_Traverser<T> extends B_LP_O_S_SE_SL_Traverser<T>
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
final LabelledCounter lc = new LabelledCounter(stepLabel, (short) 0);
this.nestedLoops.push(lc);
+ this.loopNames.put(stepLabel, lc);
if (loopName != null)
this.loopNames.put(loopName, lc);
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_P_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_P_S_SE_SL_Traverser.java
index 77157b8a22..595c1b923d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_P_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_P_S_SE_SL_Traverser.java
@@ -63,6 +63,7 @@ public class LP_NL_O_OB_P_S_SE_SL_Traverser<T> extends LP_O_OB_P_S_SE_SL_Travers
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
final LabelledCounter lc = new LabelledCounter(stepLabel, (short) 0);
this.nestedLoops.push(lc);
+ this.loopNames.put(stepLabel, lc);
if (loopName != null)
this.loopNames.put(loopName, lc);
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_S_SE_SL_Traverser.java
index 14c2fe379a..3b61be4b47 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_NL_O_OB_S_SE_SL_Traverser.java
@@ -68,6 +68,7 @@ public class LP_NL_O_OB_S_SE_SL_Traverser<T> extends LP_O_OB_S_SE_SL_Traverser<T
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
final LabelledCounter lc = new LabelledCounter(stepLabel, (short) 0);
this.nestedLoops.push(lc);
+ this.loopNames.put(stepLabel, lc);
if (loopName != null)
this.loopNames.put(loopName, lc);
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/NL_O_OB_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/NL_O_OB_S_SE_SL_Traverser.java
index c30e893308..3040784706 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/NL_O_OB_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/NL_O_OB_S_SE_SL_Traverser.java
@@ -63,6 +63,7 @@ public class NL_O_OB_S_SE_SL_Traverser<T> extends O_OB_S_SE_SL_Traverser<T> {
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
final LabelledCounter lc = new LabelledCounter(stepLabel, (short) 0);
this.nestedLoops.push(lc);
+ this.loopNames.put(stepLabel, lc);
if (loopName != null)
this.loopNames.put(loopName, lc);
}
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index af6485be9e..c9317ba083 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -59,6 +59,7 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
* @author Stephen Mallette (http://stephen.genoprime.com);
@@ -95,6 +96,20 @@ public class TinkerGraphPlayTest {
.limit(2).out("knows")
.path().by("id");
assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+
+ }
+
+ @Test
+ public void testRepeatOutLimit() {
+ GraphTraversal<Vertex, Path> basic = g.V().has("id", "l2-0")
+ .repeat(__.out("knows").limit(2))
+ .times(2).path().by("id");
+ GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l2-0")
+ .out("knows").limit(2)
+ .out("knows").limit(2)
+ .path().by("id");
+ assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+
}
@Test
(tinkerpop) 18/19: Moved tests to new file.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit ac95eebb8b0f1152923cc5073f0900a788da7f1d
Author: Andrea Child <an...@improving.com>
AuthorDate: Wed Sep 3 22:47:49 2025 -0700
Moved tests to new file.
---
.../tinkergraph/structure/TinkerGraphPlayTest.java | 586 +--------------------
.../structure/TinkerGraphRepeatLimitTest.java | 569 ++++++++++++++++++++
2 files changed, 578 insertions(+), 577 deletions(-)
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index d74992dc61..c4903013d8 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -18,36 +18,35 @@
*/
package org.apache.tinkerpop.gremlin.tinkergraph.structure;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.BiFunction;
-import java.util.function.Supplier;
-import org.apache.commons.collections.CollectionUtils;
import org.apache.tinkerpop.gremlin.process.computer.Computer;
import org.apache.tinkerpop.gremlin.process.traversal.P;
-import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
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.util.WithOptions;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.ConsoleMutationListener;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathRetractionStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLIo;
import org.apache.tinkerpop.gremlin.util.TimeUtil;
-import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
import static org.apache.tinkerpop.gremlin.process.traversal.Operator.sum;
import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.Symbols.values;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.choose;
@@ -59,580 +58,14 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.sack;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.apache.tinkerpop.gremlin.structure.Column.keys;
/**
- * @author Stephen Mallette (http://stephen.genoprime.com);
+ * @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class TinkerGraphPlayTest {
private static final Logger logger = LoggerFactory.getLogger(TinkerGraphPlayTest.class);
- private static GraphTraversalSource g;
-
- @BeforeClass
- public static void setup() {
- g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
- load(g);
-// g = g.withComputer(Computer.compute().workers(1));
- }
-
- @Test
- public void testBasicRepeatLimit() {
- GraphTraversal<Vertex, Vertex> basic = g.V().has("id", "l1-0")
- .repeat(__.limit(1).out("knows"))
- .times(2);
- GraphTraversal<Vertex, Vertex> basicUnfolded = g.V().has("id", "l1-0")
- .limit(1).out("knows")
- .limit(1).out("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded)));
- }
-
- @Test
- public void testBasicRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Vertex> basic = g.V().has("id", "l1-0")
- .repeat(__.limit(2).out("knows"))
- .times(2);
- GraphTraversal<Vertex, Vertex> basicUnfolded = g.V().has("id", "l1-0")
- .limit(2).out("knows")
- .limit(2).out("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded)));
-
- }
-
- @Test
- public void testRepeatOutLimit() {
- GraphTraversal<Vertex, Path> outLimit = g.V().has("id", "l2-0")
- .repeat(__.out("knows").order().by("id").limit(2))
- .times(2)
- .path().by(T.id);
- GraphTraversal<Vertex, Path> outLimitUnfolded = g.V().has("id", "l2-0")
- .out("knows").order().by("id").limit(2)
- .out("knows").order().by("id").limit(2)
- .path().by(T.id);
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("outLimit", outLimit), toListAndPrint("outLimitUnfolded", outLimitUnfolded)));
- }
-
- @Test
- public void testRepeatWithBothAndLimit() {
- GraphTraversal<Vertex, Vertex> bothLimit = g.V().has("id", "l3-0")
- .repeat(__.both("knows").order().by("id").limit(3))
- .times(2);
- GraphTraversal<Vertex, Vertex> bothLimitUnfolded = g.V().has("id", "l3-0")
- .both("knows").order().by("id").limit(3)
- .both("knows").order().by("id").limit(3);
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("bothLimit", bothLimit), toListAndPrint("bothLimitUnfolded", bothLimitUnfolded)));
- }
-
- @Test
- public void testRepeatWithFilterAndLimit() {
- GraphTraversal<Vertex, Vertex> filterLimit = g.V().has("id", "l2-0")
- .repeat(__.out("knows").has("id", P.neq("l4-3")).order().limit(2))
- .times(2);
- GraphTraversal<Vertex, Vertex> filterLimitUnfolded = g.V().has("id", "l2-0")
- .out("knows").has("id", P.neq("l4-3")).order().limit(2)
- .out("knows").has("id", P.neq("l4-3")).order().limit(2);
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("filterLimit", filterLimit), toListAndPrint("filterLimitUnfolded", filterLimitUnfolded)));
- }
-
- @Test
- public void testChainedRepeatLimit() {
- GraphTraversal<Vertex, Vertex> chained = g.V().has("id", "l2-0")
- .repeat(__.order().by("id").limit(1).out("knows")).times(2)
- .repeat(__.order().by("id").limit(1).in("knows")).times(2);
- GraphTraversal<Vertex, Vertex> chainedUnfolded = g.V().has("id", "l2-0")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded)));
- }
-
- @Test
- public void testChainedRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Vertex> chained = g.V().has("id", "l2-0")
- .repeat(__.order().by("id").limit(2).out("knows")).times(2)
- .repeat(__.order().by("id").limit(3).in("knows")).times(2);
- GraphTraversal<Vertex, Vertex> chainedUnfolded = g.V().has("id", "l2-0")
- .order().by("id").limit(2).out("knows")
- .order().by("id").limit(2).out("knows")
- .order().by("id").limit(3).in("knows")
- .order().by("id").limit(3).in("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded)));
- }
-
- @Test
- public void testNestedRepeatLimit() {
- GraphTraversal<Vertex, Vertex> nested = g.V().has("id", "l3-0")
- .repeat(__.order().by("id").limit(1).out("knows")
- .repeat(__.order().by("id").limit(1).in("knows"))
- .times(2))
- .times(2);
- GraphTraversal<Vertex, Vertex> nestedUnfolded = g.V().has("id", "l3-0")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded)));
-
- GraphTraversal<Vertex, Vertex> nested2 = g.V().has("id", "l3-0").out("knows").order().by("id").
- repeat(__.order().by("id").limit(1).out("knows")
- .repeat(__.order().by("id").limit(1).in("knows"))
- .times(2)).
- times(2);
- GraphTraversal<Vertex, Vertex> nested2Unfolded = g.V().has("id", "l3-0").out("knows").order().by("id")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded)));
- }
-
- @Test
- public void testNestedRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Vertex> nested = g.V().has("id", "l3-0")
- .repeat(__.order().by("id").limit(2).out("knows")
- .repeat(__.order().by("id").limit(3).in("knows"))
- .times(2))
- .times(2);
- GraphTraversal<Vertex, Vertex> nestedUnfolded = g.V().has("id", "l3-0")
- .order().by("id").limit(2).out("knows")
- .order().by("id").limit(3).in("knows")
- .order().by("id").limit(3).in("knows")
- .order().by("id").limit(2).out("knows")
- .order().by("id").limit(3).in("knows")
- .order().by("id").limit(3).in("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded)));
-
- GraphTraversal<Vertex, Vertex> nested2 = g.V().has("id", "l3-0").out("knows").
- repeat(__.order().by("id").limit(1).out("knows")
- .repeat(__.order().by("id").limit(1).in("knows"))
- .times(2)).
- times(2);
- GraphTraversal<Vertex, Vertex> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).out("knows")
- .order().by("id").limit(1).in("knows")
- .order().by("id").limit(1).in("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded)));
- }
- @Test
- public void testTripleNestedRepeatLimit() {
- GraphTraversal<Vertex, Vertex> tripleNested = g.V().has("id", "l1-0")
- .repeat(__.limit(1).out("knows")
- .repeat(__.limit(1).in("knows")
- .repeat(__.limit(1).out("knows"))
- .times(2))
- .times(2))
- .times(2);
- GraphTraversal<Vertex, Vertex> tripleNestedUnfolded = g.V().has("id", "l1-0")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).out("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded)));
- }
-
- @Test
- public void testTripleNestedRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Vertex> tripleNested = g.V().has("id", "l1-0")
- .repeat(__.limit(2).out("knows")
- .repeat(__.limit(3).in("knows")
- .repeat(__.limit(4).out("knows"))
- .times(2))
- .times(2))
- .times(2);
- GraphTraversal<Vertex, Vertex> tripleNestedUnfolded = g.V().has("id", "l1-0")
- .limit(2).out("knows")
- .limit(3).in("knows")
- .limit(4).out("knows")
- .limit(4).out("knows")
- .limit(3).in("knows")
- .limit(4).out("knows")
- .limit(4).out("knows")
- .limit(2).out("knows")
- .limit(3).in("knows")
- .limit(4).out("knows")
- .limit(4).out("knows")
- .limit(3).in("knows")
- .limit(4).out("knows")
- .limit(4).out("knows");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded)));
- }
-
- @Test
- public void testAggregateRepeatLimit() {
- GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0")
- .repeat(__.limit(1).out("knows").aggregate("x"))
- .times(2)
- .cap("x");
- GraphTraversal<Vertex, Object> aggregateUnfolded = g.V().has("id", "l1-0")
- .limit(1).out("knows").aggregate("x")
- .limit(1).out("knows").aggregate("x")
- .cap("x");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded)));
- }
-
- @Test
- public void testAggregateRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0")
- .repeat(__.limit(3).out("knows").aggregate("x"))
- .times(2)
- .cap("x");
- GraphTraversal<Vertex, Object> aggregateUnfolded = g.V().has("id", "l1-0")
- .limit(3).out("knows").aggregate("x")
- .limit(3).out("knows").aggregate("x")
- .cap("x");
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded)));
- }
-
- @Test
- public void testUnionRepeatLimit() {
- GraphTraversal<Vertex, Vertex> union = g.V().has("id", "l1-0")
- .union(out().limit(1), out().out().limit(1))
- .repeat(__.limit(1)).times(1);
- GraphTraversal<Vertex, Vertex> unionUnfolded = g.V().has("id", "l1-0")
- .union(out().limit(1), out().out().limit(1))
- .limit(1);
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded)));
- }
-
- @Test
- public void testUnionRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Vertex> union = g.V().has("id", "l1-0")
- .union(out().limit(1), out().out().limit(1))
- .repeat(__.limit(3)).times(1);
- GraphTraversal<Vertex, Vertex> unionUnfolded = g.V().has("id", "l1-0")
- .union(out().limit(1), out().out().limit(1))
- .limit(3);
- assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded)));
- }
-
- private List toListAndPrint(String header, GraphTraversal t) {
- System.out.println("=====" + header + "===================================");
- System.out.println(t);
- List<?> list = t.toList();
- for (Object o : list) {
- System.out.println(o);
- }
- assertFalse(list.isEmpty());
- return list;
- }
-
- private static void load(GraphTraversalSource g) {
- g.V().drop();
-
- g.addV("node").property("id","l1-0").iterate();
-
- g.addV("node").property("id","l2-0").iterate();
- g.addV("node").property("id","l2-1").iterate();
-
- g.addV("node").property("id","l3-0").iterate();
- g.addV("node").property("id","l3-1").iterate();
- g.addV("node").property("id","l3-2").iterate();
-
- g.addV("node").property("id","l4-0").iterate();
- g.addV("node").property("id","l4-1").iterate();
- g.addV("node").property("id","l4-2").iterate();
- g.addV("node").property("id","l4-3").iterate();
-
- g.addV("node").property("id","l5-0").iterate();
- g.addV("node").property("id","l5-1").iterate();
- g.addV("node").property("id","l5-2").iterate();
- g.addV("node").property("id","l5-3").iterate();
- g.addV("node").property("id","l5-4").iterate();
-
- g.V().has("id","l1-0").as("n1").V().has("id","l2-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l1-0").as("n1").V().has("id","l2-1").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l2-0").as("n1").V().has("id","l3-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l2-0").as("n1").V().has("id","l3-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l2-0").as("n1").V().has("id","l3-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l2-1").as("n1").V().has("id","l3-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l2-1").as("n1").V().has("id","l3-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l2-1").as("n1").V().has("id","l3-2").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l3-0").as("n1").V().has("id","l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-0").as("n1").V().has("id","l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-0").as("n1").V().has("id","l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-0").as("n1").V().has("id","l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l4-0").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l1-0").as("n1").V().has("id","l2-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l1-0").as("n1").V().has("id","l2-1").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l2-0").as("n1").V().has("id","l3-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l2-0").as("n1").V().has("id","l3-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l2-0").as("n1").V().has("id","l3-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l2-1").as("n1").V().has("id","l3-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l2-1").as("n1").V().has("id","l3-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l2-1").as("n1").V().has("id","l3-2").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l3-0").as("n1").V().has("id","l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-0").as("n1").V().has("id","l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-0").as("n1").V().has("id","l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-0").as("n1").V().has("id","l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-1").as("n1").V().has("id","l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l3-2").as("n1").V().has("id","l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l4-0").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-0").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-1").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-2").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l4-3").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- // Add layer 6 nodes
- g.addV("node").property("id","l6-0").iterate();
- g.addV("node").property("id","l6-1").iterate();
- g.addV("node").property("id","l6-2").iterate();
- g.addV("node").property("id","l6-3").iterate();
- g.addV("node").property("id","l6-4").iterate();
- g.addV("node").property("id","l6-5").iterate();
-
- g.V().has("id","l5-0").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-1").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-2").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-3").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-4").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- // Connect layer 5 to layer 6 with "friend" edges (same pattern)
- g.V().has("id","l5-0").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-0").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-1").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-1").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-2").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-2").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-3").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-3").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l5-4").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l5-4").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- // Add layer 7 nodes
- g.addV("node").property("id","l7-0").iterate();
- g.addV("node").property("id","l7-1").iterate();
- g.addV("node").property("id","l7-2").iterate();
- g.addV("node").property("id","l7-3").iterate();
- g.addV("node").property("id","l7-4").iterate();
- g.addV("node").property("id","l7-5").iterate();
- g.addV("node").property("id","l7-6").iterate();
-
- // Connect layer 6 to layer 7 with "knows" edges
- g.V().has("id","l6-0").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-1").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-2").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-3").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-4").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-5").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
-
- // Connect layer 6 to layer 7 with "friend" edges
- g.V().has("id","l6-0").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-0").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-1").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-1").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-2").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-2").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-3").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-3").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-4").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-4").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
-
- g.V().has("id","l6-5").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
- g.V().has("id","l6-5").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
- }
-
@Test
@Ignore
public void testPlay8() throws Exception {
@@ -821,7 +254,6 @@ public class TinkerGraphPlayTest {
}
@Test
- @Ignore
public void testPlay6() throws Exception {
final Graph graph = TinkerGraph.open();
final GraphTraversalSource g = graph.traversal();
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphRepeatLimitTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphRepeatLimitTest.java
new file mode 100644
index 0000000000..24213f7655
--- /dev/null
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphRepeatLimitTest.java
@@ -0,0 +1,569 @@
+/*
+ * 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.tinkergraph.structure;
+
+import java.util.List;
+import java.util.function.Function;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.tinkerpop.gremlin.process.computer.Computer;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+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.strategy.optimization.RepeatUnrollStrategy;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+
+public class TinkerGraphRepeatLimitTest {
+ private static GraphTraversalSource gSource;
+ private static GraphTraversalSource gComputerSource;
+
+ @BeforeClass
+ public static void setup() {
+ gSource = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
+ load(gSource);
+ gComputerSource = gSource.withComputer(Computer.compute().workers(3));
+ }
+
+ @Test
+ public void testBasicRepeatLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .repeat(__.limit(1).out("knows"))
+ .times(2),
+ s -> s.V().has("id", "l1-0")
+ .limit(1).out("knows")
+ .limit(1).out("knows"));
+ }
+
+ @Test
+ public void testBasicRepeatLimitIncreasedLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .repeat(__.limit(2).out("knows"))
+ .times(2),
+ s -> s.V().has("id", "l1-0")
+ .limit(2).out("knows")
+ .limit(2).out("knows"));
+
+ }
+
+ @Test
+ public void testRepeatOutLimit() {
+ testTraversals(s -> s.V().has("id", "l2-0")
+ // adding order inside repeat breaks things
+ .repeat(__.out("knows").limit(2))
+ .times(2),
+ s -> s.V().has("id", "l2-0")
+ .out("knows").limit(2)
+ .out("knows").limit(2));
+ }
+
+ @Test
+ public void testRepeatWithBothAndLimit() {
+ testTraversals(s -> s.V().has("id", "l3-0")
+ .repeat(__.both("knows").order().by("id").limit(3))
+ .times(2),
+ s -> s.V().has("id", "l3-0")
+ .both("knows").order().by("id").limit(3)
+ .both("knows").order().by("id").limit(3));
+ }
+
+ @Test
+ public void testRepeatWithFilterAndLimit() {
+ testTraversals(s -> s.V().has("id", "l2-0")
+ .repeat(__.out("knows").has("id", P.neq("l4-3")).order().limit(2))
+ .times(2),
+ s -> s.V().has("id", "l2-0")
+ .out("knows").has("id", P.neq("l4-3")).order().limit(2)
+ .out("knows").has("id", P.neq("l4-3")).order().limit(2));
+ }
+
+ @Test
+ public void testChainedRepeatLimit() {
+ testTraversals(s -> s.V().has("id", "l2-0")
+ .repeat(__.order().by("id").limit(1).out("knows")).times(2)
+ .repeat(__.order().by("id").limit(1).in("knows")).times(2),
+ s -> s.V().has("id", "l2-0")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows"));
+ }
+
+ @Test
+ public void testChainedRepeatLimitIncreasedLimit() {
+ testTraversals(s -> s.V().has("id", "l2-0")
+ .repeat(__.order().by("id").limit(2).out("knows")).times(2)
+ .repeat(__.order().by("id").limit(3).in("knows")).times(2),
+ s -> s.V().has("id", "l2-0")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(3).in("knows"));
+ }
+
+ @Test
+ public void testNestedRepeatLimit() {
+ testTraversals(s -> s.V().has("id", "l3-0")
+ .repeat(__.order().by("id").limit(1).out("knows")
+ .repeat(__.order().by("id").limit(1).in("knows"))
+ .times(2))
+ .times(2), s -> s.V().has("id", "l3-0")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows"));
+ }
+
+ @Test
+ public void testNestedRepeatLimitIncreasedLimit() {
+ testTraversals(s -> s.V().has("id", "l3-0")
+ .repeat(__.order().by("id").limit(2).out("knows")
+ .repeat(__.order().by("id").limit(3).in("knows"))
+ .times(2))
+ .times(2), s -> s.V().has("id", "l3-0")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(3).in("knows"));
+ }
+
+ @Test
+ public void testTripleNestedRepeatLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .repeat(__.limit(1).out("knows")
+ .repeat(__.limit(1).in("knows")
+ .repeat(__.limit(1).out("knows"))
+ .times(2))
+ .times(2))
+ .times(2),
+ s -> s.V().has("id", "l1-0")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows"));
+ }
+
+ @Test
+ public void testTripleNestedRepeatLimitIncreasedLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .repeat(__.limit(2).out("knows")
+ .repeat(__.limit(3).in("knows")
+ .repeat(__.limit(4).out("knows"))
+ .times(2))
+ .times(2))
+ .times(2),
+ s -> s.V().has("id", "l1-0")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows"));
+ }
+
+ @Test
+ public void testAggregateRepeatLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .repeat(__.limit(1).out("knows").aggregate("x"))
+ .times(2)
+ .cap("x"),
+ s -> s.V().has("id", "l1-0")
+ .limit(1).out("knows").aggregate("x")
+ .limit(1).out("knows").aggregate("x")
+ .cap("x"));
+ }
+
+ @Test
+ public void testAggregateRepeatLimitIncreasedLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .repeat(__.limit(3).out("knows").aggregate("x"))
+ .times(2)
+ .cap("x"),
+ s -> s.V().has("id", "l1-0")
+ .limit(3).out("knows").aggregate("x")
+ .limit(3).out("knows").aggregate("x")
+ .cap("x"));
+ }
+
+ @Test
+ public void testUnionRepeatLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .repeat(__.limit(1)).times(1),
+ s -> s.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .limit(1));
+ }
+
+ @Test
+ public void testUnionRepeatLimitIncreasedLimit() {
+ testTraversals(s -> s.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .repeat(__.limit(3)).times(1),
+ s -> s.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .limit(3));
+ }
+
+ private List<?> toListAndPrint(String header, GraphTraversal<?, ?> t) {
+ System.out.println("=====" + header + "===================================");
+ System.out.println(t);
+ List<?> list = t.toList();
+ for (Object o : list) {
+ System.out.println(o);
+ }
+ return list;
+ }
+
+ private void testTraversals(Function<GraphTraversalSource, GraphTraversal<Vertex, Vertex>> repeatFunction,
+ Function<GraphTraversalSource, GraphTraversal<Vertex, Vertex>> nonRepeatFunction) {
+ List<?> repeatTraversal = toListAndPrint("repeatTraversal", repeatFunction.apply(gSource));
+ List<?> withComputerTraversal = toListAndPrint("withComputerTraversal", repeatFunction.apply(gComputerSource));
+ List<?> nonRepeatTraversal = toListAndPrint("nonRepeatTraversal", nonRepeatFunction.apply(gSource));
+ assertFalse(repeatTraversal.isEmpty());
+ assertTrue(CollectionUtils.isEqualCollection(repeatTraversal, nonRepeatTraversal));
+ // due to non-sequential processing of computer algorithm, can not assert equality but only size
+ assertEquals(repeatTraversal.size(), withComputerTraversal.size());
+ }
+
+ private static void load(GraphTraversalSource g) {
+ g.addV("node").property("id", "l1-0").iterate();
+
+ g.addV("node").property("id", "l2-0").iterate();
+ g.addV("node").property("id", "l2-1").iterate();
+
+ g.addV("node").property("id", "l3-0").iterate();
+ g.addV("node").property("id", "l3-1").iterate();
+ g.addV("node").property("id", "l3-2").iterate();
+
+ g.addV("node").property("id", "l4-0").iterate();
+ g.addV("node").property("id", "l4-1").iterate();
+ g.addV("node").property("id", "l4-2").iterate();
+ g.addV("node").property("id", "l4-3").iterate();
+
+ g.addV("node").property("id", "l5-0").iterate();
+ g.addV("node").property("id", "l5-1").iterate();
+ g.addV("node").property("id", "l5-2").iterate();
+ g.addV("node").property("id", "l5-3").iterate();
+ g.addV("node").property("id", "l5-4").iterate();
+
+ g.V().has("id", "l1-0").as("n1").V().has("id", "l2-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l1-0").as("n1").V().has("id", "l2-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l2-0").as("n1").V().has("id", "l3-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-0").as("n1").V().has("id", "l3-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-0").as("n1").V().has("id", "l3-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-1").as("n1").V().has("id", "l3-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-1").as("n1").V().has("id", "l3-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-1").as("n1").V().has("id", "l3-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l1-0").as("n1").V().has("id", "l2-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l1-0").as("n1").V().has("id", "l2-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l2-0").as("n1").V().has("id", "l3-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-0").as("n1").V().has("id", "l3-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-0").as("n1").V().has("id", "l3-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-1").as("n1").V().has("id", "l3-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-1").as("n1").V().has("id", "l3-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l2-1").as("n1").V().has("id", "l3-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-0").as("n1").V().has("id", "l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-1").as("n1").V().has("id", "l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l3-2").as("n1").V().has("id", "l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-0").as("n1").V().has("id", "l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-1").as("n1").V().has("id", "l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-2").as("n1").V().has("id", "l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l4-3").as("n1").V().has("id", "l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ // Add layer 6 nodes
+ g.addV("node").property("id", "l6-0").iterate();
+ g.addV("node").property("id", "l6-1").iterate();
+ g.addV("node").property("id", "l6-2").iterate();
+ g.addV("node").property("id", "l6-3").iterate();
+ g.addV("node").property("id", "l6-4").iterate();
+ g.addV("node").property("id", "l6-5").iterate();
+
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ // Connect layer 5 to layer 6 with "friend" edges (same pattern)
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-0").as("n1").V().has("id", "l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-1").as("n1").V().has("id", "l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-2").as("n1").V().has("id", "l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-3").as("n1").V().has("id", "l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l5-4").as("n1").V().has("id", "l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ // Add layer 7 nodes
+ g.addV("node").property("id", "l7-0").iterate();
+ g.addV("node").property("id", "l7-1").iterate();
+ g.addV("node").property("id", "l7-2").iterate();
+ g.addV("node").property("id", "l7-3").iterate();
+ g.addV("node").property("id", "l7-4").iterate();
+ g.addV("node").property("id", "l7-5").iterate();
+ g.addV("node").property("id", "l7-6").iterate();
+
+ // Connect layer 6 to layer 7 with "knows" edges
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ // Connect layer 6 to layer 7 with "friend" edges
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-0").as("n1").V().has("id", "l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-1").as("n1").V().has("id", "l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-2").as("n1").V().has("id", "l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-3").as("n1").V().has("id", "l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-4").as("n1").V().has("id", "l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id", "l6-5").as("n1").V().has("id", "l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+ }
+}
(tinkerpop) 14/19: Added feature tests.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit bc0c835bd2e55a67284d4495825662d2e9f55aab
Author: Andrea Child <an...@improving.com>
AuthorDate: Tue Sep 2 16:25:10 2025 -0700
Added feature tests.
---
.../traversal/step/filter/RangeGlobalStep.java | 2 +-
.../gremlin/test/features/filter/Range.feature | 162 +++++++++++++++++++++
2 files changed, 163 insertions(+), 1 deletion(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 2585f73543..b1c61905ea 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -89,7 +89,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// Create counter key that isolates between different repeat step contexts
String iterationKey = sb.toString();
- Object vId = ((Vertex) traverser.get()).property("id").value();
+// Object vId = ((Vertex) traverser.get()).property("id").value();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
// System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
}
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
index 0bbc215bc0..14407afab8 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
@@ -411,3 +411,165 @@ Feature: Step - range()
| result |
| l[d[2].i] |
| l[d[5].i] |
+
+ Scenario: g_V_hasXnameX_repeatXlimitX1X_outXfollowedByXX_timesX2X_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX7XXX_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(1).out("followedBy")).times(2).has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(7))).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | GLORIA |
+ | DRUMS |
+
+ Scenario: g_V_hasXnameX_limitX1X_outXfollowedByX_limitX1X_outXfollowedByX_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX7XXX_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(1).out("followedBy").limit(1).out("followedBy").has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(7))).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | GLORIA |
+ | DRUMS |
+
+ Scenario: g_V_hasXnameX_repeatXlimitX2X_outXfollowedByXX_timesX2X_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(2).out("followedBy")).times(2).has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | RAIN |
+ | DEAL |
+
+ Scenario: g_V_hasXnameX_limitX2X_outXfollowedByX_limitX2X_outXfollowedByX_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(2).out("followedBy").limit(2).out("followedBy").has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | RAIN |
+ | DEAL |
+
+ Scenario: g_V_hasXnameX_repeatXoutXfollowedByX_limitX1XX_timesX2X_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.out("followedBy").limit(1)).times(2).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | PLAYING IN THE BAND |
+
+ Scenario: g_V_hasXnameX_outXfollowedByX_limitX1X_outXfollowedByX_limitX1X_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").out("followedBy").limit(1).out("followedBy").limit(1).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | PLAYING IN THE BAND |
+
+ Scenario: g_V_hasXnameX_repeatXoutXfollowedByX_limitX2XX_timesX2X_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.out("followedBy").limit(2)).times(2).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | SUGAR MAGNOLIA |
+ | PLAYING IN THE BAND |
+
+ Scenario: g_V_hasXnameX_outXfollowedByX_limitX2X_outXfollowedByX_limitX2X_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").out("followedBy").limit(2).out("followedBy").limit(2).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | SUGAR MAGNOLIA |
+ | PLAYING IN THE BAND |
+
+ Scenario: g_V_hasXnameX_repeatXlimitX1X_outXfollowedByXX_timesX2X_repeatXlimitX1X_inXfollowedByXX_timesX1X_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(1).out("followedBy")).times(2).repeat(__.limit(1).in("followedBy")).times(1).has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | DEAL |
+
+ Scenario: g_V_hasXnameX_limitX1X_outXfollowedByX_limitX1X_outXfollowedByX_limitX1X_inXfollowedByX_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(1).out("followedBy").limit(1).out("followedBy").limit(1).in("followedBy").has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | DEAL |
+
+ Scenario: g_V_hasXnameX_repeatXlimitX1X_outXfollowedByX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_aggregateXxX_byXnameXX_timesX2X_capXxX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(1).out("followedBy").filter(__.values("name").map(__.length()).is(lt(5))).aggregate("x").by("name")).times(2).cap("x")
+ """
+ When iterated next
+ Then the result should be unordered
+ | result |
+ | DEAL |
+ | RAIN |
+
+ Scenario: g_V_hasXnameX_limitX1X_outXfollowedByX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_aggregateXxX_byXnameX_limitX1X_outXfollowedByX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_aggregateXxX_byXnameX_capXxX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(1).out("followedBy").filter(__.values("name").map(__.length()).is(lt(5))).aggregate("x").by("name").limit(1).out("followedBy").filter(__.values("name").map(__.length()).is(lt(5))).aggregate("x").by("name").cap("x")
+ """
+ When iterated next
+ Then the result should be unordered
+ | result |
+ | DEAL |
+ | RAIN |
+
+ Scenario: g_V_hasXnameX_unionXoutXfollowedByX_limitX1X_outXfollowedByX_outXfollowedByX_limitX1XX_repeatXlimitX1XX_timesX1X_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").union(__.out("followedBy").limit(1), __.out("followedBy").out("followedBy").limit(1)).repeat(__.limit(1)).times(1).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | MORNING DEW |
+
+ Scenario: g_V_hasXnameX_unionXoutXfollowedByX_limitX1X_outXfollowedByX_outXfollowedByX_limitX1XX_limitX1X_valuesXnameX
+ Given the grateful graph
+ And the traversal of
+ """
+ g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").union(__.out("followedBy").limit(1), __.out("followedBy").out("followedBy").limit(1)).limit(1).values("name")
+ """
+ When iterated to list
+ Then the result should be unordered
+ | result |
+ | MORNING DEW |
(tinkerpop) 04/19: Modify counter key to account for nested repeats. Added temporary playground test for various traversals. Added information for logging.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 83ba4d1fedbdb9762e062cd7b5a17d25de27b12e
Author: Andrea Child <an...@improving.com>
AuthorDate: Thu Aug 28 09:36:59 2025 -0700
Modify counter key to account for nested repeats. Added temporary playground test for various traversals. Added information for logging.
---
.../traversal/step/filter/RangeGlobalStep.java | 10 +-
.../gremlin/structure/util/StringFactory.java | 7 +-
.../tinkergraph/structure/TinkerGraphPlayTest.java | 380 ++++++++++++++++++++-
3 files changed, 385 insertions(+), 12 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 004d52e0d9..0ec51e0b76 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -24,9 +24,11 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.Bypassing;
import org.apache.tinkerpop.gremlin.process.traversal.step.FilteringBarrier;
import org.apache.tinkerpop.gremlin.process.traversal.step.Ranging;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_NL_O_P_S_SE_SL_Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -70,9 +72,13 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// Determine which counter to use
AtomicLong currentCounter = this.counter;
- if (usePerIterationCounters && traverser.loops() > 0) {
- String iterationKey = this.getId() + ":" + traverser.loops();
+ if (usePerIterationCounters) {
+ // Create counter key that isolates between different repeat step contexts
+ String pathStructure = String.valueOf(traverser.path().size());
+ String iterationKey = this.getId() + ":" + traverser.loops() + ":" + pathStructure;
+ Object vId = ((Vertex) ((B_LP_NL_O_P_S_SE_SL_Traverser) traverser).get()).property("id").value();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
+ System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
}
if (this.high != -1 && currentCounter.get() >= this.high) {
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
index 49206cf8e3..23ac3d831c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
@@ -268,6 +268,11 @@ public final class StringFactory {
}
public static String pathString(final Path path) {
- return PATH + L_BRACKET + String.join(", ", IteratorUtils.map(path, Objects::toString)) + R_BRACKET;
+ return PATH + L_BRACKET + String.join(", ", IteratorUtils.map(path, p -> {
+ if (p instanceof Vertex) {
+ return ((Vertex) p).property("id").value().toString();
+ }
+ return Objects.toString(p);
+ })) + R_BRACKET;
}
}
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index c4903013d8..4a455a58a1 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -18,16 +18,21 @@
*/
package org.apache.tinkerpop.gremlin.tinkergraph.structure;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
import org.apache.tinkerpop.gremlin.process.computer.Computer;
import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
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.util.WithOptions;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.ConsoleMutationListener;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.EventStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathRetractionStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -39,14 +44,8 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.BiFunction;
-import java.util.function.Supplier;
-
import static org.apache.tinkerpop.gremlin.process.traversal.Operator.sum;
import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.Symbols.values;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.choose;
@@ -58,14 +57,377 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.sack;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
-import static org.apache.tinkerpop.gremlin.structure.Column.keys;
/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Stephen Mallette (http://stephen.genoprime.com);
*/
public class TinkerGraphPlayTest {
private static final Logger logger = LoggerFactory.getLogger(TinkerGraphPlayTest.class);
+ @Test
+ @Ignore
+ public void testIterationScopedRangeGlobalInRepeat() {
+ GraphTraversalSource g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
+ load(g);
+ GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0").repeat(__.limit(1).out("knows")).times(2).path().by("id");
+ toListAndPrint("basic", basic);
+ GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0").repeat(__.limit(1).out("knows")).times(2).repeat(__.limit(1).in("knows")).times(2).path().by("id");
+ toListAndPrint("chained", chained);
+ GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0").repeat(__.limit(1).out("knows").repeat(__.limit(1).in("knows")).times(2)).times(2).path().by("id");
+ toListAndPrint("nested", nested);
+ GraphTraversal<Vertex, Path> nestedUnfolded = g.V().has("id", "l3-0")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .path().by("id");
+ toListAndPrint("nestedUnfolded", nestedUnfolded);
+
+ GraphTraversal<Vertex, Path> tripleNested = g.V().has("id", "l1-0")
+ .repeat(__.limit(1).out("knows")
+ .repeat(__.limit(1).in("knows")
+ .repeat(__.limit(1).out("knows"))
+ .times(2))
+ .times(2))
+ .times(2)
+ .path().by("id");
+ toListAndPrint("tripleNested", tripleNested);
+
+ GraphTraversal<Vertex, Path> tripleNestedUnfolded = g.V().has("id", "l1-0")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .path().by("id");
+ toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded);
+
+ GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
+ repeat(__.limit(1).out("knows").repeat(__.limit(1).in("knows")).times(2)).
+ times(2).path().by("id");
+ toListAndPrint("nested2", nested2);
+// GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0").repeat(__.limit(1).out("knows").aggregate("x")).times(2).cap("x");
+// toListAndPrint("aggregate", aggregate);
+ }
+
+ private void toListAndPrint(String header, GraphTraversal t) {
+ System.out.println("=====" + header + "===================================");
+ System.out.println(t);
+ List<?> list = t.toList();
+ for (Object o : list) {
+ System.out.println(o);
+ }
+ }
+
+ private void load(GraphTraversalSource g) {
+ g.V().drop();
+
+ g.addV("node").property("id","l1-0").iterate();
+
+ g.addV("node").property("id","l2-0").iterate();
+ g.addV("node").property("id","l2-1").iterate();
+
+ g.addV("node").property("id","l3-0").iterate();
+ g.addV("node").property("id","l3-1").iterate();
+ g.addV("node").property("id","l3-2").iterate();
+
+ g.addV("node").property("id","l4-0").iterate();
+ g.addV("node").property("id","l4-1").iterate();
+ g.addV("node").property("id","l4-2").iterate();
+ g.addV("node").property("id","l4-3").iterate();
+
+ g.addV("node").property("id","l5-0").iterate();
+ g.addV("node").property("id","l5-1").iterate();
+ g.addV("node").property("id","l5-2").iterate();
+ g.addV("node").property("id","l5-3").iterate();
+ g.addV("node").property("id","l5-4").iterate();
+
+ g.V().has("id","l1-0").as("n1").V().has("id","l2-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l1-0").as("n1").V().has("id","l2-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l2-0").as("n1").V().has("id","l3-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l2-0").as("n1").V().has("id","l3-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l2-0").as("n1").V().has("id","l3-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l2-1").as("n1").V().has("id","l3-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l2-1").as("n1").V().has("id","l3-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l2-1").as("n1").V().has("id","l3-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l1-0").as("n1").V().has("id","l2-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l1-0").as("n1").V().has("id","l2-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l2-0").as("n1").V().has("id","l3-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l2-0").as("n1").V().has("id","l3-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l2-0").as("n1").V().has("id","l3-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l2-1").as("n1").V().has("id","l3-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l2-1").as("n1").V().has("id","l3-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l2-1").as("n1").V().has("id","l3-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-0").as("n1").V().has("id","l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-1").as("n1").V().has("id","l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l3-2").as("n1").V().has("id","l4-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-0").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-1").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-2").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l4-3").as("n1").V().has("id","l5-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ // Add layer 6 nodes
+ g.addV("node").property("id","l6-0").iterate();
+ g.addV("node").property("id","l6-1").iterate();
+ g.addV("node").property("id","l6-2").iterate();
+ g.addV("node").property("id","l6-3").iterate();
+ g.addV("node").property("id","l6-4").iterate();
+ g.addV("node").property("id","l6-5").iterate();
+
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ // Connect layer 5 to layer 6 with "friend" edges (same pattern)
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-0").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-1").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-2").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-3").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l5-4").as("n1").V().has("id","l6-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ // Add layer 7 nodes
+ g.addV("node").property("id","l7-0").iterate();
+ g.addV("node").property("id","l7-1").iterate();
+ g.addV("node").property("id","l7-2").iterate();
+ g.addV("node").property("id","l7-3").iterate();
+ g.addV("node").property("id","l7-4").iterate();
+ g.addV("node").property("id","l7-5").iterate();
+ g.addV("node").property("id","l7-6").iterate();
+
+ // Connect layer 6 to layer 7 with "knows" edges
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-0").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-1").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-2").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-3").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-4").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-5").as("n2").addE("knows").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-6").as("n2").addE("knows").from("n1").to("n2").iterate();
+
+ // Connect layer 6 to layer 7 with "friend" edges
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-0").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-1").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-2").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-3").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-4").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-0").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-1").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-2").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-3").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-4").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-5").as("n2").addE("friend").from("n1").to("n2").iterate();
+ g.V().has("id","l6-5").as("n1").V().has("id","l7-6").as("n2").addE("friend").from("n1").to("n2").iterate();
+ }
+
@Test
@Ignore
public void testPlay8() throws Exception {
(tinkerpop) 16/19: Troubleshooting graph computer.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 96882afcab0afad5885e0981f25ee730f2e4ee44
Author: Andrea Child <an...@improving.com>
AuthorDate: Wed Sep 3 17:20:28 2025 -0700
Troubleshooting graph computer.
---
.../process/traversal/step/branch/RepeatStep.java | 11 +-
.../traversal/step/filter/RangeGlobalStep.java | 31 ++-
.../process/traversal/step/map/VertexStep.java | 9 +-
.../tinkergraph/structure/TinkerGraphPlayTest.java | 269 ++++++++++-----------
4 files changed, 160 insertions(+), 160 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index 0c6ef0fd0d..97533940df 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -264,19 +264,22 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
throw new IllegalStateException("The repeat()-traversal was not defined: " + this);
final Traverser.Admin<S> start = this.starts.next();
+ System.out.printf("RepeatStep.computerAlgorithm: received traverser%n");
if (doUntil(start, true)) {
+ System.out.printf("RepeatStep.computerAlgorithm: doUntil=true, exiting%n");
start.setStepId(this.getNextStep().getId());
start.addLabels(this.labels);
return IteratorUtils.of(start);
} else {
+ System.out.printf("RepeatStep.computerAlgorithm: entering repeat body%n");
start.setStepId(this.repeatTraversal.getStartStep().getId());
String ln;
if (this.loopName != null) {
ln = this.loopName;
} else {
- ln = start.getStepId();
+ ln = this.getId();
}
- start.initialiseLoops(start.getStepId(), ln);
+ start.initialiseLoops(this.getId(), ln);
if (doEmit(start, true)) {
final Traverser.Admin<S> emitSplit = start.split();
emitSplit.resetLoops();
@@ -368,8 +371,11 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
protected Iterator<Traverser.Admin<S>> computerAlgorithm() throws NoSuchElementException {
final RepeatStep<S> repeatStep = (RepeatStep<S>) this.getTraversal().getParent();
final Traverser.Admin<S> start = this.starts.next();
+ System.out.printf("RepeatEndStep.computerAlgorithm: %s loops=%d before incrLoops%n", start.path(), start.loops());
start.incrLoops();
+ System.out.printf("RepeatEndStep.computerAlgorithm: %s loops=%d after incrLoops%n", start.path(), start.loops());
if (repeatStep.doUntil(start, false)) {
+ System.out.printf("RepeatEndStep.computerAlgorithm: doUntil=true, calling resetLoops for %s%n", start.path());
start.resetLoops();
start.setStepId(repeatStep.getNextStep().getId());
start.addLabels(repeatStep.labels);
@@ -378,6 +384,7 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
start.setStepId(repeatStep.getId());
if (repeatStep.doEmit(start, false)) {
final Traverser.Admin<S> emitSplit = start.split();
+ System.out.printf("RepeatEndStep.computerAlgorithm: doEmit=true, calling resetLoops for emitSplit %s%n", emitSplit.path());
emitSplit.resetLoops();
emitSplit.setStepId(repeatStep.getNextStep().getId());
emitSplit.addLabels(repeatStep.labels);
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index b1c61905ea..50ea137f20 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -68,35 +68,40 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
@Override
protected boolean filter(final Traverser.Admin<S> traverser) {
+ System.out.printf("Filter called: %s loops=%d%n", traverser.path(), traverser.loops());
if (this.bypass) return true;
// Determine which counter to use
AtomicLong currentCounter = this.counter;
if (usePerIterationCounters) {
- StringBuilder sb = new StringBuilder();
+ // Find the parent repeat step and use its loop context
+ String repeatStepId = null;
+ int repeatLoops = 0;
+
Traversal.Admin<?,?> t = this.traversal;
while (!t.isRoot()) {
TraversalParent pt = t.getParent();
Step<?, ?> ps = pt.asStep();
- String pid = ps.getId();
- if (traverser.getLoopNames().contains(pid)) {
- sb.append(pid).append(":");
- sb.append(traverser.loops(pid)).append(":");
+ if (ps.getClass().getSimpleName().equals("RepeatStep")) {
+ repeatStepId = ps.getId();
+ if (traverser.getLoopNames().contains(repeatStepId)) {
+ repeatLoops = traverser.loops(repeatStepId);
+ }
+ break;
}
t = ps.getTraversal();
}
- sb.append(this.getId()).append(":").append(traverser.loops());
-
- // Create counter key that isolates between different repeat step contexts
- String iterationKey = sb.toString();
-// Object vId = ((Vertex) traverser.get()).property("id").value();
+
+ // Create key based on repeat step and its current iteration
+ String iterationKey = repeatStepId + ":" + repeatLoops;
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
- // System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
+ System.out.printf("IterationKey: %s RepeatLoops: %d Counter: %d Path: %s%n", iterationKey, repeatLoops, currentCounter.get(), traverser.path());
}
+ System.out.printf("Traverser: %s%n", traverser);
if (this.high != -1 && currentCounter.get() >= this.high) {
if (usePerIterationCounters) {
- // System.out.printf("Filter false for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
+ System.out.printf("Filter false for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
return false;
}
// System.out.printf("FastNoSuchElementException for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
@@ -233,7 +238,9 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
@Override
public void addBarrier(final TraverserSet<S> barrier) {
+ System.out.printf("=== addBarrier called with %d traversers ===%n", barrier.size());
IteratorUtils.removeOnNext(barrier.iterator()).forEachRemaining(traverser -> {
+ System.out.printf("Barrier traverser: %s loops=%d%n", traverser.path(), traverser.loops());
traverser.setSideEffects(this.getTraversal().getSideEffects());
this.addStart(traverser);
});
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
index f4d2743f24..f23d17e8cf 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
@@ -70,9 +70,16 @@ public class VertexStep<E extends Element> extends FlatMapStep<Vertex, E> implem
@Override
protected Iterator<E> flatMap(final Traverser.Admin<Vertex> traverser) {
- return Vertex.class.isAssignableFrom(this.returnClass) ?
+ Iterator<E> result = Vertex.class.isAssignableFrom(this.returnClass) ?
(Iterator<E>) traverser.get().vertices(this.direction, this.edgeLabels) :
(Iterator<E>) traverser.get().edges(this.direction, this.edgeLabels);
+
+ // Count results for debugging
+ List<E> resultList = new java.util.ArrayList<>();
+ result.forEachRemaining(resultList::add);
+ System.out.printf("VertexStep.flatMap: traverser=%s direction=%s labels=%s results=%s%n",
+ traverser, this.direction, Arrays.toString(this.edgeLabels), resultList);
+ return resultList.iterator();
}
@Override
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index 297aa4a240..594090b1e1 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.tinkerpop.gremlin.process.computer.Computer;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
@@ -58,8 +59,8 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.sack;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
/**
* @author Stephen Mallette (http://stephen.genoprime.com);
@@ -72,180 +73,165 @@ public class TinkerGraphPlayTest {
public static void setup() {
g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
load(g);
+ g = g.withComputer(Computer.compute().workers(1));
}
@Test
public void testBasicRepeatLimit() {
- GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0")
+ GraphTraversal<Vertex, Vertex> basic = g.V().has("id", "l1-0")
.repeat(__.limit(1).out("knows"))
- .times(2).path().by("id");
- GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l1-0")
+ .times(2);
+ GraphTraversal<Vertex, Vertex> basicUnfolded = g.V().has("id", "l1-0")
.limit(1).out("knows")
- .limit(1).out("knows")
- .path().by("id");
- assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+ .limit(1).out("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded)));
}
@Test
public void testBasicRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0")
+ GraphTraversal<Vertex, Vertex> basic = g.V().has("id", "l1-0")
.repeat(__.limit(2).out("knows"))
- .times(2).path().by("id");
- GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l1-0")
- .limit(2).out("knows")
+ .times(2);
+ GraphTraversal<Vertex, Vertex> basicUnfolded = g.V().has("id", "l1-0")
.limit(2).out("knows")
- .path().by("id");
- assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+ .limit(2).out("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded)));
}
@Test
public void testRepeatOutLimit() {
GraphTraversal<Vertex, Path> outLimit = g.V().has("id", "l2-0")
- .repeat(__.out("knows").limit(2))
- .times(2).path().by("id");
+ .repeat(__.out("knows").order().by("id").limit(2))
+ .times(2)
+ .path().by(T.id);
GraphTraversal<Vertex, Path> outLimitUnfolded = g.V().has("id", "l2-0")
- .out("knows").limit(2)
- .out("knows").limit(2)
- .path().by("id");
- assertEquals(toListAndPrint("outLimit", outLimit), toListAndPrint("outLimitUnfolded", outLimitUnfolded));
+ .out("knows").order().by("id").limit(2)
+ .out("knows").order().by("id").limit(2)
+ .path().by(T.id);
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("outLimit", outLimit), toListAndPrint("outLimitUnfolded", outLimitUnfolded)));
}
@Test
public void testRepeatWithBothAndLimit() {
- GraphTraversal<Vertex, Path> bothLimit = g.V().has("id", "l3-0")
- .repeat(__.both("knows").limit(3))
- .times(2).path().by("id");
- GraphTraversal<Vertex, Path> bothLimitUnfolded = g.V().has("id", "l3-0")
- .both("knows").limit(3)
- .both("knows").limit(3)
- .path().by("id");
- assertEquals(toListAndPrint("bothLimit", bothLimit), toListAndPrint("bothLimitUnfolded", bothLimitUnfolded));
+ GraphTraversal<Vertex, Vertex> bothLimit = g.V().has("id", "l3-0")
+ .repeat(__.both("knows").order().by("id").limit(3))
+ .times(2);
+ GraphTraversal<Vertex, Vertex> bothLimitUnfolded = g.V().has("id", "l3-0")
+ .both("knows").order().by("id").limit(3)
+ .both("knows").order().by("id").limit(3);
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("bothLimit", bothLimit), toListAndPrint("bothLimitUnfolded", bothLimitUnfolded)));
}
@Test
public void testRepeatWithFilterAndLimit() {
- GraphTraversal<Vertex, Path> filterLimit = g.V().has("id", "l2-0")
- .repeat(__.out("knows").has("id", P.neq("l4-3")).limit(2))
- .times(2).path().by("id");
- GraphTraversal<Vertex, Path> filterLimitUnfolded = g.V().has("id", "l2-0")
- .out("knows").has("id", P.neq("l4-3")).limit(2)
- .out("knows").has("id", P.neq("l4-3")).limit(2)
- .path().by("id");
- assertEquals(toListAndPrint("filterLimit", filterLimit), toListAndPrint("filterLimitUnfolded", filterLimitUnfolded));
+ GraphTraversal<Vertex, Vertex> filterLimit = g.V().has("id", "l2-0")
+ .repeat(__.out("knows").has("id", P.neq("l4-3")).order().limit(2))
+ .times(2);
+ GraphTraversal<Vertex, Vertex> filterLimitUnfolded = g.V().has("id", "l2-0")
+ .out("knows").has("id", P.neq("l4-3")).order().limit(2)
+ .out("knows").has("id", P.neq("l4-3")).order().limit(2);
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("filterLimit", filterLimit), toListAndPrint("filterLimitUnfolded", filterLimitUnfolded)));
}
@Test
public void testChainedRepeatLimit() {
- GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0")
- .repeat(__.limit(1).out("knows")).times(2)
- .repeat(__.limit(1).in("knows")).times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> chainedUnfolded = g.V().has("id", "l2-0")
- .limit(1).out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .path().by("id");
- assertEquals(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded));
+ GraphTraversal<Vertex, Vertex> chained = g.V().has("id", "l2-0")
+ .repeat(__.order().by("id").limit(1).out("knows")).times(2)
+ .repeat(__.order().by("id").limit(1).in("knows")).times(2);
+ GraphTraversal<Vertex, Vertex> chainedUnfolded = g.V().has("id", "l2-0")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded)));
}
@Test
public void testChainedRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0")
- .repeat(__.limit(2).out("knows")).times(2)
- .repeat(__.limit(3).in("knows")).times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> chainedUnfolded = g.V().has("id", "l2-0")
- .limit(2).out("knows")
- .limit(2).out("knows")
- .limit(3).in("knows")
- .limit(3).in("knows")
- .path().by("id");
- assertEquals(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded));
+ GraphTraversal<Vertex, Vertex> chained = g.V().has("id", "l2-0")
+ .repeat(__.order().by("id").limit(2).out("knows")).times(2)
+ .repeat(__.order().by("id").limit(3).in("knows")).times(2);
+ GraphTraversal<Vertex, Vertex> chainedUnfolded = g.V().has("id", "l2-0")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(3).in("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded)));
}
@Test
public void testNestedRepeatLimit() {
- GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0")
- .repeat(__.limit(1).out("knows")
- .repeat(__.limit(1).in("knows"))
+ GraphTraversal<Vertex, Vertex> nested = g.V().has("id", "l3-0")
+ .repeat(__.order().by("id").limit(1).out("knows")
+ .repeat(__.order().by("id").limit(1).in("knows"))
.times(2))
- .times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> nestedUnfolded = g.V().has("id", "l3-0")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .path().by("id");
- assertEquals(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded));
-
- GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
- repeat(__.limit(1).out("knows")
- .repeat(__.limit(1).in("knows"))
+ .times(2);
+ GraphTraversal<Vertex, Vertex> nestedUnfolded = g.V().has("id", "l3-0")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded)));
+
+ GraphTraversal<Vertex, Vertex> nested2 = g.V().has("id", "l3-0").out("knows").order().by("id").
+ repeat(__.order().by("id").limit(1).out("knows")
+ .repeat(__.order().by("id").limit(1).in("knows"))
.times(2)).
- times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .path().by("id");
- assertEquals(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded));
+ times(2);
+ GraphTraversal<Vertex, Vertex> nested2Unfolded = g.V().has("id", "l3-0").out("knows").order().by("id")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded)));
}
@Test
public void testNestedRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0")
- .repeat(__.limit(2).out("knows")
- .repeat(__.limit(3).in("knows"))
+ GraphTraversal<Vertex, Vertex> nested = g.V().has("id", "l3-0")
+ .repeat(__.order().by("id").limit(2).out("knows")
+ .repeat(__.order().by("id").limit(3).in("knows"))
.times(2))
- .times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> nestedUnfolded = g.V().has("id", "l3-0")
- .limit(2).out("knows")
- .limit(3).in("knows")
- .limit(3).in("knows")
- .limit(2).out("knows")
- .limit(3).in("knows")
- .limit(3).in("knows")
- .path().by("id");
- assertEquals(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded));
-
- GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
- repeat(__.limit(1).out("knows")
- .repeat(__.limit(1).in("knows"))
+ .times(2);
+ GraphTraversal<Vertex, Vertex> nestedUnfolded = g.V().has("id", "l3-0")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(2).out("knows")
+ .order().by("id").limit(3).in("knows")
+ .order().by("id").limit(3).in("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded)));
+
+ GraphTraversal<Vertex, Vertex> nested2 = g.V().has("id", "l3-0").out("knows").
+ repeat(__.order().by("id").limit(1).out("knows")
+ .repeat(__.order().by("id").limit(1).in("knows"))
.times(2)).
- times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .path().by("id");
- assertEquals(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded));
+ times(2);
+ GraphTraversal<Vertex, Vertex> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).out("knows")
+ .order().by("id").limit(1).in("knows")
+ .order().by("id").limit(1).in("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded)));
}
@Test
public void testTripleNestedRepeatLimit() {
- GraphTraversal<Vertex, Path> tripleNested = g.V().has("id", "l1-0")
+ GraphTraversal<Vertex, Vertex> tripleNested = g.V().has("id", "l1-0")
.repeat(__.limit(1).out("knows")
.repeat(__.limit(1).in("knows")
.repeat(__.limit(1).out("knows"))
.times(2))
.times(2))
- .times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> tripleNestedUnfolded = g.V().has("id", "l1-0")
+ .times(2);
+ GraphTraversal<Vertex, Vertex> tripleNestedUnfolded = g.V().has("id", "l1-0")
.limit(1).out("knows")
.limit(1).in("knows")
.limit(1).out("knows")
@@ -259,22 +245,20 @@ public class TinkerGraphPlayTest {
.limit(1).out("knows")
.limit(1).in("knows")
.limit(1).out("knows")
- .limit(1).out("knows")
- .path().by("id");
- assertEquals(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded));
+ .limit(1).out("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded)));
}
@Test
public void testTripleNestedRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Path> tripleNested = g.V().has("id", "l1-0")
+ GraphTraversal<Vertex, Vertex> tripleNested = g.V().has("id", "l1-0")
.repeat(__.limit(2).out("knows")
.repeat(__.limit(3).in("knows")
.repeat(__.limit(4).out("knows"))
.times(2))
.times(2))
- .times(2)
- .path().by("id");
- GraphTraversal<Vertex, Path> tripleNestedUnfolded = g.V().has("id", "l1-0")
+ .times(2);
+ GraphTraversal<Vertex, Vertex> tripleNestedUnfolded = g.V().has("id", "l1-0")
.limit(2).out("knows")
.limit(3).in("knows")
.limit(4).out("knows")
@@ -288,9 +272,8 @@ public class TinkerGraphPlayTest {
.limit(4).out("knows")
.limit(3).in("knows")
.limit(4).out("knows")
- .limit(4).out("knows")
- .path().by("id");
- assertEquals(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded));
+ .limit(4).out("knows");
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded)));
}
@Test
@@ -303,7 +286,7 @@ public class TinkerGraphPlayTest {
.limit(1).out("knows").aggregate("x")
.limit(1).out("knows").aggregate("x")
.cap("x");
- assertEquals(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded));
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded)));
}
@Test
@@ -316,33 +299,29 @@ public class TinkerGraphPlayTest {
.limit(3).out("knows").aggregate("x")
.limit(3).out("knows").aggregate("x")
.cap("x");
- assertEquals(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded));
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded)));
}
@Test
public void testUnionRepeatLimit() {
- GraphTraversal<Vertex, Path> union = g.V().has("id", "l1-0")
+ GraphTraversal<Vertex, Vertex> union = g.V().has("id", "l1-0")
.union(out().limit(1), out().out().limit(1))
- .repeat(__.limit(1)).times(1)
- .path().by("id");
- GraphTraversal<Vertex, Path> unionUnfolded = g.V().has("id", "l1-0")
+ .repeat(__.limit(1)).times(1);
+ GraphTraversal<Vertex, Vertex> unionUnfolded = g.V().has("id", "l1-0")
.union(out().limit(1), out().out().limit(1))
- .limit(1)
- .path().by("id");
- assertEquals(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded));
+ .limit(1);
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded)));
}
@Test
public void testUnionRepeatLimitIncreasedLimit() {
- GraphTraversal<Vertex, Path> union = g.V().has("id", "l1-0")
+ GraphTraversal<Vertex, Vertex> union = g.V().has("id", "l1-0")
.union(out().limit(1), out().out().limit(1))
- .repeat(__.limit(3)).times(1)
- .path().by("id");
- GraphTraversal<Vertex, Path> unionUnfolded = g.V().has("id", "l1-0")
+ .repeat(__.limit(3)).times(1);
+ GraphTraversal<Vertex, Vertex> unionUnfolded = g.V().has("id", "l1-0")
.union(out().limit(1), out().out().limit(1))
- .limit(3)
- .path().by("id");
- assertEquals(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded));
+ .limit(3);
+ assertTrue(CollectionUtils.isEqualCollection(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded)));
}
private List toListAndPrint(String header, GraphTraversal t) {
(tinkerpop) 17/19: Fixed standard algo.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit c7f5c06a25b8f1618214e911f737f800430be76c
Author: Andrea Child <an...@improving.com>
AuthorDate: Wed Sep 3 18:09:53 2025 -0700
Fixed standard algo.
---
.../process/traversal/step/branch/RepeatStep.java | 8 +++---
.../traversal/step/filter/RangeGlobalStep.java | 31 ++++++++++------------
.../process/traversal/step/map/VertexStep.java | 9 +------
.../tinkergraph/structure/TinkerGraphPlayTest.java | 2 +-
4 files changed, 20 insertions(+), 30 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index 97533940df..b76c3a6378 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -371,11 +371,11 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
protected Iterator<Traverser.Admin<S>> computerAlgorithm() throws NoSuchElementException {
final RepeatStep<S> repeatStep = (RepeatStep<S>) this.getTraversal().getParent();
final Traverser.Admin<S> start = this.starts.next();
- System.out.printf("RepeatEndStep.computerAlgorithm: %s loops=%d before incrLoops%n", start.path(), start.loops());
+// System.out.printf("RepeatEndStep.computerAlgorithm: %s loops=%d before incrLoops%n", start.path(), start.loops());
start.incrLoops();
- System.out.printf("RepeatEndStep.computerAlgorithm: %s loops=%d after incrLoops%n", start.path(), start.loops());
+// System.out.printf("RepeatEndStep.computerAlgorithm: %s loops=%d after incrLoops%n", start.path(), start.loops());
if (repeatStep.doUntil(start, false)) {
- System.out.printf("RepeatEndStep.computerAlgorithm: doUntil=true, calling resetLoops for %s%n", start.path());
+// System.out.printf("RepeatEndStep.computerAlgorithm: doUntil=true, calling resetLoops for %s%n", start.path());
start.resetLoops();
start.setStepId(repeatStep.getNextStep().getId());
start.addLabels(repeatStep.labels);
@@ -384,7 +384,7 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
start.setStepId(repeatStep.getId());
if (repeatStep.doEmit(start, false)) {
final Traverser.Admin<S> emitSplit = start.split();
- System.out.printf("RepeatEndStep.computerAlgorithm: doEmit=true, calling resetLoops for emitSplit %s%n", emitSplit.path());
+// System.out.printf("RepeatEndStep.computerAlgorithm: doEmit=true, calling resetLoops for emitSplit %s%n", emitSplit.path());
emitSplit.resetLoops();
emitSplit.setStepId(repeatStep.getNextStep().getId());
emitSplit.addLabels(repeatStep.labels);
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 50ea137f20..37f814a0d4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -68,34 +68,31 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
@Override
protected boolean filter(final Traverser.Admin<S> traverser) {
- System.out.printf("Filter called: %s loops=%d%n", traverser.path(), traverser.loops());
+// System.out.printf("Filter called: %s loops=%d%n", traverser.path(), traverser.loops());
if (this.bypass) return true;
// Determine which counter to use
AtomicLong currentCounter = this.counter;
if (usePerIterationCounters) {
- // Find the parent repeat step and use its loop context
- String repeatStepId = null;
- int repeatLoops = 0;
-
+ StringBuilder sb = new StringBuilder();
Traversal.Admin<?,?> t = this.traversal;
while (!t.isRoot()) {
TraversalParent pt = t.getParent();
Step<?, ?> ps = pt.asStep();
- if (ps.getClass().getSimpleName().equals("RepeatStep")) {
- repeatStepId = ps.getId();
- if (traverser.getLoopNames().contains(repeatStepId)) {
- repeatLoops = traverser.loops(repeatStepId);
- }
- break;
+ String pid = ps.getId();
+ if (traverser.getLoopNames().contains(pid)) {
+ sb.append(pid).append(":");
+ sb.append(traverser.loops(pid)).append(":");
}
t = ps.getTraversal();
}
-
- // Create key based on repeat step and its current iteration
- String iterationKey = repeatStepId + ":" + repeatLoops;
+ sb.append(this.getId()).append(":").append(traverser.loops());
+
+ // Create counter key that isolates between different repeat step contexts
+ String iterationKey = sb.toString();
+// Object vId = ((Vertex) traverser.get()).property("id").value();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
- System.out.printf("IterationKey: %s RepeatLoops: %d Counter: %d Path: %s%n", iterationKey, repeatLoops, currentCounter.get(), traverser.path());
+ // System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
}
System.out.printf("Traverser: %s%n", traverser);
@@ -238,9 +235,9 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
@Override
public void addBarrier(final TraverserSet<S> barrier) {
- System.out.printf("=== addBarrier called with %d traversers ===%n", barrier.size());
+// System.out.printf("=== addBarrier called with %d traversers ===%n", barrier.size());
IteratorUtils.removeOnNext(barrier.iterator()).forEachRemaining(traverser -> {
- System.out.printf("Barrier traverser: %s loops=%d%n", traverser.path(), traverser.loops());
+// System.out.printf("Barrier traverser: %s loops=%d%n", traverser.path(), traverser.loops());
traverser.setSideEffects(this.getTraversal().getSideEffects());
this.addStart(traverser);
});
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
index f23d17e8cf..f4d2743f24 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStep.java
@@ -70,16 +70,9 @@ public class VertexStep<E extends Element> extends FlatMapStep<Vertex, E> implem
@Override
protected Iterator<E> flatMap(final Traverser.Admin<Vertex> traverser) {
- Iterator<E> result = Vertex.class.isAssignableFrom(this.returnClass) ?
+ return Vertex.class.isAssignableFrom(this.returnClass) ?
(Iterator<E>) traverser.get().vertices(this.direction, this.edgeLabels) :
(Iterator<E>) traverser.get().edges(this.direction, this.edgeLabels);
-
- // Count results for debugging
- List<E> resultList = new java.util.ArrayList<>();
- result.forEachRemaining(resultList::add);
- System.out.printf("VertexStep.flatMap: traverser=%s direction=%s labels=%s results=%s%n",
- traverser, this.direction, Arrays.toString(this.edgeLabels), resultList);
- return resultList.iterator();
}
@Override
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index 594090b1e1..d74992dc61 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -73,7 +73,7 @@ public class TinkerGraphPlayTest {
public static void setup() {
g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
load(g);
- g = g.withComputer(Computer.compute().workers(1));
+// g = g.withComputer(Computer.compute().workers(1));
}
@Test
(tinkerpop) 10/19: Added more tests.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 25ce55657de2746878ce74b7aa37acc04f5ce3d7
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 23:10:26 2025 -0700
Added more tests.
---
.../process/traversal/step/branch/RepeatStep.java | 48 +++++-----------------
.../traversal/step/filter/RangeGlobalStep.java | 8 +---
.../tinkergraph/structure/TinkerGraphPlayTest.java | 32 +++++++++++++--
3 files changed, 39 insertions(+), 49 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index 644aa9f7e6..ed26d2634e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -18,25 +18,23 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.branch;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.ComputerAwareStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ComputerAwareStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -236,34 +234,21 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
while (true) {
if (this.repeatTraversal.getEndStep().hasNext()) {
- Traverser.Admin<S> result = this.repeatTraversal.getEndStep().next();
- System.out.printf("RepeatStep returning result: %s Path: %s%n",
- ((Vertex) result.get()).property("id").value(), result.path());
- return IteratorUtils.of(result);
+ return this.repeatTraversal.getEndStep();
} else {
final Traverser.Admin<S> start = this.starts.next();
-
String ln;
if (this.loopName != null) {
ln = this.getId();
} else {
ln = this.loopName;
}
-
start.initialiseLoops(this.getId(), ln);
- System.out.printf("RepeatStep processing start: %s Path: %s Loops: %d%n",
- ((Vertex) start.get()).property("id").value(), start.path(), start.loops());
if (doUntil(start, true)) {
- System.out.printf("RepeatStep until condition met, exiting: %s%n",
- ((Vertex) start.get()).property("id").value());
start.resetLoops();
return IteratorUtils.of(start);
}
-
- System.out.printf("RepeatStep adding to repeat traversal: %s%n",
- ((Vertex) start.get()).property("id").value());
this.repeatTraversal.addStart(start);
-
if (doEmit(start, true)) {
final Traverser.Admin<S> emitSplit = start.split();
emitSplit.resetLoops();
@@ -355,28 +340,15 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
final RepeatStep<S> repeatStep = (RepeatStep<S>) this.getTraversal().getParent();
while (true) {
final Traverser.Admin<S> start = this.starts.next();
- System.out.printf("RepeatEndStep processing: %s Path: %s Loops: %d%n",
- ((Vertex) start.get()).property("id").value(), start.path(), start.loops());
start.incrLoops();
- System.out.printf("RepeatEndStep after incrLoops: %s Loops: %d%n",
- ((Vertex) start.get()).property("id").value(), start.loops());
if (repeatStep.doUntil(start, false)) {
- System.out.printf("RepeatEndStep until condition met, resetting loops: %s%n",
- ((Vertex) start.get()).property("id").value());
start.resetLoops();
return IteratorUtils.of(start);
} else {
- System.out.printf("RepeatEndStep continuing repeat: %s Loops: %d%n",
- ((Vertex) start.get()).property("id").value(), start.loops());
- if (!repeatStep.untilFirst && !repeatStep.emitFirst) {
+ if (!repeatStep.untilFirst && !repeatStep.emitFirst)
repeatStep.repeatTraversal.addStart(start);
- System.out.printf("RepeatEndStep added start to repeatTraversal: %s Loops: %d%n",
- ((Vertex) start.get()).property("id").value(), start.loops());
- } else {
+ else
repeatStep.addStart(start);
- System.out.printf("RepeatEndStep adding start to repeatStep: %s Loops: %d%n",
- ((Vertex) start.get()).property("id").value(), start.loops());
- }
if (repeatStep.doEmit(start, false)) {
final Traverser.Admin<S> emitSplit = start.split();
emitSplit.resetLoops();
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index c9d5d1ed7d..b5ed20db43 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -73,8 +73,6 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// Determine which counter to use
AtomicLong currentCounter = this.counter;
if (usePerIterationCounters) {
-
-
StringBuilder sb = new StringBuilder();
Traversal.Admin t = this.traversal;
while (!t.isRoot()) {
@@ -82,15 +80,11 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// TODO: account scenario where parent is not repeat step?
Step<?, ?> ps = pt.asStep();
String pid = ps.getId();
- int loops = traverser.loops(pid);
- System.out.printf("Parent: %s PID: %s Loops: %d TraverserLoops: %d%n", ps, pid, loops, traverser.loops());
sb.append(pid).append(":");
- sb.append(loops).append(":");
+ sb.append(traverser.loops(pid)).append(":");
t = ps.getTraversal();
}
sb.append(this.getId()).append(":").append(traverser.loops());
-// Object pathHead = traverser.path().get(0);
-// sb.append(":").append(pathHead.toString());
// Create counter key that isolates between different repeat step contexts
String iterationKey = sb.toString();
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index c9317ba083..5b8b37a5c1 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -59,7 +59,7 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
/**
* @author Stephen Mallette (http://stephen.genoprime.com);
@@ -101,15 +101,38 @@ public class TinkerGraphPlayTest {
@Test
public void testRepeatOutLimit() {
- GraphTraversal<Vertex, Path> basic = g.V().has("id", "l2-0")
+ GraphTraversal<Vertex, Path> outLimit = g.V().has("id", "l2-0")
.repeat(__.out("knows").limit(2))
.times(2).path().by("id");
- GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l2-0")
+ GraphTraversal<Vertex, Path> outLimitUnfolded = g.V().has("id", "l2-0")
.out("knows").limit(2)
.out("knows").limit(2)
.path().by("id");
- assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+ assertEquals(toListAndPrint("outLimit", outLimit), toListAndPrint("outLimitUnfolded", outLimitUnfolded));
+ }
+
+ @Test
+ public void testRepeatWithBothAndLimit() {
+ GraphTraversal<Vertex, Path> bothLimit = g.V().has("id", "l3-0")
+ .repeat(__.both("knows").limit(3))
+ .times(2).path().by("id");
+ GraphTraversal<Vertex, Path> bothLimitUnfolded = g.V().has("id", "l3-0")
+ .both("knows").limit(3)
+ .both("knows").limit(3)
+ .path().by("id");
+ assertEquals(toListAndPrint("bothLimit", bothLimit), toListAndPrint("bothLimitUnfolded", bothLimitUnfolded));
+ }
+ @Test
+ public void testRepeatWithFilterAndLimit() {
+ GraphTraversal<Vertex, Path> filterLimit = g.V().has("id", "l2-0")
+ .repeat(__.out("knows").has("id", P.neq("l4-3")).limit(2))
+ .times(2).path().by("id");
+ GraphTraversal<Vertex, Path> filterLimitUnfolded = g.V().has("id", "l2-0")
+ .out("knows").has("id", P.neq("l4-3")).limit(2)
+ .out("knows").has("id", P.neq("l4-3")).limit(2)
+ .path().by("id");
+ assertEquals(toListAndPrint("filterLimit", filterLimit), toListAndPrint("basicUnfolded", filterLimitUnfolded));
}
@Test
@@ -329,6 +352,7 @@ public class TinkerGraphPlayTest {
for (Object o : list) {
System.out.println(o);
}
+ assertFalse(list.isEmpty());
return list;
}
(tinkerpop) 15/19: Set loop name for computer algorithm.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 98f9c7ac28c42ae5d2b6723c85d2350a2a97596b
Author: Andrea Child <an...@improving.com>
AuthorDate: Tue Sep 2 17:15:20 2025 -0700
Set loop name for computer algorithm.
---
.../gremlin/process/traversal/step/branch/RepeatStep.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index b1af408f79..0c6ef0fd0d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -270,7 +270,13 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
return IteratorUtils.of(start);
} else {
start.setStepId(this.repeatTraversal.getStartStep().getId());
- start.initialiseLoops(start.getStepId(), this.loopName);
+ String ln;
+ if (this.loopName != null) {
+ ln = this.loopName;
+ } else {
+ ln = start.getStepId();
+ }
+ start.initialiseLoops(start.getStepId(), ln);
if (doEmit(start, true)) {
final Traverser.Admin<S> emitSplit = start.split();
emitSplit.resetLoops();
(tinkerpop) 11/19: Fix typo.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit e460f9b85ccc748c75e24ebfc7339772a0a9e5b5
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 23:17:10 2025 -0700
Fix typo.
---
.../tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index 5b8b37a5c1..297aa4a240 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -132,7 +132,7 @@ public class TinkerGraphPlayTest {
.out("knows").has("id", P.neq("l4-3")).limit(2)
.out("knows").has("id", P.neq("l4-3")).limit(2)
.path().by("id");
- assertEquals(toListAndPrint("filterLimit", filterLimit), toListAndPrint("basicUnfolded", filterLimitUnfolded));
+ assertEquals(toListAndPrint("filterLimit", filterLimit), toListAndPrint("filterLimitUnfolded", filterLimitUnfolded));
}
@Test
(tinkerpop) 06/19: Account for traversals with varying path lengths.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 2fd547bb40ba92c675a9c3a6b93b452283694b3c
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 16:15:56 2025 -0700
Account for traversals with varying path lengths.
---
.../process/traversal/step/branch/RepeatStep.java | 9 +-
.../traversal/step/filter/RangeGlobalStep.java | 22 ++++-
.../traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java | 1 +
.../traverser/B_NL_O_S_SE_SL_Traverser.java | 1 +
.../tinkergraph/structure/TinkerGraphPlayTest.java | 106 +++++++++++++--------
5 files changed, 96 insertions(+), 43 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index 3f27e71e54..b37d51ab3c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -238,7 +238,14 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
return this.repeatTraversal.getEndStep();
} else {
final Traverser.Admin<S> start = this.starts.next();
- start.initialiseLoops(this.getId(), this.loopName);
+ String ln;
+ if (this.loopName != null) {
+ ln = this.getId();
+ } else {
+ ln = this.loopName;
+ }
+
+ start.initialiseLoops(this.getId(), ln);
if (doUntil(start, true)) {
start.resetLoops();
return IteratorUtils.of(start);
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index c0c0c86e35..e02c572c3c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -28,11 +28,13 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BinaryOperator;
import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.Bypassing;
import org.apache.tinkerpop.gremlin.process.traversal.step.FilteringBarrier;
import org.apache.tinkerpop.gremlin.process.traversal.step.Ranging;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
@@ -71,16 +73,29 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// Determine which counter to use
AtomicLong currentCounter = this.counter;
if (usePerIterationCounters) {
+
+
+ StringBuilder sb = new StringBuilder();
+ Traversal.Admin t = this.traversal;
+ while (!t.isRoot()) {
+ TraversalParent pt = t.getParent();
+ Step<?, ?> ps = pt.asStep();
+ String pid = ps.getId();
+ sb.append(pid).append(":");
+ sb.append(traverser.loops(pid)).append(":");
+ t = ps.getTraversal();
+ }
+ sb.append(this.getId()).append(":").append(traverser.loops());
+
// Create counter key that isolates between different repeat step contexts
- String pathStructure = String.valueOf(traverser.path().size());
- // consider removing the stepId from the key
- String iterationKey = this.getId() + ":" + traverser.loops() + ":" + pathStructure;
+ String iterationKey = sb.toString();
Object vId = ((Vertex) traverser.get()).property("id").value();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
}
if (this.high != -1 && currentCounter.get() >= this.high) {
+ System.out.printf("FastNoSuchElementException for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
throw FastNoSuchElementException.instance();
}
@@ -88,6 +103,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
if (currentCounter.get() + avail <= this.low) {
// Will not surpass the low w/ this traverser. Skip and filter the whole thing.
currentCounter.getAndAdd(avail);
+ System.out.printf("False for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
return false;
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java
index 1af9dbefef..70e827630d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java
@@ -62,6 +62,7 @@ public class B_LP_NL_O_P_S_SE_SL_Traverser<T> extends B_LP_O_P_S_SE_SL_Traverser
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
final LabelledCounter lc = new LabelledCounter(stepLabel, (short) 0);
this.nestedLoops.push(lc);
+ this.loopNames.put(stepLabel, lc);
if (loopName != null)
this.loopNames.put(loopName, lc);
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java
index 6e18d12a61..cb05a7559e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java
@@ -61,6 +61,7 @@ public class B_NL_O_S_SE_SL_Traverser<T> extends B_O_S_SE_SL_Traverser<T> {
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
final LabelledCounter lc = new LabelledCounter(stepLabel, (short) 0);
this.nestedLoops.push(lc);
+ this.loopNames.put(stepLabel, lc);
if (loopName != null)
this.loopNames.put(loopName, lc);
}
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index 82d72c69a5..e6ccff6d8d 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -39,6 +39,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLIo;
import org.apache.tinkerpop.gremlin.util.TimeUtil;
+import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
@@ -57,48 +58,56 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.sack;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
+import static org.junit.Assert.assertEquals;
/**
* @author Stephen Mallette (http://stephen.genoprime.com);
*/
public class TinkerGraphPlayTest {
private static final Logger logger = LoggerFactory.getLogger(TinkerGraphPlayTest.class);
-
- @Test
- @Ignore
- public void testIterationScopedRangeGlobalInRepeat() {
- GraphTraversalSource g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
+ private static GraphTraversalSource g;
+
+ @BeforeClass
+ public static void setup() {
+ g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
load(g);
+ }
+
+ @Test
+ public void testBasicRepeatLimit() {
GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0")
.repeat(__.limit(1).out("knows"))
.times(2).path().by("id");
- toListAndPrint("basic", basic);
GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l1-0")
.limit(1).out("knows")
.limit(1).out("knows")
.path().by("id");
- toListAndPrint("basicUnfolded", basicUnfolded);
+ assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+ }
+ @Test
+ public void testChainedRepeatLimit() {
GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0")
.repeat(__.limit(1).out("knows")).times(2)
.repeat(__.limit(1).in("knows")).times(2)
.path().by("id");
- toListAndPrint("chained", chained);
GraphTraversal<Vertex, Path> chainedUnfolded = g.V().has("id", "l2-0")
.limit(1).out("knows")
.limit(1).out("knows")
.limit(1).in("knows")
.limit(1).in("knows")
.path().by("id");
- toListAndPrint("chainedUnfolded", chainedUnfolded);
+ assertEquals(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded));
+ }
+ @Test
+ public void testNestedRepeatLimit() {
GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0")
.repeat(__.limit(1).out("knows")
.repeat(__.limit(1).in("knows"))
.times(2))
.times(2)
.path().by("id");
- toListAndPrint("nested", nested);
GraphTraversal<Vertex, Path> nestedUnfolded = g.V().has("id", "l3-0")
.limit(1).out("knows")
.limit(1).in("knows")
@@ -107,8 +116,27 @@ public class TinkerGraphPlayTest {
.limit(1).in("knows")
.limit(1).in("knows")
.path().by("id");
- toListAndPrint("nestedUnfolded", nestedUnfolded);
+ assertEquals(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded));
+ GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
+ repeat(__.limit(1).out("knows")
+ .repeat(__.limit(1).in("knows"))
+ .times(2)).
+ times(2)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .path().by("id");
+ assertEquals(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded));
+ }
+
+ @Test
+ public void testTripleNestedRepeatLimit() {
GraphTraversal<Vertex, Path> tripleNested = g.V().has("id", "l1-0")
.repeat(__.limit(1).out("knows")
.repeat(__.limit(1).in("knows")
@@ -117,7 +145,6 @@ public class TinkerGraphPlayTest {
.times(2))
.times(2)
.path().by("id");
- toListAndPrint("tripleNested", tripleNested);
GraphTraversal<Vertex, Path> tripleNestedUnfolded = g.V().has("id", "l1-0")
.limit(1).out("knows")
.limit(1).in("knows")
@@ -134,46 +161,46 @@ public class TinkerGraphPlayTest {
.limit(1).out("knows")
.limit(1).out("knows")
.path().by("id");
- toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded);
+ assertEquals(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded));
+ }
- GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
- repeat(__.limit(1).out("knows")
- .repeat(__.limit(1).in("knows"))
- .times(2)).
- times(2)
- .path().by("id");
- toListAndPrint("nested2", nested2);
- GraphTraversal<Vertex, Path> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .limit(1).out("knows")
- .limit(1).in("knows")
- .limit(1).in("knows")
- .path().by("id");
- toListAndPrint("nested2Unfolded", nested2Unfolded);
- GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0").repeat(__.limit(1).out("knows").aggregate("x")).times(2).cap("x");
- toListAndPrint("aggregate", aggregate);
+ @Test
+ public void testAggregateRepeatLimit() {
+ GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0")
+ .repeat(__.limit(1).out("knows").aggregate("x"))
+ .times(2)
+ .cap("x");
+ GraphTraversal<Vertex, Object> aggregateUnfolded = g.V().has("id", "l1-0")
+ .limit(1).out("knows").aggregate("x")
+ .limit(1).out("knows").aggregate("x")
+ .cap("x");
+ assertEquals(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded));
+ }
- GraphTraversal<Vertex, Path> test = g.V().has("id", "l1-0")
+ @Test
+ public void testUnionRepeatLimit() {
+ GraphTraversal<Vertex, Path> union = g.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .repeat(__.limit(1)).times(1)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> unionUnfolded = g.V().has("id", "l1-0")
.union(out().limit(1), out().out().limit(1))
- .repeat(__.limit(1))
- .times(1).path().by("id");
- toListAndPrint("test", test);
- GraphTraversal<Vertex, Path> test2 = g.V().has("id", "l1-0").union(out().limit(1), out().out().limit(1)).limit(1).path().by("id");
- toListAndPrint("test2", test2);
+ .limit(1)
+ .path().by("id");
+ assertEquals(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded));
}
- private void toListAndPrint(String header, GraphTraversal t) {
+ private List toListAndPrint(String header, GraphTraversal t) {
System.out.println("=====" + header + "===================================");
System.out.println(t);
List<?> list = t.toList();
for (Object o : list) {
System.out.println(o);
}
+ return list;
}
- private void load(GraphTraversalSource g) {
+ private static void load(GraphTraversalSource g) {
g.V().drop();
g.addV("node").property("id","l1-0").iterate();
@@ -659,6 +686,7 @@ public class TinkerGraphPlayTest {
}
@Test
+ @Ignore
public void testPlay6() throws Exception {
final Graph graph = TinkerGraph.open();
final GraphTraversalSource g = graph.traversal();
(tinkerpop) 02/19: Fixed RangeGlobalStep requirements.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit cd5a485b6b1631e1d51b585ae655a154c9a4778a
Author: Andrea Child <an...@improving.com>
AuthorDate: Mon Aug 25 19:23:33 2025 -0700
Fixed RangeGlobalStep requirements.
---
.../gremlin/process/traversal/step/filter/RangeGlobalStep.java | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 5d6dbbab7c..ef8bcaf5a8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -33,6 +33,7 @@ import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
@@ -70,7 +71,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
// Determine which counter to use
AtomicLong currentCounter = this.counter;
if (usePerIterationCounters && traverser.loops() > 0) {
- String iterationKey = traverser.getStepId() + ":" + traverser.loops();
+ String iterationKey = this.getId() + ":" + traverser.loops();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
}
@@ -159,6 +160,12 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
@Override
public Set<TraverserRequirement> getRequirements() {
+ if (usePerIterationCounters) {
+ final Set<TraverserRequirement> requirements = new HashSet<>();
+ requirements.add(TraverserRequirement.BULK);
+ requirements.add(TraverserRequirement.SINGLE_LOOP);
+ return requirements;
+ }
return Collections.singleton(TraverserRequirement.BULK);
}
(tinkerpop) 12/19: Revert changes to StringFactory. Fixed bug with loop name.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 2fbda208288ef6f44ea049750de0098975332887
Author: Andrea Child <an...@improving.com>
AuthorDate: Tue Sep 2 11:42:25 2025 -0700
Revert changes to StringFactory. Fixed bug with loop name.
---
.../gremlin/process/traversal/step/branch/RepeatStep.java | 4 ++--
.../gremlin/process/traversal/step/filter/RangeGlobalStep.java | 8 ++++----
.../apache/tinkerpop/gremlin/structure/util/StringFactory.java | 7 +------
3 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index ed26d2634e..b1af408f79 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -239,9 +239,9 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
final Traverser.Admin<S> start = this.starts.next();
String ln;
if (this.loopName != null) {
- ln = this.getId();
- } else {
ln = this.loopName;
+ } else {
+ ln = this.getId();
}
start.initialiseLoops(this.getId(), ln);
if (doUntil(start, true)) {
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index b5ed20db43..2be2a7da1a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -90,15 +90,15 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
String iterationKey = sb.toString();
Object vId = ((Vertex) traverser.get()).property("id").value();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
- System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
+ // System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
}
if (this.high != -1 && currentCounter.get() >= this.high) {
if (usePerIterationCounters) {
- System.out.printf("Filter false for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
+ // System.out.printf("Filter false for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
return false;
}
- System.out.printf("FastNoSuchElementException for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
+ // System.out.printf("FastNoSuchElementException for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
throw FastNoSuchElementException.instance();
}
@@ -106,7 +106,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
if (currentCounter.get() + avail <= this.low) {
// Will not surpass the low w/ this traverser. Skip and filter the whole thing.
currentCounter.getAndAdd(avail);
- System.out.printf("False for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
+ // System.out.printf("False for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
return false;
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
index 23ac3d831c..49206cf8e3 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
@@ -268,11 +268,6 @@ public final class StringFactory {
}
public static String pathString(final Path path) {
- return PATH + L_BRACKET + String.join(", ", IteratorUtils.map(path, p -> {
- if (p instanceof Vertex) {
- return ((Vertex) p).property("id").value().toString();
- }
- return Objects.toString(p);
- })) + R_BRACKET;
+ return PATH + L_BRACKET + String.join(", ", IteratorUtils.map(path, Objects::toString)) + R_BRACKET;
}
}
(tinkerpop) 09/19: Only throw FastNoSuchElementException when not using iteration counts.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 7553687edadc59ff4db0a7ce6c296b4c6ad568fd
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 22:52:01 2025 -0700
Only throw FastNoSuchElementException when not using iteration counts.
---
.../gremlin/process/traversal/step/branch/RepeatStep.java | 13 +++++++++----
.../process/traversal/step/filter/RangeGlobalStep.java | 8 ++++++--
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index 2aa7ca9355..644aa9f7e6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -366,12 +366,17 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
start.resetLoops();
return IteratorUtils.of(start);
} else {
- System.out.printf("RepeatEndStep continuing repeat: %s%n",
- ((Vertex) start.get()).property("id").value());
- if (!repeatStep.untilFirst && !repeatStep.emitFirst)
+ System.out.printf("RepeatEndStep continuing repeat: %s Loops: %d%n",
+ ((Vertex) start.get()).property("id").value(), start.loops());
+ if (!repeatStep.untilFirst && !repeatStep.emitFirst) {
repeatStep.repeatTraversal.addStart(start);
- else
+ System.out.printf("RepeatEndStep added start to repeatTraversal: %s Loops: %d%n",
+ ((Vertex) start.get()).property("id").value(), start.loops());
+ } else {
repeatStep.addStart(start);
+ System.out.printf("RepeatEndStep adding start to repeatStep: %s Loops: %d%n",
+ ((Vertex) start.get()).property("id").value(), start.loops());
+ }
if (repeatStep.doEmit(start, false)) {
final Traverser.Admin<S> emitSplit = start.split();
emitSplit.resetLoops();
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 07dd40e277..c9d5d1ed7d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -100,8 +100,12 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
}
if (this.high != -1 && currentCounter.get() >= this.high) {
- System.out.printf("Filtering out traverser (reached high limit): %s Counter: %d%n", traverser.path(), currentCounter.get());
- return false;
+ if (usePerIterationCounters) {
+ System.out.printf("Filter false for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
+ return false;
+ }
+ System.out.printf("FastNoSuchElementException for Traverser: %s Counter: %d%n", traverser.path(), currentCounter.get());
+ throw FastNoSuchElementException.instance();
}
long avail = traverser.bulk();
(tinkerpop) 05/19: Draft code for logging, different test case.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit a0e79cd9f3a6186b9e29435442b966d16ab822bd
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 09:39:51 2025 -0700
Draft code for logging, different test case.
---
.../traversal/step/filter/RangeGlobalStep.java | 23 ++++-----
.../tinkergraph/structure/TinkerGraphPlayTest.java | 59 +++++++++++++++++++---
2 files changed, 62 insertions(+), 20 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 0ec51e0b76..c0c0c86e35 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -18,13 +18,21 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BinaryOperator;
import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.Bypassing;
import org.apache.tinkerpop.gremlin.process.traversal.step.FilteringBarrier;
import org.apache.tinkerpop.gremlin.process.traversal.step.Ranging;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_NL_O_P_S_SE_SL_Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
@@ -32,16 +40,6 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.BinaryOperator;
-
/**
* @author Bob Briody (http://bobbriody.com)
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -75,8 +73,9 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
if (usePerIterationCounters) {
// Create counter key that isolates between different repeat step contexts
String pathStructure = String.valueOf(traverser.path().size());
+ // consider removing the stepId from the key
String iterationKey = this.getId() + ":" + traverser.loops() + ":" + pathStructure;
- Object vId = ((Vertex) ((B_LP_NL_O_P_S_SE_SL_Traverser) traverser).get()).property("id").value();
+ Object vId = ((Vertex) traverser.get()).property("id").value();
currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
System.out.printf("IterationKey: %s Traverser: %s Path: %s Counter: %s High: %s%n", iterationKey, vId, traverser.path(), currentCounter.get(), this.high);
}
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index 4a455a58a1..82d72c69a5 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -69,11 +69,35 @@ public class TinkerGraphPlayTest {
public void testIterationScopedRangeGlobalInRepeat() {
GraphTraversalSource g = TinkerGraph.open().traversal().withoutStrategies(RepeatUnrollStrategy.class);
load(g);
- GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0").repeat(__.limit(1).out("knows")).times(2).path().by("id");
+ GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0")
+ .repeat(__.limit(1).out("knows"))
+ .times(2).path().by("id");
toListAndPrint("basic", basic);
- GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0").repeat(__.limit(1).out("knows")).times(2).repeat(__.limit(1).in("knows")).times(2).path().by("id");
+ GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l1-0")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .path().by("id");
+ toListAndPrint("basicUnfolded", basicUnfolded);
+
+ GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0")
+ .repeat(__.limit(1).out("knows")).times(2)
+ .repeat(__.limit(1).in("knows")).times(2)
+ .path().by("id");
toListAndPrint("chained", chained);
- GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0").repeat(__.limit(1).out("knows").repeat(__.limit(1).in("knows")).times(2)).times(2).path().by("id");
+ GraphTraversal<Vertex, Path> chainedUnfolded = g.V().has("id", "l2-0")
+ .limit(1).out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .path().by("id");
+ toListAndPrint("chainedUnfolded", chainedUnfolded);
+
+ GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0")
+ .repeat(__.limit(1).out("knows")
+ .repeat(__.limit(1).in("knows"))
+ .times(2))
+ .times(2)
+ .path().by("id");
toListAndPrint("nested", nested);
GraphTraversal<Vertex, Path> nestedUnfolded = g.V().has("id", "l3-0")
.limit(1).out("knows")
@@ -94,7 +118,6 @@ public class TinkerGraphPlayTest {
.times(2)
.path().by("id");
toListAndPrint("tripleNested", tripleNested);
-
GraphTraversal<Vertex, Path> tripleNestedUnfolded = g.V().has("id", "l1-0")
.limit(1).out("knows")
.limit(1).in("knows")
@@ -114,11 +137,31 @@ public class TinkerGraphPlayTest {
toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded);
GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
- repeat(__.limit(1).out("knows").repeat(__.limit(1).in("knows")).times(2)).
- times(2).path().by("id");
+ repeat(__.limit(1).out("knows")
+ .repeat(__.limit(1).in("knows"))
+ .times(2)).
+ times(2)
+ .path().by("id");
toListAndPrint("nested2", nested2);
-// GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0").repeat(__.limit(1).out("knows").aggregate("x")).times(2).cap("x");
-// toListAndPrint("aggregate", aggregate);
+ GraphTraversal<Vertex, Path> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .path().by("id");
+ toListAndPrint("nested2Unfolded", nested2Unfolded);
+ GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0").repeat(__.limit(1).out("knows").aggregate("x")).times(2).cap("x");
+ toListAndPrint("aggregate", aggregate);
+
+ GraphTraversal<Vertex, Path> test = g.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .repeat(__.limit(1))
+ .times(1).path().by("id");
+ toListAndPrint("test", test);
+ GraphTraversal<Vertex, Path> test2 = g.V().has("id", "l1-0").union(out().limit(1), out().out().limit(1)).limit(1).path().by("id");
+ toListAndPrint("test2", test2);
}
private void toListAndPrint(String header, GraphTraversal t) {
(tinkerpop) 07/19: Added more tests.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 2c4b4e689659e061ffbb0a0f08c50add3df5b866
Author: Andrea Child <an...@improving.com>
AuthorDate: Fri Aug 29 16:24:47 2025 -0700
Added more tests.
---
.../traversal/step/filter/RangeGlobalStep.java | 1 +
.../tinkergraph/structure/TinkerGraphPlayTest.java | 117 +++++++++++++++++++++
2 files changed, 118 insertions(+)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index e02c572c3c..2b7c7431c7 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -79,6 +79,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
Traversal.Admin t = this.traversal;
while (!t.isRoot()) {
TraversalParent pt = t.getParent();
+ // TODO: account scenario where parent is not repeat step?
Step<?, ?> ps = pt.asStep();
String pid = ps.getId();
sb.append(pid).append(":");
diff --git a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
index e6ccff6d8d..af6485be9e 100644
--- a/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
+++ b/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
@@ -85,6 +85,18 @@ public class TinkerGraphPlayTest {
assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
}
+ @Test
+ public void testBasicRepeatLimitIncreasedLimit() {
+ GraphTraversal<Vertex, Path> basic = g.V().has("id", "l1-0")
+ .repeat(__.limit(2).out("knows"))
+ .times(2).path().by("id");
+ GraphTraversal<Vertex, Path> basicUnfolded = g.V().has("id", "l1-0")
+ .limit(2).out("knows")
+ .limit(2).out("knows")
+ .path().by("id");
+ assertEquals(toListAndPrint("basic", basic), toListAndPrint("basicUnfolded", basicUnfolded));
+ }
+
@Test
public void testChainedRepeatLimit() {
GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0")
@@ -100,6 +112,21 @@ public class TinkerGraphPlayTest {
assertEquals(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded));
}
+ @Test
+ public void testChainedRepeatLimitIncreasedLimit() {
+ GraphTraversal<Vertex, Path> chained = g.V().has("id", "l2-0")
+ .repeat(__.limit(2).out("knows")).times(2)
+ .repeat(__.limit(3).in("knows")).times(2)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> chainedUnfolded = g.V().has("id", "l2-0")
+ .limit(2).out("knows")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(3).in("knows")
+ .path().by("id");
+ assertEquals(toListAndPrint("chained", chained), toListAndPrint("chainedUnfolded", chainedUnfolded));
+ }
+
@Test
public void testNestedRepeatLimit() {
GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0")
@@ -135,6 +162,41 @@ public class TinkerGraphPlayTest {
assertEquals(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded));
}
+ @Test
+ public void testNestedRepeatLimitIncreasedLimit() {
+ GraphTraversal<Vertex, Path> nested = g.V().has("id", "l3-0")
+ .repeat(__.limit(2).out("knows")
+ .repeat(__.limit(3).in("knows"))
+ .times(2))
+ .times(2)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> nestedUnfolded = g.V().has("id", "l3-0")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(3).in("knows")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(3).in("knows")
+ .path().by("id");
+ assertEquals(toListAndPrint("nested", nested), toListAndPrint("nestedUnfolded", nestedUnfolded));
+
+ GraphTraversal<Vertex, Path> nested2 = g.V().has("id", "l3-0").out("knows").
+ repeat(__.limit(1).out("knows")
+ .repeat(__.limit(1).in("knows"))
+ .times(2)).
+ times(2)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> nested2Unfolded = g.V().has("id", "l3-0").out("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .limit(1).out("knows")
+ .limit(1).in("knows")
+ .limit(1).in("knows")
+ .path().by("id");
+ assertEquals(toListAndPrint("nested2", nested2), toListAndPrint("nested2Unfolded", nested2Unfolded));
+ }
+
@Test
public void testTripleNestedRepeatLimit() {
GraphTraversal<Vertex, Path> tripleNested = g.V().has("id", "l1-0")
@@ -164,6 +226,35 @@ public class TinkerGraphPlayTest {
assertEquals(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded));
}
+ @Test
+ public void testTripleNestedRepeatLimitIncreasedLimit() {
+ GraphTraversal<Vertex, Path> tripleNested = g.V().has("id", "l1-0")
+ .repeat(__.limit(2).out("knows")
+ .repeat(__.limit(3).in("knows")
+ .repeat(__.limit(4).out("knows"))
+ .times(2))
+ .times(2))
+ .times(2)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> tripleNestedUnfolded = g.V().has("id", "l1-0")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .limit(2).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .limit(3).in("knows")
+ .limit(4).out("knows")
+ .limit(4).out("knows")
+ .path().by("id");
+ assertEquals(toListAndPrint("tripleNested", tripleNested), toListAndPrint("tripleNestedUnfolded", tripleNestedUnfolded));
+ }
+
@Test
public void testAggregateRepeatLimit() {
GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0")
@@ -177,6 +268,19 @@ public class TinkerGraphPlayTest {
assertEquals(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded));
}
+ @Test
+ public void testAggregateRepeatLimitIncreasedLimit() {
+ GraphTraversal<Vertex, Object> aggregate = g.V().has("id", "l1-0")
+ .repeat(__.limit(3).out("knows").aggregate("x"))
+ .times(2)
+ .cap("x");
+ GraphTraversal<Vertex, Object> aggregateUnfolded = g.V().has("id", "l1-0")
+ .limit(3).out("knows").aggregate("x")
+ .limit(3).out("knows").aggregate("x")
+ .cap("x");
+ assertEquals(toListAndPrint("aggregate", aggregate), toListAndPrint("aggregateUnfolded", aggregateUnfolded));
+ }
+
@Test
public void testUnionRepeatLimit() {
GraphTraversal<Vertex, Path> union = g.V().has("id", "l1-0")
@@ -189,6 +293,19 @@ public class TinkerGraphPlayTest {
.path().by("id");
assertEquals(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded));
}
+
+ @Test
+ public void testUnionRepeatLimitIncreasedLimit() {
+ GraphTraversal<Vertex, Path> union = g.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .repeat(__.limit(3)).times(1)
+ .path().by("id");
+ GraphTraversal<Vertex, Path> unionUnfolded = g.V().has("id", "l1-0")
+ .union(out().limit(1), out().out().limit(1))
+ .limit(3)
+ .path().by("id");
+ assertEquals(toListAndPrint("union", union), toListAndPrint("unionUnfolded", unionUnfolded));
+ }
private List toListAndPrint(String header, GraphTraversal t) {
System.out.println("=====" + header + "===================================");
(tinkerpop) 13/19: Fixed getLoopNames logic.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 4af663175e0318a68bb816774ebce9bbcb5cd2a8
Author: Andrea Child <an...@improving.com>
AuthorDate: Tue Sep 2 13:31:31 2025 -0700
Fixed getLoopNames logic.
---
.../gremlin/process/traversal/step/filter/RangeGlobalStep.java | 9 +++++----
.../traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java | 6 ++++++
.../process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java | 6 ++++++
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 2be2a7da1a..2585f73543 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -74,14 +74,15 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
AtomicLong currentCounter = this.counter;
if (usePerIterationCounters) {
StringBuilder sb = new StringBuilder();
- Traversal.Admin t = this.traversal;
+ Traversal.Admin<?,?> t = this.traversal;
while (!t.isRoot()) {
TraversalParent pt = t.getParent();
- // TODO: account scenario where parent is not repeat step?
Step<?, ?> ps = pt.asStep();
String pid = ps.getId();
- sb.append(pid).append(":");
- sb.append(traverser.loops(pid)).append(":");
+ if (traverser.getLoopNames().contains(pid)) {
+ sb.append(pid).append(":");
+ sb.append(traverser.loops(pid)).append(":");
+ }
t = ps.getTraversal();
}
sb.append(this.getId()).append(":").append(traverser.loops());
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java
index 70e827630d..57cdf63c2d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_NL_O_P_S_SE_SL_Traverser.java
@@ -18,6 +18,7 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.traverser;
+import java.util.Set;
import org.apache.commons.collections.map.ReferenceMap;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.LabelledCounter;
@@ -47,6 +48,11 @@ public class B_LP_NL_O_P_S_SE_SL_Traverser<T> extends B_LP_O_P_S_SE_SL_Traverser
return this.nestedLoops.peek().count();
}
+ @Override
+ public Set<String> getLoopNames() {
+ return loopNames.keySet();
+ }
+
@Override
public int loops(final String loopName) {
if (loopName == null)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java
index cb05a7559e..3ce0884c6e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_NL_O_S_SE_SL_Traverser.java
@@ -18,6 +18,7 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal.traverser;
+import java.util.Set;
import org.apache.commons.collections.map.ReferenceMap;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.LabelledCounter;
@@ -56,6 +57,11 @@ public class B_NL_O_S_SE_SL_Traverser<T> extends B_O_S_SE_SL_Traverser<T> {
throw new IllegalArgumentException("Loop name not defined: " + loopName);
}
+ @Override
+ public Set<String> getLoopNames() {
+ return loopNames.keySet();
+ }
+
@Override
public void initialiseLoops(final String stepLabel, final String loopName) {
if (this.nestedLoops.empty() || !this.nestedLoops.peek().hasLabel(stepLabel)) {
(tinkerpop) 19/19: Replaced tests with ones against modern graph.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 40183f519c936584f599a58ef0b7d0ebd2d17e50
Author: Andrea Child <an...@improving.com>
AuthorDate: Wed Sep 3 23:33:33 2025 -0700
Replaced tests with ones against modern graph.
---
.../gremlin/test/features/filter/Range.feature | 143 ++++++++-------------
1 file changed, 51 insertions(+), 92 deletions(-)
diff --git a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
index 14407afab8..047ac64e78 100644
--- a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
+++ b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/filter/Range.feature
@@ -412,164 +412,123 @@ Feature: Step - range()
| l[d[2].i] |
| l[d[5].i] |
- Scenario: g_V_hasXnameX_repeatXlimitX1X_outXfollowedByXX_timesX2X_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX7XXX_valuesXnameX
- Given the grateful graph
- And the traversal of
- """
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(1).out("followedBy")).times(2).has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(7))).values("name")
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | GLORIA |
- | DRUMS |
-
- Scenario: g_V_hasXnameX_limitX1X_outXfollowedByX_limitX1X_outXfollowedByX_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX7XXX_valuesXnameX
- Given the grateful graph
+ Scenario: 111.1
+ Given the modern graph
+ And using the parameter vid1 defined as "v[marko].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(1).out("followedBy").limit(1).out("followedBy").has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(7))).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid1).repeat(__.limit(1)).times(2).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | GLORIA |
- | DRUMS |
+ | marko |
- Scenario: g_V_hasXnameX_repeatXlimitX2X_outXfollowedByXX_timesX2X_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
- Given the grateful graph
+ Scenario: 111.2
+ Given the modern graph
+ And using the parameter vid1 defined as "v[marko].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(2).out("followedBy")).times(2).has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid1).repeat(__.limit(1)).until(__.loops().is(2)).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | RAIN |
- | DEAL |
+ | marko |
- Scenario: g_V_hasXnameX_limitX2X_outXfollowedByX_limitX2X_outXfollowedByX_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
- Given the grateful graph
+ Scenario: 111.3
+ Given the modern graph
+ And using the parameter vid1 defined as "v[marko].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(2).out("followedBy").limit(2).out("followedBy").has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid1).limit(1).limit(1).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | RAIN |
- | DEAL |
+ | marko |
- Scenario: g_V_hasXnameX_repeatXoutXfollowedByX_limitX1XX_timesX2X_valuesXnameX
- Given the grateful graph
+ Scenario: 222.1
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.out("followedBy").limit(1)).times(2).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).repeat(__.limit(1).in()).times(2).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | PLAYING IN THE BAND |
+ | marko |
- Scenario: g_V_hasXnameX_outXfollowedByX_limitX1X_outXfollowedByX_limitX1X_valuesXnameX
- Given the grateful graph
+ Scenario: 222.2
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").out("followedBy").limit(1).out("followedBy").limit(1).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).repeat(__.limit(1).in()).until(loops().is(2)).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | PLAYING IN THE BAND |
+ | marko |
- Scenario: g_V_hasXnameX_repeatXoutXfollowedByX_limitX2XX_timesX2X_valuesXnameX
- Given the grateful graph
+ Scenario: 222.3
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.out("followedBy").limit(2)).times(2).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).limit(1).in().limit(1).in().values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | SUGAR MAGNOLIA |
- | PLAYING IN THE BAND |
+ | marko |
- Scenario: g_V_hasXnameX_outXfollowedByX_limitX2X_outXfollowedByX_limitX2X_valuesXnameX
- Given the grateful graph
+ Scenario: 333.1
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").out("followedBy").limit(2).out("followedBy").limit(2).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).repeat(__.limit(1).in()).times(1).repeat(__.limit(1).in()).times(1).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | SUGAR MAGNOLIA |
- | PLAYING IN THE BAND |
+ | marko |
- Scenario: g_V_hasXnameX_repeatXlimitX1X_outXfollowedByXX_timesX2X_repeatXlimitX1X_inXfollowedByXX_timesX1X_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
- Given the grateful graph
+ Scenario: 333.2
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(1).out("followedBy")).times(2).repeat(__.limit(1).in("followedBy")).times(1).has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).repeat(__.limit(1).in()).until(loops().is(1)).repeat(__.limit(1).in()).until(loops().is(1)).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | DEAL |
+ | marko |
- Scenario: g_V_hasXnameX_limitX1X_outXfollowedByX_limitX1X_outXfollowedByX_limitX1X_inXfollowedByX_hasXnameX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_valuesXnameX
- Given the grateful graph
+ Scenario: 444.1
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(1).out("followedBy").limit(1).out("followedBy").limit(1).in("followedBy").has("name", neq("")).filter(__.values("name").map(__.length()).is(lt(5))).values("name")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).repeat(__.limit(1).in().repeat(__.limit(1).in()).times(1)).times(1).values("name")
"""
When iterated to list
Then the result should be unordered
| result |
- | DEAL |
-
- Scenario: g_V_hasXnameX_repeatXlimitX1X_outXfollowedByX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_aggregateXxX_byXnameXX_timesX2X_capXxX
- Given the grateful graph
- And the traversal of
- """
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").repeat(__.limit(1).out("followedBy").filter(__.values("name").map(__.length()).is(lt(5))).aggregate("x").by("name")).times(2).cap("x")
- """
- When iterated next
- Then the result should be unordered
- | result |
- | DEAL |
- | RAIN |
+ | marko |
- Scenario: g_V_hasXnameX_limitX1X_outXfollowedByX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_aggregateXxX_byXnameX_limitX1X_outXfollowedByX_filterXvaluesXnameX_mapXlengthXX_isXltX5XXX_aggregateXxX_byXnameX_capXxX
- Given the grateful graph
+ Scenario: 444.2
+ Given the modern graph
+ And using the parameter vid5 defined as "v[ripple].id"
And the traversal of
"""
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").limit(1).out("followedBy").filter(__.values("name").map(__.length()).is(lt(5))).aggregate("x").by("name").limit(1).out("followedBy").filter(__.values("name").map(__.length()).is(lt(5))).aggregate("x").by("name").cap("x")
+ g.withoutStrategies(RepeatUnrollStrategy).V(vid5).repeat(limit(1).in().aggregate('x')).times(2).cap('x')
"""
When iterated next
Then the result should be unordered
| result |
- | DEAL |
- | RAIN |
-
- Scenario: g_V_hasXnameX_unionXoutXfollowedByX_limitX1X_outXfollowedByX_outXfollowedByX_limitX1XX_repeatXlimitX1XX_timesX1X_valuesXnameX
- Given the grateful graph
- And the traversal of
- """
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").union(__.out("followedBy").limit(1), __.out("followedBy").out("followedBy").limit(1)).repeat(__.limit(1)).times(1).values("name")
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | MORNING DEW |
-
- Scenario: g_V_hasXnameX_unionXoutXfollowedByX_limitX1X_outXfollowedByX_outXfollowedByX_limitX1XX_limitX1X_valuesXnameX
- Given the grateful graph
- And the traversal of
- """
- g.withoutStrategies(RepeatUnrollStrategy).V().has("name", "DARK STAR").union(__.out("followedBy").limit(1), __.out("followedBy").out("followedBy").limit(1)).limit(1).values("name")
- """
- When iterated to list
- Then the result should be unordered
- | result |
- | MORNING DEW |
+ | v[josh] |
+ | v[marko] |
\ No newline at end of file
(tinkerpop) 01/19: Q's first attempt to change limit in repeat to per-iteration counters.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 78b223f8cd6a08beceaf08352e95205059514098
Author: Andrea Child <an...@improving.com>
AuthorDate: Sun Aug 24 22:56:07 2025 -0700
Q's first attempt to change limit in repeat to per-iteration counters.
---
.../process/traversal/step/branch/RepeatStep.java | 28 +++++++++++++++
.../traversal/step/filter/RangeGlobalStep.java | 40 +++++++++++++++++-----
2 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
index 17b8a2ef4e..3f27e71e54 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ComputerAwareStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.RangeGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
@@ -67,6 +68,9 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
this.repeatTraversal = repeatTraversal; // .clone();
this.repeatTraversal.addStep(new RepeatEndStep(this.repeatTraversal));
this.integrateChild(this.repeatTraversal);
+
+ // Enable per-iteration counters on any RangeGlobalStep instances within the repeat traversal
+ this.enablePerIterationCountersOnRangeSteps(this.repeatTraversal);
}
@@ -125,6 +129,26 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
return emitFirst == this.emitFirst && null != this.emitTraversal && TraversalUtil.test(traverser, this.emitTraversal);
}
+ /**
+ * Recursively enables per-iteration counters on all RangeGlobalStep instances within a traversal.
+ */
+ private void enablePerIterationCountersOnRangeSteps(final Traversal.Admin<?, ?> traversal) {
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ if (step instanceof RangeGlobalStep) {
+ ((RangeGlobalStep<?>) step).enablePerIterationCounters();
+ }
+ if (step instanceof TraversalParent) {
+ final TraversalParent parent = (TraversalParent) step;
+ for (final Traversal.Admin<?, ?> childTraversal : parent.getGlobalChildren()) {
+ this.enablePerIterationCountersOnRangeSteps(childTraversal);
+ }
+ for (final Traversal.Admin<?, ?> childTraversal : parent.getLocalChildren()) {
+ this.enablePerIterationCountersOnRangeSteps(childTraversal);
+ }
+ }
+ }
+ }
+
@Override
public String toString() {
if (this.untilFirst && this.emitFirst)
@@ -169,6 +193,10 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav
clone.untilTraversal = this.untilTraversal.clone();
if (null != this.emitTraversal)
clone.emitTraversal = this.emitTraversal.clone();
+
+ // Enable per-iteration counters on the cloned repeat traversal
+ clone.enablePerIterationCountersOnRangeSteps(clone.repeatTraversal);
+
return clone;
}
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index 792ab2d645..5d6dbbab7c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -32,6 +32,8 @@ import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.io.Serializable;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@@ -47,6 +49,10 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
private long high;
private AtomicLong counter = new AtomicLong(0l);
private boolean bypass;
+
+ // Per-iteration counter tracking for repeat steps
+ private Map<String, AtomicLong> perIterationCounters = new HashMap<>();
+ private boolean usePerIterationCounters = false;
public RangeGlobalStep(final Traversal.Admin traversal, final long low, final long high) {
super(traversal);
@@ -61,31 +67,38 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
protected boolean filter(final Traverser.Admin<S> traverser) {
if (this.bypass) return true;
- if (this.high != -1 && this.counter.get() >= this.high) {
+ // Determine which counter to use
+ AtomicLong currentCounter = this.counter;
+ if (usePerIterationCounters && traverser.loops() > 0) {
+ String iterationKey = traverser.getStepId() + ":" + traverser.loops();
+ currentCounter = perIterationCounters.computeIfAbsent(iterationKey, k -> new AtomicLong(0L));
+ }
+
+ if (this.high != -1 && currentCounter.get() >= this.high) {
throw FastNoSuchElementException.instance();
}
long avail = traverser.bulk();
- if (this.counter.get() + avail <= this.low) {
+ if (currentCounter.get() + avail <= this.low) {
// Will not surpass the low w/ this traverser. Skip and filter the whole thing.
- this.counter.getAndAdd(avail);
+ currentCounter.getAndAdd(avail);
return false;
}
// Skip for the low and trim for the high. Both can happen at once.
long toSkip = 0;
- if (this.counter.get() < this.low) {
- toSkip = this.low - this.counter.get();
+ if (currentCounter.get() < this.low) {
+ toSkip = this.low - currentCounter.get();
}
long toTrim = 0;
- if (this.high != -1 && this.counter.get() + avail >= this.high) {
- toTrim = this.counter.get() + avail - this.high;
+ if (this.high != -1 && currentCounter.get() + avail >= this.high) {
+ toTrim = currentCounter.get() + avail - this.high;
}
long toEmit = avail - toSkip - toTrim;
- this.counter.getAndAdd(toSkip + toEmit);
+ currentCounter.getAndAdd(toSkip + toEmit);
traverser.setBulk(toEmit);
return true;
@@ -95,6 +108,15 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
public void reset() {
super.reset();
this.counter.set(0l);
+ this.perIterationCounters.clear();
+ }
+
+ /**
+ * Enables per-iteration counter tracking for use within repeat steps.
+ * When enabled, separate counters are maintained for each repeat iteration.
+ */
+ public void enablePerIterationCounters() {
+ this.usePerIterationCounters = true;
}
@Override
@@ -116,6 +138,8 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
public RangeGlobalStep<S> clone() {
final RangeGlobalStep<S> clone = (RangeGlobalStep<S>) super.clone();
clone.counter = new AtomicLong(0l);
+ clone.perIterationCounters = new HashMap<>();
+ clone.usePerIterationCounters = this.usePerIterationCounters;
return clone;
}
(tinkerpop) 03/19: Change to nested loop requirement.
Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch repeatLimit
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit c6df17362526be68402147ecd41adff6a769783f
Author: Andrea Child <an...@improving.com>
AuthorDate: Tue Aug 26 08:31:08 2025 -0700
Change to nested loop requirement.
---
.../gremlin/process/traversal/step/filter/RangeGlobalStep.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
index ef8bcaf5a8..004d52e0d9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/RangeGlobalStep.java
@@ -163,7 +163,7 @@ public final class RangeGlobalStep<S> extends FilterStep<S> implements Ranging,
if (usePerIterationCounters) {
final Set<TraverserRequirement> requirements = new HashSet<>();
requirements.add(TraverserRequirement.BULK);
- requirements.add(TraverserRequirement.SINGLE_LOOP);
+ requirements.add(TraverserRequirement.NESTED_LOOP);
return requirements;
}
return Collections.singleton(TraverserRequirement.BULK);