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 54c4271637 CTR Update equals and hashCode on step placeholders
54c4271637 is described below

commit 54c4271637db0acae01d1d3d2fcc173f1c3989db
Author: Cole-Greer <[email protected]>
AuthorDate: Tue Oct 28 15:43:41 2025 -0700

    CTR Update equals and hashCode on step placeholders
---
 .../traversal/step/filter/IsStepPlaceholder.java   | 12 +++-
 .../step/filter/TailGlobalStepPlaceholder.java     | 11 +++-
 .../step/map/AbstractAddEdgeStepPlaceholder.java   | 19 +++---
 .../map/AbstractAddElementStepPlaceholder.java     | 29 +++++----
 .../step/map/AbstractAddVertexStepPlaceholder.java | 16 +++++
 .../traversal/step/map/CallStepPlaceholder.java    | 22 ++++---
 .../traversal/step/map/GraphStepPlaceholder.java   | 20 +++---
 .../step/map/TailLocalStepPlaceholder.java         | 11 +++-
 .../traversal/step/map/VertexStepPlaceholder.java  | 72 +++++++++++++---------
 .../sideEffect/AddPropertyStepPlaceholder.java     | 16 ++++-
 .../process/traversal/step/util/Parameters.java    |  9 +++
 11 files changed, 166 insertions(+), 71 deletions(-)

diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStepPlaceholder.java
index 903f9eb34c..3328e536c6 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/IsStepPlaceholder.java
@@ -28,6 +28,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 
 import java.util.Collection;
 import java.util.EnumSet;
+import java.util.Objects;
 import java.util.Set;
 
 public final class IsStepPlaceholder<S> extends FilterStep<S> implements 
GValueHolder<S, S>, IsStepContract<S> {
@@ -65,9 +66,18 @@ public final class IsStepPlaceholder<S> extends 
FilterStep<S> implements GValueH
         return clone;
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        IsStepPlaceholder<?> that = (IsStepPlaceholder<?>) o;
+        return Objects.equals(predicate, that.predicate);
+    }
+
     @Override
     public int hashCode() {
-        return super.hashCode() ^ this.predicate.hashCode();
+        return Objects.hash(super.hashCode(), predicate);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStepPlaceholder.java
index 8c56ca149d..801a27b08a 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/TailGlobalStepPlaceholder.java
@@ -72,9 +72,18 @@ public final class TailGlobalStepPlaceholder<S> extends 
AbstractStep<S, S> imple
         return clone;
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        TailGlobalStepPlaceholder<?> that = (TailGlobalStepPlaceholder<?>) o;
+        return bypass == that.bypass && Objects.equals(limit, that.limit);
+    }
+
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Objects.hashCode(this.limit);
+        return Objects.hash(super.hashCode(), limit, bypass);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddEdgeStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddEdgeStepPlaceholder.java
index f320beedf7..bf04ec3ae0 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddEdgeStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddEdgeStepPlaceholder.java
@@ -28,6 +28,7 @@ import 
org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertex;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
 
 public abstract class AbstractAddEdgeStepPlaceholder<S> extends 
