Skip to content

Commit 2ac1eb9

Browse files
vaibhavm99Vaibhav Malhotra
andauthored
getScopingInfo utility added (#3118)
Added PopContaining interface, and its implementation in Scoping.java and TraversalParent.java, and classes that use these interfaces. Co-authored-by: Vaibhav Malhotra <vaimalho@amazon.com>
1 parent eeb989c commit 2ac1eb9

32 files changed

Lines changed: 753 additions & 6 deletions

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
3030
[[release-4-0-0-beta-1]]
3131
=== TinkerPop 4.0.0-beta.1 (January 17, 2025)
3232
33+
* Added the `PopContaining` interface designed to get label and `Pop` combinations held in a `PopInstruction` object.
3334
* Added support for deserialization of `Set` for `gremlin-javascript`.
3435
* Added grammar-based `Translator` for all languages including explicit ones for Java and anonymization.
3536
* Removed old `Translator` infrastructure.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.tinkerpop.gremlin.process.traversal.step;
20+
21+
import java.util.Objects;
22+
import java.util.Set;
23+
24+
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
25+
26+
/**
27+
* The {@code PopContaining} interface is implemented by traversal steps that maintain Pop instructions
28+
* for label access. It provides a mechanism to track and manage how labeled elements should
29+
* be accessed using {@link Pop} semantics (first, last, all, or mixed).
30+
*
31+
* In Gremlin traversals, various elements can be labeled and later accessed via these labels.
32+
* The {@link Pop} enum determines how to access these labeled elements when there are multiple
33+
* values associated with the same label.
34+
*
35+
* <pre>
36+
* {@code
37+
* // Simple example with default Pop.last behavior
38+
* gremlin> g.V().as("a").out().as("a").select("a")
39+
* ==>[v[2]] // returns the last element labeled "a"
40+
*
41+
* // Using Pop.first to get the first labeled element
42+
* gremlin> g.V().as("a").out().as("a").select(first, "a")
43+
* ==>[v[1]] // returns the first element labeled "a"
44+
*
45+
* // Using Pop.all to get all labeled elements
46+
* gremlin> g.V().as("a").out().as("a").select(all, "a")
47+
* ==>[v[1], v[2]] // returns all elements labeled "a"
48+
* }
49+
* </pre>
50+
*
51+
* Steps implementing this interface maintain a collection of {@link PopInstruction} objects, each containing
52+
* a label and a {@link Pop} value that specifies how to access elements with that label.
53+
*
54+
*/
55+
public interface PopContaining {
56+
public Set<PopInstruction> getPopInstructions();
57+
/**
58+
* A class for storing the Scope Context. It has two elements:
59+
* - label: String
60+
* - pop: Pop value
61+
*/
62+
class PopInstruction {
63+
private final Pop pop;
64+
private final String label;
65+
66+
public PopInstruction(String label, Pop pop) {
67+
this.pop = pop;
68+
this.label = label;
69+
}
70+
71+
public PopInstruction(final Pop pop, final String label) {
72+
this.pop = pop;
73+
this.label = label;
74+
}
75+
76+
public PopInstruction() {
77+
this.pop = null;
78+
this.label = "";
79+
}
80+
81+
public String getLabel() {
82+
return label;
83+
}
84+
85+
public Pop getPop() {
86+
return pop;
87+
}
88+
89+
@Override
90+
public boolean equals(Object o) {
91+
if (o == null || getClass() != o.getClass()) {
92+
return false;
93+
}
94+
final PopInstruction that = (PopInstruction) o;
95+
return getPop() == that.getPop() && Objects.equals(getLabel(), that.getLabel());
96+
}
97+
98+
@Override
99+
public int hashCode() {
100+
return Objects.hash(getPop(), getLabel());
101+
}
102+
}
103+
}

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.tinkerpop.gremlin.process.traversal.Step;
2424
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
2525

26+
import java.util.HashSet;
2627
import java.util.Map;
2728
import java.util.Set;
2829

@@ -105,7 +106,7 @@
105106
* @author Marko A. Rodriguez (http://markorodriguez.com)
106107
* @author Stephen Mallette (http://stephen.genoprime.com)
107108
*/
108-
public interface Scoping {
109+
public interface Scoping extends PopContaining {
109110

110111
public enum Variable {START, END}
111112

@@ -166,6 +167,23 @@ public default <S> S getNullableScopeValue(final Pop pop, final String key, fina
166167
*/
167168
public Set<String> getScopeKeys();
168169

170+
/**
171+
* Used to get PopInstruction of a Step that implements Scoping. PopInstruction includes the labels it needs, and the
172+
* pop type for each label.
173+
*
174+
* @return A Set of {@link PopInstruction} values which contain the label and Pop value
175+
*/
176+
@Override
177+
public default HashSet<PopInstruction> getPopInstructions() {
178+
final Set<String> labels = this.getScopeKeys();
179+
final HashSet<PopInstruction> scopingInfoSet = new HashSet<>();
180+
for (final String label : labels) {
181+
final PopInstruction scopingInfo = new PopInstruction(Pop.last, label);
182+
scopingInfoSet.add(scopingInfo);
183+
}
184+
return scopingInfoSet;
185+
}
186+
169187
public static class KeyNotFoundException extends Exception {
170188

171189
private final Object key;

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/TraversalParent.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@
2121
import org.apache.tinkerpop.gremlin.process.traversal.Step;
2222
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
2323
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
24+
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
2425

2526
import java.util.Collections;
2627
import java.util.EnumSet;
28+
import java.util.HashSet;
2729
import java.util.List;
2830
import java.util.Set;
2931

3032
/**
3133
* @author Marko A. Rodriguez (http://markorodriguez.com)
3234
*/
33-
public interface TraversalParent extends AutoCloseable {
35+
public interface TraversalParent extends PopContaining, AutoCloseable {
3436

3537
public default <S, E> List<Traversal.Admin<S, E>> getGlobalChildren() {
3638
return Collections.emptyList();
@@ -95,4 +97,16 @@ default void close() throws Exception {
9597
traversal.close();
9698
}
9799
}
100+
101+
@Override
102+
public default HashSet<PopInstruction> getPopInstructions() {
103+
final HashSet<PopInstruction> scopingInfos = new HashSet<>();
104+
for (final Traversal.Admin local: this.getLocalChildren()) {
105+
scopingInfos.addAll(TraversalHelper.getPopInstructions(local));
106+
}
107+
for (final Traversal.Admin global: this.getGlobalChildren()) {
108+
scopingInfos.addAll(TraversalHelper.getPopInstructions(global));
109+
}
110+
return scopingInfos;
111+
}
98112
}

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@ public Set<String> getScopeKeys() {
189189
return null == this.dedupLabels ? Collections.emptySet() : this.dedupLabels;
190190
}
191191

192+
@Override
193+
public HashSet<PopInstruction> getPopInstructions() {
194+
final HashSet<PopInstruction> popInstructions = new HashSet<>();
195+
popInstructions.addAll(Scoping.super.getPopInstructions());
196+
popInstructions.addAll(TraversalParent.super.getPopInstructions());
197+
return popInstructions;
198+
}
199+
192200
@Override
193201
public void processAllStarts() {
194202

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ public Set<String> getScopeKeys() {
132132
return Collections.unmodifiableSet(this.scopeKeys);
133133
}
134134

135+
@Override
136+
public HashSet<PopInstruction> getPopInstructions() {
137+
final HashSet<PopInstruction> popInstructions = new HashSet<>();
138+
popInstructions.addAll(Scoping.super.getPopInstructions());
139+
popInstructions.addAll(TraversalParent.super.getPopInstructions());
140+
return popInstructions;
141+
}
142+
135143
@Override
136144
public WherePredicateStep<S> clone() {
137145
final WherePredicateStep<S> clone = (WherePredicateStep<S>) super.clone();

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ public Set<String> getKeepLabels() {
147147
return this.keepLabels;
148148
}
149149

150+
@Override
151+
public HashSet<PopInstruction> getPopInstructions() {
152+
final HashSet<PopInstruction> popInstructions = new HashSet<>();
153+
popInstructions.addAll(Scoping.super.getPopInstructions());
154+
popInstructions.addAll(TraversalParent.super.getPopInstructions());
155+
return popInstructions;
156+
}
157+
150158
//////////////////////////////
151159

152160
public static class WhereStartStep<S> extends ScalarMapStep<S, Object> implements Scoping {

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStartStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
4444
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
4545

46+
import java.util.HashSet;
4647
import java.util.List;
4748
import java.util.Set;
4849

@@ -89,6 +90,13 @@ public Set<String> getScopeKeys() {
8990
return this.parameters.getReferencedLabels();
9091
}
9192

93+
@Override
94+
public HashSet<PopInstruction> getPopInstructions() {
95+
final HashSet<PopInstruction> popInstructions = new HashSet<>();
96+
popInstructions.addAll(TraversalParent.super.getPopInstructions());
97+
return popInstructions;
98+
}
99+
92100
@Override
93101
public void configure(final Object... keyValues) {
94102
this.parameters.set(this, keyValues);

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
4141
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
4242

43+
import java.util.HashSet;
4344
import java.util.List;
4445
import java.util.Set;
4546

@@ -86,6 +87,13 @@ public Set<String> getScopeKeys() {
8687
return this.parameters.getReferencedLabels();
8788
}
8889

90+
@Override
91+
public HashSet<PopInstruction> getPopInstructions() {
92+
final HashSet<PopInstruction> popInstructions = new HashSet<>();
93+
popInstructions.addAll(TraversalParent.super.getPopInstructions());
94+
return popInstructions;
95+
}
96+
8997
@Override
9098
public void configure(final Object... keyValues) {
9199
this.parameters.set(this, keyValues);

gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddVertexStartStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.apache.tinkerpop.gremlin.structure.Vertex;
3939
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
4040

41+
import java.util.HashSet;
4142
import java.util.List;
4243
import java.util.Set;
4344

@@ -85,6 +86,13 @@ public Set<String> getScopeKeys() {
8586
return this.parameters.getReferencedLabels();
8687
}
8788

89+
@Override
90+
public HashSet<PopInstruction> getPopInstructions() {
91+
final HashSet<PopInstruction> popInstructions = new HashSet<>();
92+
popInstructions.addAll(TraversalParent.super.getPopInstructions());
93+
return popInstructions;
94+
}
95+
8896
@Override
8997
public <S, E> List<Traversal.Admin<S, E>> getLocalChildren() {
9098
return this.parameters.getTraversals();

0 commit comments

Comments
 (0)