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/10/01 19:24:46 UTC
(tinkerpop) branch 3.8-dev updated: CTR: Docs updates for strategies to reflect GValue awareness
This is an automated email from the ASF dual-hosted git repository.
colegreer pushed a commit to branch 3.8-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/3.8-dev by this push:
new c3c3baa51a CTR: Docs updates for strategies to reflect GValue awareness
c3c3baa51a is described below
commit c3c3baa51ae28feef05fb312b3bddb916f5a1a54
Author: Cole-Greer <Co...@improving.com>
AuthorDate: Wed Oct 1 12:24:37 2025 -0700
CTR: Docs updates for strategies to reflect GValue awareness
---
docs/src/reference/the-traversal.asciidoc | 82 +++++++++++++++++++++-
.../provider/ProviderGValueReductionStrategy.java | 3 -
2 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index ef9ffe8ceb..dbcb9af468 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -5861,7 +5861,7 @@ public final class TinkerGraphStepStrategy extends AbstractTraversalStrategy<Tra
if (TraversalHelper.onGraphComputer(traversal))
return;
- for (GraphStep originalGraphStep : TraversalHelper.getStepsOfClass(GraphStep.class, traversal)) {
+ for (GraphStepContract originalGraphStep : TraversalHelper.getStepsOfAssignableClass(GraphStepContract.class, traversal)) {
TinkerGraphStep<?, ?> tinkerGraphStep = new TinkerGraphStep<>(originalGraphStep);
TraversalHelper.replaceStep(originalGraphStep, tinkerGraphStep, traversal);
Step<?, ?> currentStep = tinkerGraphStep.getNextStep();
@@ -5935,6 +5935,58 @@ g.V().hasLabel('person'). <1>
<8> `PathRetractionStrategy` will remove paths from the traversers and increase the likelihood of bulking as path data is not required after `select('b')`.
<9> `AdjacentToIncidentStrategy` will turn `out()` into `outE()` to increase data access locality.
+==== A note on Traversal Parameters
+
+Certain gremlin steps are able to accept parameterized arguments in the form of one of more `GValue` objects. Please see
+the <<traversal-parameterization,parameterizable steps documentation>> for a complete listing of such steps.
+
+When authoring strategies that interact with parameterizable steps, it's important to work with `StepContract` interfaces
+rather than concrete step classes. Parameterizable steps can exist as either concrete implementations or as placeholder
+steps that hold `GValue` objects (parameterized arguments). The placeholders are temporary proxies for the concrete
+steps which exist during strategy execution, but must be "reduced" to concrete steps prior to traversal execution. Both
+concrete and placeholder forms of a step implement the same contract interface, allowing strategies to work uniformly
+with either representation.
+
+[source,java]
+----
+// Use contract interfaces for parameterizable steps
+ for (GraphStepContract originalGraphStep : TraversalHelper.getStepsOfAssignableClass(GraphStepContract.class, traversal)) {
+ // Work with all matching instances of a step through its contract <1>
+ }
+if (step instanceof GraphStepContract) {
+ GraphStepContract graphStep = (GraphStepContract) step;
+ // Work with the step through its contract
+}
+
+// Instead of checking concrete classes
+if (step instanceof GraphStep) {
+ // This approach has the risk of missing instances of GraphStepPlaceholder
+}
+----
+
+<1> Note that use of `TraversalHelper.getStepsOfAssignableClass(GraphStepContract.class, traversal))` will match all
+instances of TinkerPop's reference implementations of `GraphStepContract`, ie `GraphStep` and `GraphStepPlaceholder`,
+but will not match and provider specific implementations of the contract such as `TinkerGraphStep`. Similar rules apply
+to matching any StepContract via this method.
+
+The contract-based approach ensures strategies work correctly whether the step is in its concrete form or placeholder
+form with `GValue` parameters. Common contract interfaces include:
+
+* `AddVertexStepContract` - for `AddVertexStep` and `AddVertexStartStep`
+* `AddEdgeStepContract` - for `AddEdgeStep` and `AddEdgeStartStep`
+* `VertexStepContract` - for `VertexStep`
+* `GraphStepContract` - for `GraphStep`
+* `MergeStepContract` - for `MergeVertexStep` and `MergeEdgeStep`
+
+Strategy authors should consult the `GValueReductionStrategy` to understand how placeholder steps are converted to
+concrete steps, and consider whether their strategy should execute before or after this conversion based on whether
+they need to work with `GValue` objects or concrete step implementations. As this is an `OptimizationStrategy`, any
+`ProviderOptimizationStrategy` are excluded by default from the above considerations regarding parameterizable steps.
+Any providers who wish to leverage `GValue` in a `ProviderOptimizationStrategy` should first remove
+`GValueReductionStrategy`, and take ownership over ensuring all placeholder steps are reduced to concrete steps
+afterward. `ProviderGValueReductionStrategy` is offered for such purposes.
+----
+
=== EdgeLabelVerificationStrategy
`EdgeLabelVerificationStrategy` prevents traversals from writing traversals that do not explicitly specify and edge
@@ -6061,6 +6113,34 @@ new transaction immediately following the `commit()` that raises the events. The
may also not behave as "snapshots" at the time of their creation as they are "live" references to actual database
elements.
+=== GValueReductionStrategy
+
+`GValueReductionStrategy` converts placeholder steps that hold `GValue` objects to their concrete implementations.
+While not an optimization in and of itself, the `GValue` functionality provides a mechanism for traversal optimization
+and parameterization, so this strategy falls in the optimization category. Converting to concrete steps at this stage
+also allows provider optimization strategies to execute on concrete steps rather than step interfaces, which are much
+easier to reason about for the vast majority of providers.
+
+This strategy is automatically applied and typically does not need to be explicitly configured by users. However,
+providers hoping to do more advanced optimizations that require `GValue` objects to be present for their strategies
+will need to remove `GValueReductionStrategy` and offer their own mechanism for converting step placeholders to
+concrete steps. `ProviderGValueReductionStrategy` is a base class available to help with this need.
+
+The strategy operates by calling the `reduce()` method on any step that implements `GValueHolder`:
+
+[source,java]
+----
+@Override
+public void apply(final Traversal.Admin<?, ?> traversal) {
+ final List<Step> steps = traversal.getSteps();
+ for (int i = 0; i < steps.size(); i++) {
+ if (steps.get(i) instanceof GValueHolder) {
+ ((GValueHolder) steps.get(i)).reduce();
+ }
+ }
+}
+----
+
[[partitionstrategy]]
=== PartitionStrategy
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
index a3c3c92a27..5e8d870f7f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/provider/ProviderGValueReductionStrategy.java
@@ -24,11 +24,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.process.traversal.step.GValueHolder;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
/**
* Converts placeholder steps that hold {@link GValue} objects to their concrete implementations. While not an