AbstractAddElementStepPlaceholder<S, Edge, Event.EdgeAddedEvent> implements 
AddEdgeStepContract<S> {
     protected Traversal.Admin<?, ?> from;
@@ -70,16 +71,18 @@ public abstract class AbstractAddEdgeStepPlaceholder<S> 
extends AbstractAddEleme
         this.integrateChild(this.from);
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        AbstractAddEdgeStepPlaceholder<?> that = 
(AbstractAddEdgeStepPlaceholder<?>) o;
+        return Objects.equals(from, that.from) && Objects.equals(to, that.to);
+    }
+
     @Override
     public int hashCode() {
-        int hash = super.hashCode();
-        if (from != null) {
-            hash ^= from.hashCode();
-        }
-        if (to != null) {
-            hash ^= to.hashCode();
-        }
-        return hash;
+        return Objects.hash(super.hashCode(), from, to);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddElementStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddElementStepPlaceholder.java
index 16001c70ef..66a3fca8fe 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddElementStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddElementStepPlaceholder.java
@@ -126,23 +126,22 @@ public abstract class 
AbstractAddElementStepPlaceholder<S, E extends Element, X
         throw new IllegalStateException("GValuePlaceholder step is not 
executable");
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        AbstractAddElementStepPlaceholder<?, ?, ?> that = 
(AbstractAddElementStepPlaceholder<?, ?, ?>) o;
+        return Objects.equals(label, that.label) &&
+                Objects.equals(properties, that.properties) &&
+                Objects.equals(elementId, that.elementId) &&
+                Objects.equals(scopeKeys, that.scopeKeys) &&
+                Objects.equals(withConfiguration, that.withConfiguration);
+    }
+
     @Override
     public int hashCode() {
-        int hash = super.hashCode();
-        if (label != null) {
-            hash ^= label.hashCode();
-        }
-        if (elementId != null) {
-            hash ^= elementId.hashCode();
-        }
-        if (properties != null) {
-            for (Map.Entry<Object, List<Object>> entry : 
properties.entrySet()) {
-                hash ^= Objects.hashCode(entry.getKey());
-                hash ^= Objects.hashCode(entry.getValue());
-            }
-        }
-        hash ^= withConfiguration.hashCode();
-        return hash;
+        return Objects.hash(super.hashCode(), label, properties, elementId, 
scopeKeys, withConfiguration);
     }
 
     protected void configureConcreteStep(AddElementStepContract<S, E> step) {
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddVertexStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddVertexStepPlaceholder.java
index 6413b816dd..2025951c01 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddVertexStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AbstractAddVertexStepPlaceholder.java
@@ -24,6 +24,8 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.step.GValueHolder;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.event.Event;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 
+import java.util.Objects;
+
 public abstract class AbstractAddVertexStepPlaceholder<S> extends 
AbstractAddElementStepPlaceholder<S, Vertex, Event.VertexAddedEvent>
         implements AddVertexStepContract<S>, GValueHolder<S, Vertex> {
 
@@ -54,6 +56,20 @@ public abstract class AbstractAddVertexStepPlaceholder<S> 
extends AbstractAddEle
         return userProvidedLabel;
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        AbstractAddVertexStepPlaceholder<?> that = 
(AbstractAddVertexStepPlaceholder<?>) o;
+        return userProvidedLabel == that.userProvidedLabel;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), userProvidedLabel);
+    }
+
     @Override
     public AbstractAddVertexStepPlaceholder<S> clone() {
         final AbstractAddVertexStepPlaceholder<S> clone = 
(AbstractAddVertexStepPlaceholder<S>) super.clone();
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CallStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CallStepPlaceholder.java
index da31839d84..ebd8db33ca 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CallStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/CallStepPlaceholder.java
@@ -202,16 +202,22 @@ public final class CallStepPlaceholder<S, E> extends 
AbstractStep<S, E> implemen
         return StringFactory.stepString(this, args.toArray());
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        CallStepPlaceholder<?, ?> that = (CallStepPlaceholder<?, ?>) o;
+        return isStart == that.isStart &&
+                Objects.equals(serviceName, that.serviceName) &&
+                Objects.equals(staticParams, that.staticParams) &&
+                Objects.equals(mapTraversal, that.mapTraversal) &&
+                Objects.equals(parameters, that.parameters);
+    }
+
     @Override
     public int hashCode() {
-        int hashCode = super.hashCode() ^ Objects.hashCode(this.serviceName);
-        if (!staticParams.get().isEmpty())
-            hashCode ^= staticParams.hashCode();
-        if (mapTraversal != null)
-            hashCode ^= mapTraversal.hashCode();
-        if (!parameters.isEmpty())
-            hashCode ^= parameters.hashCode();
-        return hashCode;
+        return Objects.hash(super.hashCode(), isStart, serviceName, 
staticParams, mapTraversal, parameters);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStepPlaceholder.java
index 06d523c5fd..7d36e22861 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GraphStepPlaceholder.java
@@ -112,15 +112,21 @@ public class GraphStepPlaceholder<S, E extends Element> 
extends AbstractStep<S,
         throw new IllegalStateException("GraphStepGValueContract is not 
executable");
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        GraphStepPlaceholder<?, ?> that = (GraphStepPlaceholder<?, ?>) o;
+        return isStart == that.isStart &&
+                onGraphComputer == that.onGraphComputer &&
+                Objects.equals(returnClass, that.returnClass) &&
+                Objects.deepEquals(ids, that.ids);
+    }
+
     @Override
     public int hashCode() {
-        int result = Objects.hash(super.hashCode(), returnClass);
-        if (ids != null) {
-            for (Object id : ids) {
-                result = 31 * result + Objects.hashCode(id);
-            }
-        }
-        return result;
+        return Objects.hash(super.hashCode(), returnClass, 
Arrays.hashCode(ids), isStart, onGraphComputer);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStepPlaceholder.java
index 82f27cab8c..5cef3cff1b 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStepPlaceholder.java
@@ -55,9 +55,18 @@ public final class TailLocalStepPlaceholder<S> extends 
ScalarMapStep<S, S> imple
         return clone;
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        TailLocalStepPlaceholder<?> that = (TailLocalStepPlaceholder<?>) o;
+        return Objects.equals(limit, that.limit);
+    }
+
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Objects.hashCode(this.limit);
+        return Objects.hash(super.hashCode(), limit);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStepPlaceholder.java
index cc78590b49..f3af6c9e03 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/VertexStepPlaceholder.java
@@ -116,36 +116,20 @@ public class VertexStepPlaceholder<E extends Element> 
extends FlatMapStep<Vertex
         return StringFactory.stepString(this, this.direction, 
Arrays.asList(this.edgeLabels), this.returnClass.getSimpleName().toLowerCase());
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        VertexStepPlaceholder<?> that = (VertexStepPlaceholder<?>) o;
+        return Objects.equals(sortEdgeLabels(edgeLabels), 
sortEdgeLabels(that.edgeLabels)) &&
+                direction == that.direction &&
+                Objects.equals(returnClass, that.returnClass);
+    }
+
     @Override
     public int hashCode() {
-        int result = Objects.hash(super.hashCode(), direction, returnClass);
-        // edgeLabel's order does not matter because in("x", "y") and in("y", 
"x") must be considered equal.
-        if (edgeLabels != null && edgeLabels.length > 0) {
-            final List<GValue<String>> sortedEdgeLabels = 
Arrays.stream(edgeLabels)
-                    .sorted(Comparator.nullsLast(new 
Comparator<GValue<String>>() {
-                        @Override
-                        public int compare(GValue<String> o1, GValue<String> 
o2) {
-                            // variables come before non-variables
-                            if (o1.isVariable() && !o2.isVariable()) {
-                                return -1;
-                            } else if (!o1.isVariable() && o2.isVariable()) {
-                                return 1;
-                            } else if (o1.isVariable()) {
-                                if (!o2.getName().equals(o1.getName())) {
-                                    return 
o1.getName().compareTo(o2.getName()); // compare by variable name
-                                } else {
-                                    return o1.get().compareTo(o2.get()); // 
use value as tie-breaker
-                                }
-                            } else {
-                                return o1.get().compareTo(o2.get()); // 
comparison of 2 non-variables
-                            }
-                        }
-                    })).collect(Collectors.toList());
-            for (final GValue<String> edgeLabel : sortedEdgeLabels) {
-                result = 31 * result + Objects.hashCode(edgeLabel);
-            }
-        }
-        return result;
+        return Objects.hash(super.hashCode(), sortEdgeLabels(edgeLabels), 
direction, returnClass);
     }
 
     @Override
