Corrections to include hashCode(), use of primitive short and to docs Added missing fields to hashCode() in RepeatStep, B_O_S_SE_SL_Traverser and O_OB_S_SE_SL_Traverser and implemented hashCode() for LoopsStep. Added missing tests to RepeatStepTest. Correction to documentation to make sure sample query matches given description and some formatting of traversals. Use primtive short in LabelledCounter rather than MutableShort.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/d5de5d82 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/d5de5d82 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/d5de5d82 Branch: refs/heads/TINKERPOP-1996 Commit: d5de5d8281e86ae6495024d8430d3e85b15fcf9e Parents: a80eb84 Author: GCHQResearcher1337 <[email protected]> Authored: Fri Jul 13 18:54:35 2018 +0100 Committer: GCHQResearcher1337 <[email protected]> Committed: Fri Jul 13 18:59:36 2018 +0100 ---------------------------------------------------------------------- docs/src/reference/the-traversal.asciidoc | 10 ++++++-- .../traversal/dsl/graph/GraphTraversal.java | 4 ++-- .../traversal/step/branch/RepeatStep.java | 2 ++ .../process/traversal/step/map/LoopsStep.java | 19 ++++++++++++++++ .../traverser/B_O_S_SE_SL_Traverser.java | 9 ++++---- .../traverser/O_OB_S_SE_SL_Traverser.java | 10 +++++--- .../traverser/util/LabelledCounter.java | 24 +++++++++----------- .../gremlin/structure/io/gryo/GryoVersion.java | 11 ++++----- .../traversal/step/branch/RepeatStepTest.java | 4 +++- gremlin-test/features/branch/Repeat.feature | 4 ++-- .../traversal/step/branch/RepeatTest.java | 10 ++++---- 11 files changed, 68 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/docs/src/reference/the-traversal.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc index b565bae..1fb8abd 100644 --- a/docs/src/reference/the-traversal.asciidoc +++ b/docs/src/reference/the-traversal.asciidoc @@ -2129,8 +2129,14 @@ Therefore, the traverser has seen the vertices: lop, vadas, josh, ripple, and lo [gremlin-groovy,modern] ---- -g.V(1).repeat(out("knows")).until(__.repeat(out("created")).emit(__.has("name", "lop"))) <1> -g.V(6).repeat('a', both('created')).emit(repeat('b', __.both('knows')).until(or(loops().is(2), loops('b').is(loops('a')))).hasId(2)).dedup() <2> +g.V(1). + repeat(out("knows")). + until(repeat(out("created")).emit(has("name", "lop"))) <1> +g.V(6). + repeat('a', both('created').simplePath()). + emit(repeat('b', both('knows')). + until(loops('b').as('b').where(loops('a').as('b'))). + hasId(2)).dedup() <2> ---- <1> Starting from vertex 1, keep going taking outgoing 'knows' edges until the vertex was created by 'lop'. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java index 8684bfa..0a7eb95 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java @@ -2290,7 +2290,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> { } /** - * This step is used for looping over a some traversal given some break predicate. + * This step is used for looping over a traversal given some break predicate. * * @param repeatTraversal the traversal to repeat over * @return the traversal with the appended {@link RepeatStep} @@ -2303,7 +2303,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> { } /** - * This step is used for looping over a some traversal given some break predicate. + * This step is used for looping over a traversal given some break predicate and with a specified loop name. * * @param repeatTraversal the traversal to repeat over * @param loopName The name given to the loop http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStep.java ---------------------------------------------------------------------- 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 b95f1cd..f62b22c 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 @@ -178,6 +178,8 @@ public final class RepeatStep<S> extends ComputerAwareStep<S, S> implements Trav int result = super.hashCode() ^ this.repeatTraversal.hashCode(); result ^= Boolean.hashCode(this.untilFirst); result ^= Boolean.hashCode(this.emitFirst) << 1; + if (this.loopName != null) + result ^= this.loopName.hashCode(); if (this.untilTraversal != null) result ^= this.untilTraversal.hashCode(); if (this.emitTraversal != null) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LoopsStep.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LoopsStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LoopsStep.java index e95f26e..0a9167c 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LoopsStep.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/LoopsStep.java @@ -37,4 +37,23 @@ public final class LoopsStep<S> extends MapStep<S, Integer> { protected Integer map(final Traverser.Admin<S> traverser) { return traverser.loops(this.loopName); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LoopsStep)) return false; + if (!super.equals(o)) return false; + + LoopsStep<?> loopsStep = (LoopsStep<?>) o; + + return loopName != null ? loopName.equals(loopsStep.loopName) : loopsStep.loopName == null; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (loopName != null ? loopName.hashCode() : 0); + return result; + } + } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_S_SE_SL_Traverser.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_S_SE_SL_Traverser.java index a6385a6..33c5520 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_S_SE_SL_Traverser.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_S_SE_SL_Traverser.java @@ -18,12 +18,11 @@ */ package org.apache.tinkerpop.gremlin.process.traversal.traverser; - import org.apache.tinkerpop.gremlin.process.traversal.Step; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; -import java.util.Random; +import java.util.Objects; /** * @author Marko A. Rodriguez (http://markorodriguez.com) @@ -132,11 +131,13 @@ public class B_O_S_SE_SL_Traverser<T> extends B_O_Traverser<T> { @Override public int hashCode() { - return carriesUnmergeableSack() ? System.identityHashCode(this) : (super.hashCode() ^ this.loops); + return carriesUnmergeableSack() ? System.identityHashCode(this) : (super.hashCode() ^ this.loops ^ Objects.hashCode(this.loopName)); } protected final boolean equals(final B_O_S_SE_SL_Traverser other) { - return super.equals(other) && other.loops == this.loops && !carriesUnmergeableSack(); + return super.equals(other) && other.loops == this.loops + && (this.loopName != null ? this.loopName.equals(other.loopName) : other.loopName == null) + && !carriesUnmergeableSack(); } @Override http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/O_OB_S_SE_SL_Traverser.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/O_OB_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/O_OB_S_SE_SL_Traverser.java index 6001a7b..601bcda 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/O_OB_S_SE_SL_Traverser.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/O_OB_S_SE_SL_Traverser.java @@ -23,6 +23,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSideEffects; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import java.util.Objects; + /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ @@ -154,13 +156,15 @@ public class O_OB_S_SE_SL_Traverser<T> extends O_Traverser<T> { @Override public int hashCode() { - return carriesUnmergeableSack() ? System.identityHashCode(this) : (super.hashCode() ^ this.loops); + return carriesUnmergeableSack() ? System.identityHashCode(this) : (super.hashCode() ^ this.loops ^ Objects.hashCode(this.loopName)); } protected final boolean equals(final O_OB_S_SE_SL_Traverser other) { - return super.equals(other) && other.loops == this.loops && other.future.equals(this.future) && - !carriesUnmergeableSack(); + return super.equals(other) && other.loops == this.loops && other.future.equals(this.future) + && (this.loopName != null ? this.loopName.equals(other.loopName) : other.loopName == null) + && !carriesUnmergeableSack(); } + @Override public boolean equals(final Object object) { return object instanceof O_OB_S_SE_SL_Traverser && this.equals((O_OB_S_SE_SL_Traverser) object); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/LabelledCounter.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/LabelledCounter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/LabelledCounter.java index 8be43e3..0021699 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/LabelledCounter.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/LabelledCounter.java @@ -19,8 +19,6 @@ package org.apache.tinkerpop.gremlin.process.traversal.traverser.util; -import org.apache.commons.lang.mutable.MutableShort; - import java.io.Serializable; /** @@ -29,7 +27,7 @@ import java.io.Serializable; public class LabelledCounter implements Serializable, Cloneable { private final String label; - private final MutableShort count = new MutableShort(); + private short count = 0; protected LabelledCounter() { label = ""; @@ -40,7 +38,7 @@ public class LabelledCounter implements Serializable, Cloneable { throw new NullPointerException("Label is null"); } this.label = label; - this.count.setValue(initialCount); + this.count = initialCount; } public boolean hasLabel(final String label){ @@ -48,38 +46,38 @@ public class LabelledCounter implements Serializable, Cloneable { } public int count() { - return this.count.intValue(); + return this.count; } public void increment() { - this.count.increment(); + this.count++; } @Override public Object clone() { - return new LabelledCounter(this.label, this.count.shortValue()); + return new LabelledCounter(this.label, this.count); } @Override public String toString(){ - return "Step Label: " + label + " Counter: " + count.toString(); + return "Step Label: " + this.label + " Counter: " + Short.toString(this.count); } @Override - public boolean equals(final Object o) { + public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof LabelledCounter)) return false; LabelledCounter that = (LabelledCounter) o; - if (!this.label.equals(that.label)) return false; - return this.count.equals(that.count); + if (count != that.count) return false; + return label != null ? label.equals(that.label) : that.label == null; } @Override public int hashCode() { - int result = this.label.hashCode(); - result = 31 * result + this.count.hashCode(); + int result = label != null ? label.hashCode() : 0; + result = 31 * result + (int) count; return result; } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java index 6935549..e7dfd93 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java @@ -116,7 +116,6 @@ import org.apache.tinkerpop.shaded.kryo.KryoSerializable; import org.apache.tinkerpop.shaded.kryo.serializers.JavaSerializer; import org.javatuples.Pair; import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.LabelledCounter; -import org.apache.commons.lang.mutable.MutableShort; import org.apache.commons.collections.map.ReferenceMap; import java.util.Stack; @@ -393,9 +392,8 @@ public enum GryoVersion { add(GryoTypeReg.of(LP_NL_O_OB_S_SE_SL_Traverser.class, 178)); add(GryoTypeReg.of(LP_NL_O_OB_P_S_SE_SL_Traverser.class, 179)); add(GryoTypeReg.of(LabelledCounter.class, 180)); - add(GryoTypeReg.of(MutableShort.class, 181)); - add(GryoTypeReg.of(Stack.class, 182)); - add(GryoTypeReg.of(ReferenceMap.class, 183)); // ***LAST ID*** + add(GryoTypeReg.of(Stack.class, 181)); + add(GryoTypeReg.of(ReferenceMap.class, 182)); // ***LAST ID*** // placeholder serializers for classes that don't live here in core. this will allow them to be used if @@ -584,9 +582,8 @@ public enum GryoVersion { add(GryoTypeReg.of(LP_NL_O_OB_S_SE_SL_Traverser.class, 178)); add(GryoTypeReg.of(LP_NL_O_OB_P_S_SE_SL_Traverser.class, 179)); add(GryoTypeReg.of(LabelledCounter.class, 180)); - add(GryoTypeReg.of(MutableShort.class, 181)); - add(GryoTypeReg.of(Stack.class, 182)); - add(GryoTypeReg.of(ReferenceMap.class, 183)); // ***LAST ID*** + add(GryoTypeReg.of(Stack.class, 181)); + add(GryoTypeReg.of(ReferenceMap.class, 182)); // ***LAST ID*** }}; } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStepTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStepTest.java index 6c86c27..1c6ae64 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStepTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatStepTest.java @@ -39,7 +39,9 @@ public class RepeatStepTest extends StepTest { __.repeat(out()).times(3), __.repeat(out().as("x")).times(3), __.out().emit().repeat(out()).times(3), - __.repeat(out()).until(hasLabel("x")) + __.repeat(out()).until(hasLabel("x")), + __.repeat("a", __.out()).times(3), + __.repeat(out().repeat(out()).times(1)).times(1).limit(1) ); } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-test/features/branch/Repeat.feature ---------------------------------------------------------------------- diff --git a/gremlin-test/features/branch/Repeat.feature b/gremlin-test/features/branch/Repeat.feature index b5dc6ce..33470d0 100644 --- a/gremlin-test/features/branch/Repeat.feature +++ b/gremlin-test/features/branch/Repeat.feature @@ -343,12 +343,12 @@ Scenario: g_V_repeatXa_outXknows_repeatXb_outXcreatedX_filterXloops_isX0XX_emit_ | java | | java | -Scenario: g_VX6X_repeatXa_bothXcreatedXX_emitXrepeatXb_bothXknowsXX_untilXorXloops_isX2X_loopsXbX_isXloopsXaXXXX_hasXname_vadasXX_dedup_name +Scenario: g_VX6X_repeatXa_bothXcreatedX_simplePathX_emitXrepeatXb_bothXknowsXX_untilXloopsXbX_asXb_whereXloopsXaX_asXbX_hasXname_vadasXX_dedup_name Given the modern graph And using the parameter v6Id defined as "v[peter].id" And the traversal of """ - g.V(v6Id).repeat("a", __.both("created")).emit(__.repeat("b", __.both("knows")).until(__.or(__.loops().is(2), __.loops("b").is(__.loops("a")))).has("name", "vadas")).dedup().values("name") + g.V(v6Id).repeat("a", __.both("created").simplePath()).emit(__.repeat("b", __.both("knows")).until(__.loops("b").as("b").where(__.loops("a").as("b"))).has("name", "vadas")).dedup().values("name") """ When iterated to list Then the result should be unordered http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d5de5d82/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatTest.java index a43534c..e833acf 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/RepeatTest.java @@ -120,7 +120,7 @@ public abstract class RepeatTest extends AbstractGremlinProcessTest { public abstract Traversal<Vertex, String> get_g_V_emit_repeatXa_outXknows_filterXloops_isX0XX_lang(); - public abstract Traversal<Vertex, String> get_g_VX6X_repeatXa_bothXcreatedXX_emitXrepeatXb_bothXknowsXX_untilXorXloops_isX2X_loopsXbX_isXloopsXaXXXX_hasXname_vadasXX_dedup_name(final Object v6Id); + public abstract Traversal<Vertex, String> get_g_VX6X_repeatXa_bothXcreatedX_simplePathX_emitXrepeatXb_bothXknowsXX_untilXloopsXbX_asXb_whereXloopsXaX_asXbX_hasXname_vadasXX_dedup_name(final Object v6Id); @Test @LoadGraphWith(MODERN) @@ -446,8 +446,8 @@ public abstract class RepeatTest extends AbstractGremlinProcessTest { @Test @LoadGraphWith(MODERN) - public void g_VX6X_repeatXa_bothXcreatedXX_emitXrepeatXb_bothXknowsXX_untilXorXloops_isX2X_loopsXbX_isXloopsXaXXXX_hasXname_vadasXX_dedup_name() { - final Traversal<Vertex, String> traversal = get_g_VX6X_repeatXa_bothXcreatedXX_emitXrepeatXb_bothXknowsXX_untilXorXloops_isX2X_loopsXbX_isXloopsXaXXXX_hasXname_vadasXX_dedup_name(convertToVertexId("peter")); + public void g_VX6X_repeatXa_bothXcreatedX_simplePathX_emitXrepeatXb_bothXknowsXX_untilXloopsXbX_asXb_whereXloopsXaX_asXbX_hasXname_vadasXX_dedup_name() { + final Traversal<Vertex, String> traversal = get_g_VX6X_repeatXa_bothXcreatedX_simplePathX_emitXrepeatXb_bothXknowsXX_untilXloopsXbX_asXb_whereXloopsXaX_asXbX_hasXname_vadasXX_dedup_name(convertToVertexId("peter")); printTraversalForm(traversal); assertTrue(traversal.hasNext()); String name = traversal.next(); @@ -569,8 +569,8 @@ public abstract class RepeatTest extends AbstractGremlinProcessTest { } @Override - public Traversal<Vertex, String> get_g_VX6X_repeatXa_bothXcreatedXX_emitXrepeatXb_bothXknowsXX_untilXorXloops_isX2X_loopsXbX_isXloopsXaXXXX_hasXname_vadasXX_dedup_name(final Object v6Id) { - return g.V(v6Id).repeat("a", both("created")).emit(__.repeat("b", __.both("knows")).until(__.or(loops().is(2), loops("b").is(loops("a")))).has("name", "vadas")).dedup().values("name"); + public Traversal<Vertex, String> get_g_VX6X_repeatXa_bothXcreatedX_simplePathX_emitXrepeatXb_bothXknowsXX_untilXloopsXbX_asXb_whereXloopsXaX_asXbX_hasXname_vadasXX_dedup_name(final Object v6Id) { + return g.V(v6Id).repeat("a", both("created").simplePath()).emit(__.repeat("b", __.both("knows")).until(loops("b").as("b").where(loops("a").as("b"))).has("name", "vadas")).dedup().values("name"); } @Override