@@ -196,4 +180,36 @@ public class VertexStepPlaceholder<E extends Element> 
extends FlatMapStep<Vertex
     public void close() throws Exception {
         closeIterator();
     }
+
+    /**
+     * Helper method for hashCode() and equals() as edgeLabel's order should 
not influence equality.
+     * in("x", "y") and in("y", "x") must be considered equal.
+     */
+    private List<GValue<String>> sortEdgeLabels(final GValue<String>[] 
gValues) {
+        if (edgeLabels == null || edgeLabels.length == 0) {
+            return List.of();
+        }
+        final List<GValue<String>> sortedEdgeLabels = Arrays.stream(edgeLabels)
+                .sorted(Comparator.nullsLast(new Comparator<GValue<String>>() {
+                    @Override
+                    public int compare(GValue<String> o1, GValue<String> o2) {
+                        // variables come before non-variables
+                        if (o1.isVariable() && !o2.isVariable()) {
+                            return -1;
+                        } else if (!o1.isVariable() && o2.isVariable()) {
+                            return 1;
+                        } else if (o1.isVariable()) {
+                            if (!o2.getName().equals(o1.getName())) {
+                                return o1.getName().compareTo(o2.getName()); 
// compare by variable name
+                            } else {
+                                return o1.get().compareTo(o2.get()); // use 
value as tie-breaker
+                            }
+                        } else {
+                            return o1.get().compareTo(o2.get()); // comparison 
of 2 non-variables
+                        }
+                    }
+                })).collect(Collectors.toList());
+
+        return sortedEdgeLabels;
+    }
 }
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepPlaceholder.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepPlaceholder.java
index 44e8d81cfd..7375ae1e11 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepPlaceholder.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/AddPropertyStepPlaceholder.java
@@ -119,10 +119,22 @@ public class AddPropertyStepPlaceholder<S extends 
Element> extends SideEffectSte
         this.getLocalChildren().forEach(this::integrateChild);
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        if (!super.equals(o)) return false;
+        AddPropertyStepPlaceholder<?> that = (AddPropertyStepPlaceholder<?>) o;
+        return Objects.equals(key, that.key) &&
+                Objects.equals(value, that.value) &&
+                cardinality == that.cardinality &&
+                Objects.equals(properties, that.properties) &&
+                Objects.equals(withConfiguration, that.withConfiguration);
+    }
+
     @Override
     public int hashCode() {
-        return super.hashCode() ^ Objects.hashCode(key) ^ 
Objects.hashCode(value) ^ Objects.hashCode(cardinality) ^
-                Objects.hashCode(properties) ^ 
Objects.hashCode(withConfiguration);
+        return Objects.hash(super.hashCode(), key, value, cardinality, 
properties, withConfiguration);
     }
 
     @Override
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
index aa839351f2..3954cb7bdb 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/Parameters.java
@@ -279,6 +279,15 @@ public class Parameters implements Cloneable, Serializable 
{
         }
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Parameters that = (Parameters) o;
+        return Objects.equals(parameters, that.parameters) && 
Objects.equals(referencedLabels, that.referencedLabels) && 
Objects.equals(traversals, that.traversals);
+    }
+
+    @Override
     public int hashCode() {
         int result = 1;
         for (final Map.Entry<Object, List<Object>> entry : 
this.parameters.entrySet()) {

Reply via email to