You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by dk...@apache.org on 2019/06/18 18:36:35 UTC

[tinkerpop] branch TINKERPOP-1084 updated (dae2bd0 -> 7a1df9f)

This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a change to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.


    omit dae2bd0  fixed syntax error
    omit 4c0c47b  fixed missing __
    omit 43f49df  updated upgrade docs
    omit 9fc45cf  added more tests
    omit 7d202f7  TINKERPOP-1084 Allow predicates and traversals to be used as options in `BranchStep`.
    omit d970127  TINKERPOP-1084 Allow predicates to be used as options in BranchSteps.
     add 7598199  Typo fix to tp33
     add df93fb2  Downgrade docker maven plugin given a maven incompatibility.
     add b4e3890  Consistent formatting of Tutorials list
     add 8fb2099  typo and wording fixes to tp33
     add 0431da8  Merge branch 'pr-1137' into tp33
     add 09b9409  typo fix to tp33
     add 130f058  Merge branch 'pr-1139' into tp33
     add ddac926  Added asciidoc tips/fixes to dev docs
     add 780e6cf  TINKERPOP-2237: Prevent exception when closing a session that doesn't exist
     add bcef625  Merge branch 'pr-1126' into tp33
     add 9d3265b  Fix heading in dev docs CTR
     add a9eee17  Changed Order.reverse() to use not use the deprecated enums.
     add 29f8fad  tp33 Getting Started, Minutes 6-30
     add 0d08d24  Minor re-wording for clarity in getting started tutorial CTR
     new ce46f62  TINKERPOP-1084 Allow predicates to be used as options in BranchSteps.
     new 82cfa50  TINKERPOP-1084 Allow predicates and traversals to be used as options in `BranchStep`.
     new 9ca40a6  added more tests
     new 165efa2  updated upgrade docs
     new 38f9557  fixed missing __
     new 7a1df9f  fixed syntax error

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (dae2bd0)
            \
             N -- N -- N   refs/heads/TINKERPOP-1084 (7a1df9f)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 6 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:
 CHANGELOG.asciidoc                                 |  2 +
 docs/src/dev/developer/for-committers.asciidoc     | 27 +++++++++++++
 docs/src/dev/developer/release.asciidoc            |  2 +-
 docs/src/index.asciidoc                            |  6 +--
 docs/src/reference/gremlin-applications.asciidoc   | 26 ++++++------
 docs/src/tutorials/getting-started/index.asciidoc  | 46 +++++++++++-----------
 .../tinkerpop/gremlin/process/traversal/Order.java |  4 +-
 .../server/op/session/SessionOpProcessor.java      | 12 ++----
 pom.xml                                            |  4 +-
 9 files changed, 78 insertions(+), 51 deletions(-)


[tinkerpop] 05/06: fixed missing __

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 38f955763b32e08fa000f3eca75164f0237d63e3
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Mon Jun 17 14:40:27 2019 -0700

    fixed missing __
---
 gremlin-test/features/branch/Branch.feature | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gremlin-test/features/branch/Branch.feature b/gremlin-test/features/branch/Branch.feature
index 7bb3e04..69bb54c 100644
--- a/gremlin-test/features/branch/Branch.feature
+++ b/gremlin-test/features/branch/Branch.feature
@@ -96,7 +96,7 @@ Feature: Step - branch()
     And the traversal of
       """
       g.V().hasLabel("person").
-        branch(values("age")).
+        branch(__.values("age")).
           option(P.lt(30), __.constant("young")).
           option(P.gt(30), __.constant("old")).
           option(Pick.none, __.constant("on the edge"))


[tinkerpop] 02/06: TINKERPOP-1084 Allow predicates and traversals to be used as options in `BranchStep`.

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 82cfa508c9ab902aac273a165cf90e9dee315d3c
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Tue Jun 11 07:46:51 2019 -0700

    TINKERPOP-1084 Allow predicates and traversals to be used as options in `BranchStep`.
---
 CHANGELOG.asciidoc                                 |   2 +-
 .../traversal/lambda/PredicateTraversal.java       |  68 +++++++++
 .../process/traversal/step/branch/BranchStep.java  | 163 +++++++--------------
 .../process/traversal/step/branch/ChooseStep.java  |  10 +-
 .../process/traversal/step/branch/UnionStep.java   |   2 +-
 .../process/traversal/step/ComplexTest.java        |  22 ++-
 .../tinkergraph/structure/TinkerGraphPlayTest.java |   8 +-
 7 files changed, 151 insertions(+), 124 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 226c536..557f714 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,7 +33,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Fixed bug in `MatchStep` where the correct was not properly determined.
 * Fixed bug where client/server exception mismatch when server throw StackOverflowError
 * Prevent exception when closing a session that doesn't exist
-* Allow predicates to be used as options in BranchSteps.
+* Allow predicates and traversals to be used as options in `BranchStep`.
 
 [[release-3-3-7]]
 === TinkerPop 3.3.7 (Release Date: May 28, 2019)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/PredicateTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/PredicateTraversal.java
new file mode 100644
index 0000000..603ac50
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/lambda/PredicateTraversal.java
@@ -0,0 +1,68 @@
+/*
+ * 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.process.traversal.lambda;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementException;
+
+import java.util.function.Predicate;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public final class PredicateTraversal<S> extends AbstractLambdaTraversal<S, S> {
+
+    private final Predicate predicate;
+    private S s;
+    private boolean pass;
+
+    public PredicateTraversal(final Object value) {
+        this.predicate = value instanceof Predicate ? (Predicate) value : P.eq(value);
+    }
+
+    @Override
+    public S next() {
+        if (this.pass)
+            return this.s;
+        throw FastNoSuchElementException.instance();
+    }
+
+    @Override
+    public boolean hasNext() {
+        return this.pass;
+    }
+
+    @Override
+    public void addStart(final Traverser.Admin<S> start) {
+        //noinspection unchecked
+        this.pass = this.predicate.test(this.s = start.get());
+    }
+
+    @Override
+    public String toString() {
+        return "(" + this.predicate.toString() + ")";
+    }
+
+    @Override
+    public int hashCode() {
+        return this.getClass().hashCode() ^ this.predicate.hashCode();
+    }
+}
+
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
index efc43cc..d92ce2d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
@@ -18,8 +18,10 @@
  */
 package org.apache.tinkerpop.gremlin.process.traversal.step.branch;
 
+import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.PredicateTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
 import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
@@ -30,7 +32,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.FastNoSuchElementExce
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.NumberHelper;
+import org.javatuples.Pair;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -38,10 +40,10 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -50,11 +52,11 @@ import java.util.stream.Collectors;
 public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements TraversalOptionParent<M, S, E> {
 
     protected Traversal.Admin<S, M> branchTraversal;
-    protected Map<Object, List<Traversal.Admin<S, E>>> traversalOptions = new HashMap<>();
+    protected Map<Pick, List<Traversal.Admin<S, E>>> traversalPickOptions = new HashMap<>();
+    protected List<Pair<Traversal.Admin, Traversal.Admin<S, E>>> traversalOptions = new ArrayList<>();
 
     private boolean first = true;
     private boolean hasBarrier;
-    private boolean hasPredicateOptions;
 
     public BranchStep(final Traversal.Admin traversal) {
         super(traversal);
@@ -66,13 +68,20 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
 
     @Override
     public void addGlobalChildOption(final M pickToken, final Traversal.Admin<S, E> traversalOption) {
-        final Object pickTokenKey = makePickTokenKey(pickToken);
-        this.hasPredicateOptions |= pickTokenKey instanceof PredicateOption;
-        if (this.traversalOptions.containsKey(pickTokenKey))
-            this.traversalOptions.get(pickTokenKey).add(traversalOption);
-        else
-            this.traversalOptions.put(pickTokenKey, new ArrayList<>(Collections.singletonList(traversalOption)));
-
+        if (pickToken instanceof Pick) {
+            if (this.traversalPickOptions.containsKey(pickToken))
+                this.traversalPickOptions.get(pickToken).add(traversalOption);
+            else
+                this.traversalPickOptions.put((Pick) pickToken, new ArrayList<>(Collections.singletonList(traversalOption)));
+        } else {
+            final Traversal.Admin pickOptionTraversal;
+            if (pickToken instanceof Traversal) {
+                pickOptionTraversal = ((Traversal) pickToken).asAdmin();
+            } else {
+                pickOptionTraversal = new PredicateTraversal(pickToken);
+            }
+            this.traversalOptions.add(Pair.with(pickOptionTraversal, traversalOption));
+        }
         // adding an IdentityStep acts as a placeholder when reducing barriers get in the way - see the
         // standardAlgorithm() method for more information.
         if (TraversalHelper.hasStepOfAssignableClass(ReducingBarrierStep.class, traversalOption))
@@ -91,9 +100,9 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
 
     @Override
     public List<Traversal.Admin<S, E>> getGlobalChildren() {
-        return Collections.unmodifiableList(this.traversalOptions.values().stream()
-                .flatMap(List::stream)
-                .collect(Collectors.toList()));
+        return Collections.unmodifiableList(Stream.concat(
+                this.traversalPickOptions.values().stream().flatMap(List::stream),
+                this.traversalOptions.stream().map(Pair::getValue1)).collect(Collectors.toList()));
     }
 
     @Override
@@ -113,11 +122,9 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
                 // traverser as part of the condition for using that traversal option in the output. This is necessary
                 // because barriers like fold(), max(), etc. will always return true for hasNext() even if a traverser
                 // was not seeded in applyCurrentTraverser().
-                for (final List<Traversal.Admin<S, E>> options : this.traversalOptions.values()) {
-                    for (final Traversal.Admin<S, E> option : options) {
-                        if (option.getStartStep().hasNext() && option.hasNext())
-                            return option.getEndStep();
-                    }
+                for (final Traversal.Admin<S, E> option : getGlobalChildren()) {
+                    if (option.getStartStep().hasNext() && option.hasNext())
+                        return option.getEndStep();
                 }
             }
 
@@ -144,7 +151,7 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
     private void applyCurrentTraverser(final Traverser.Admin<S> start) {
         // first get the value of the choice based on the current traverser and use that to select the right traversal
         // option to which that traverser should be routed
-        final Object choice = makePickTokenKey(TraversalUtil.apply(start, this.branchTraversal));
+        final Object choice = TraversalUtil.apply(start, this.branchTraversal);
         final List<Traversal.Admin<S, E>> branches = pickBranches(choice);
 
         // if a branch is identified, then split the traverser and add it to the start of the option so that when
@@ -153,7 +160,7 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
             branches.forEach(traversal -> traversal.addStart(start.split()));
 
         if (choice != Pick.any) {
-            final List<Traversal.Admin<S, E>> anyBranch = this.traversalOptions.get(Pick.any);
+            final List<Traversal.Admin<S, E>> anyBranch = this.traversalPickOptions.get(Pick.any);
             if (null != anyBranch)
                 anyBranch.forEach(traversal -> traversal.addStart(start.split()));
         }
@@ -163,7 +170,7 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
     protected Iterator<Traverser.Admin<E>> computerAlgorithm() {
         final List<Traverser.Admin<E>> ends = new ArrayList<>();
         final Traverser.Admin<S> start = this.starts.next();
-        final Object choice = makePickTokenKey(TraversalUtil.apply(start, this.branchTraversal));
+        final Object choice = TraversalUtil.apply(start, this.branchTraversal);
         final List<Traversal.Admin<S, E>> branches = pickBranches(choice);
         if (null != branches) {
             branches.forEach(traversal -> {
@@ -174,7 +181,7 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
             });
         }
         if (choice != Pick.any) {
-            final List<Traversal.Admin<S, E>> anyBranch = this.traversalOptions.get(Pick.any);
+            final List<Traversal.Admin<S, E>> anyBranch = this.traversalPickOptions.get(Pick.any);
             if (null != anyBranch) {
                 anyBranch.forEach(traversal -> {
                     final Traverser.Admin<E> split = (Traverser.Admin<E>) start.split();
@@ -189,34 +196,37 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
 
     private List<Traversal.Admin<S, E>> pickBranches(final Object choice) {
         final List<Traversal.Admin<S, E>> branches = new ArrayList<>();
-        if (this.hasPredicateOptions) {
-            for (final Map.Entry<Object, List<Traversal.Admin<S, E>>> e : this.traversalOptions.entrySet()) {
-                if (Objects.equals(e.getKey(), choice)) {
-                    branches.addAll(e.getValue());
-                }
+        if (choice instanceof Pick) {
+            if (this.traversalPickOptions.containsKey(choice)) {
+                branches.addAll(this.traversalPickOptions.get(choice));
             }
-        } else {
-            if (this.traversalOptions.containsKey(choice)) {
-                branches.addAll(this.traversalOptions.get(choice));
+        }
+        for (final Pair<Traversal.Admin, Traversal.Admin<S, E>> p : this.traversalOptions) {
+            if (TraversalUtil.test(choice, p.getValue0())) {
+                branches.add(p.getValue1());
             }
         }
-        return branches.isEmpty() ? this.traversalOptions.get(Pick.none) : branches;
+        return branches.isEmpty() ? this.traversalPickOptions.get(Pick.none) : branches;
     }
 
     @Override
     public BranchStep<S, E, M> clone() {
         final BranchStep<S, E, M> clone = (BranchStep<S, E, M>) super.clone();
-        clone.traversalOptions = new HashMap<>(this.traversalOptions.size());
-        for (final Map.Entry<Object, List<Traversal.Admin<S, E>>> entry : this.traversalOptions.entrySet()) {
+        clone.traversalPickOptions = new HashMap<>(this.traversalPickOptions.size());
+        clone.traversalOptions = new ArrayList<>(this.traversalOptions.size());
+        for (final Map.Entry<Pick, List<Traversal.Admin<S, E>>> entry : this.traversalPickOptions.entrySet()) {
             final List<Traversal.Admin<S, E>> traversals = entry.getValue();
             if (traversals.size() > 0) {
-                final List<Traversal.Admin<S, E>> clonedTraversals = clone.traversalOptions.compute(entry.getKey(), (k, v) ->
+                final List<Traversal.Admin<S, E>> clonedTraversals = clone.traversalPickOptions.compute(entry.getKey(), (k, v) ->
                         (v == null) ? new ArrayList<>(traversals.size()) : v);
                 for (final Traversal.Admin<S, E> traversal : traversals) {
                     clonedTraversals.add(traversal.clone());
                 }
             }
         }
+        for (final Pair<Traversal.Admin, Traversal.Admin<S, E>> pair : this.traversalOptions) {
+            clone.traversalOptions.add(Pair.with(pair.getValue0().clone(), pair.getValue1().clone()));
+        }
         clone.branchTraversal = this.branchTraversal.clone();
         return clone;
     }
@@ -225,12 +235,14 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
     public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
         super.setTraversal(parentTraversal);
         this.integrateChild(this.branchTraversal);
-        this.traversalOptions.values().stream().flatMap(List::stream).forEach(this::integrateChild);
+        this.getGlobalChildren().forEach(this::integrateChild);
     }
 
     @Override
     public int hashCode() {
         int result = super.hashCode();
+        if (this.traversalPickOptions != null)
+            result ^= this.traversalPickOptions.hashCode();
         if (this.traversalOptions != null)
             result ^= this.traversalOptions.hashCode();
         if (this.branchTraversal != null)
@@ -240,7 +252,10 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
 
     @Override
     public String toString() {
-        return StringFactory.stepString(this, this.branchTraversal, this.traversalOptions);
+        final List<Pair> combinedOptions = Stream.concat(
+                this.traversalPickOptions.entrySet().stream().map(e -> Pair.with(e.getKey(), e.getValue())),
+                this.traversalOptions.stream()).collect(Collectors.toList());
+        return StringFactory.stepString(this, this.branchTraversal, combinedOptions);
     }
 
     @Override
@@ -249,78 +264,4 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
         this.getGlobalChildren().forEach(Traversal.Admin::reset);
         this.first = true;
     }
-
-    /**
-     * Converts numbers into {@link NumberOption} and predicates into {@link PredicateOption}.
-     */
-    private static Object makePickTokenKey(final Object o) {
-        return
-                o instanceof Number ? new NumberOption((Number) o) :
-                o instanceof Predicate ? new PredicateOption((Predicate) o) : o;
-    }
-
-    /**
-     * Wraps a single number and overrides equals/hashCode/compareTo in order to ignore the numeric data type.
-     */
-    private static class NumberOption implements Comparable<Number> {
-
-        final Number number;
-
-        NumberOption(final Number number) {
-            this.number = number;
-        }
-
-        @Override
-        public boolean equals(final Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            final NumberOption other = (NumberOption) o;
-            return 0 == NumberHelper.compare(number, other.number);
-        }
-
-        @Override
-        public int hashCode() {
-            return number.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return number.toString();
-        }
-
-        @Override
-        public int compareTo(final Number other) {
-            return NumberHelper.compare(this.number, other);
-        }
-    }
-
-    /**
-     * Wraps a single predicate and overrides equals/hashCode so that the predicate can be matched against a concrete value.
-     */
-    private static class PredicateOption {
-
-        final Predicate predicate;
-
-        PredicateOption(final Predicate predicate) {
-            this.predicate = predicate;
-        }
-
-        @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass", "unchecked"})
-        @Override
-        public boolean equals(final Object o) {
-            if (o instanceof PredicateOption)
-                return ((PredicateOption) o).predicate.equals(predicate);
-            return predicate.test(o);
-        }
-
-        @Override
-        public int hashCode() {
-            return 0;
-        }
-
-        @Override
-        public String toString() {
-            return predicate.toString();
-        }
-    }
 }
\ No newline at end of file
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/ChooseStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/ChooseStep.java
index e699f22..a804d8f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/ChooseStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/ChooseStep.java
@@ -42,10 +42,12 @@ public final class ChooseStep<S, E, M> extends BranchStep<S, E, M> {
 
     @Override
     public void addGlobalChildOption(final M pickToken, final Traversal.Admin<S, E> traversalOption) {
-        if (Pick.any.equals(pickToken))
-            throw new IllegalArgumentException("Choose step can not have an any-option as only one option per traverser is allowed");
-        if (this.traversalOptions.containsKey(pickToken))
-            throw new IllegalArgumentException("Choose step can only have one traversal per pick token: " + pickToken);
+        if (pickToken instanceof Pick) {
+            if (Pick.any.equals(pickToken))
+                throw new IllegalArgumentException("Choose step can not have an any-option as only one option per traverser is allowed");
+            if (this.traversalPickOptions.containsKey(pickToken))
+                throw new IllegalArgumentException("Choose step can only have one traversal per pick token: " + pickToken);
+        }
         super.addGlobalChildOption(pickToken, traversalOption);
     }
 }
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/UnionStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/UnionStep.java
index 85f3645..de70479 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/UnionStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/UnionStep.java
@@ -47,6 +47,6 @@ public final class UnionStep<S, E> extends BranchStep<S, E, TraversalOptionParen
 
     @Override
     public String toString() {
-        return StringFactory.stepString(this, this.traversalOptions.getOrDefault(Pick.any, Collections.emptyList()));
+        return StringFactory.stepString(this, this.traversalPickOptions.getOrDefault(Pick.any, Collections.emptyList()));
     }
 }
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java
index a3bb1cd..0110d44 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java
@@ -51,7 +51,19 @@ import static org.apache.tinkerpop.gremlin.process.traversal.Pop.all;
 import static org.apache.tinkerpop.gremlin.process.traversal.Pop.first;
 import static org.apache.tinkerpop.gremlin.process.traversal.Pop.last;
 import static org.apache.tinkerpop.gremlin.process.traversal.Scope.local;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.branch;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.constant;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.count;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.group;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.project;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.unfold;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.where;
 import static org.apache.tinkerpop.gremlin.structure.Column.keys;
 import static org.apache.tinkerpop.gremlin.structure.Column.values;
 import static org.junit.Assert.assertEquals;
@@ -252,9 +264,10 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
         assertTrue(map.get("vadas").contains("pretty young"));
         assertTrue(map.get("vadas").contains("younger than peter"));
         assertTrue(map.containsKey("josh"));
-        assertEquals(2, map.get("josh").size());
+        assertEquals(3, map.get("josh").size());
         assertTrue(map.get("josh").contains("younger than peter"));
         assertTrue(map.get("josh").contains("pretty old"));
+        assertTrue(map.get("josh").contains("looks like josh"));
         assertTrue(map.containsKey("peter"));
         assertEquals(1, map.get("peter").size());
         assertTrue(map.get("peter").contains("pretty old"));
@@ -282,7 +295,7 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
         public Traversal<Vertex, Map<String, Map<String, Map<String, Object>>>> getCoworkerSummary() {
             return g.V().hasLabel("person").filter(outE("created")).aggregate("p").as("p1").values("name").as("p1n")
                     .select("p").unfold().where(neq("p1")).as("p2").values("name").as("p2n").select("p2")
-                    .out("created").choose(in("created").where(eq("p1")), __.values("name"), constant(emptyList()))
+                    .out("created").choose(in("created").where(eq("p1")), values("name"), constant(emptyList()))
                     .<String, Map<String, Map<String, Object>>>group().by(select("p1n")).
                             by(group().by(select("p2n")).
                                     by(unfold().fold().project("numCoCreated", "coCreated").by(count(local)).by()));
@@ -346,8 +359,9 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
             return g.V().hasLabel("person")
                     .<String, List<String>> group()
                         .by("name")
-                        .by(branch(__.values("age"))
+                        .by(branch(values("age"))
                                 .option(29, constant("almost old"))
+                                .option(__.is(32), constant("looks like josh"))
                                 .option(lt(29), constant("pretty young"))
                                 .option(lt(35), constant("younger than peter"))
                                 .option(gte(30), constant("pretty old")).fold());
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 3b241bc..3216803 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
@@ -130,16 +130,18 @@ public class TinkerGraphPlayTest {
     public void testPlayDK() throws Exception {
 
         GraphTraversalSource g = TinkerFactory.createModern().traversal();
-        g./*withComputer().*/V().hasLabel("person")
+        System.out.println(g./*withComputer().*/V().hasLabel("person")
                 .project("name", "age", "comments")
                     .by("name")
                     .by("age")
                     .by(branch(values("age"))
+                            .option(TraversalOptionParent.Pick.any, constant("foo"))
                             .option(29, constant("almost old"))
+                            .option(__.is(32), constant("looks like josh"))
                             .option(lt(29), constant("pretty young"))
                             .option(lt(35), constant("younger than peter"))
-                            .option(gte(30), constant("pretty old")).fold())
-                .forEachRemaining(System.out::println);
+                            .option(gte(30), constant("pretty old")).fold()).explain());
+                //.forEachRemaining(System.out::println);
     }
 
     @Test


[tinkerpop] 04/06: updated upgrade docs

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 165efa250ad589e2690601c560a8f69eafcfbb0c
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Mon Jun 17 14:37:42 2019 -0700

    updated upgrade docs
---
 docs/src/upgrade/release-3.3.x.asciidoc | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/docs/src/upgrade/release-3.3.x.asciidoc b/docs/src/upgrade/release-3.3.x.asciidoc
index 51da497..d0fdfb4 100644
--- a/docs/src/upgrade/release-3.3.x.asciidoc
+++ b/docs/src/upgrade/release-3.3.x.asciidoc
@@ -27,6 +27,36 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 Please see the link:https://github.com/apache/tinkerpop/blob/3.3.8/CHANGELOG.asciidoc#release-3-3-8[changelog] for a complete list of all the modifications that are part of this release.
 
+== Upgrading for Users
+
+==== Branch Steps accept Predicates and Traversals
+
+Prior to this version, branch steps (in particular `BranchStep` and `ChooseStep`) could only handle constant values and `Pick` tokens. Starting in this version, these steps will also accept
+predicates and traversals as show in the example below.
+
+[source,text]
+----
+gremlin> g = TinkerFactory.createModern().traversal()
+==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
+gremlin> g.V().hasLabel("person").
+......1>   group().
+......2>     by("name").
+......3>     by(branch(values("age")).
+......4>          option(29, constant("almost old")).
+......5>          option(__.is(32), constant("looks like josh")).
+......6>          option(lt(29), constant("pretty young")).
+......7>          option(lt(35), constant("younger than peter")).
+......8>          option(gte(30), constant("pretty old")).
+......9>          option(none, constant("mysterious")).fold()).
+.....10>   unfold()
+==>peter=[pretty old]
+==>vadas=[pretty young, younger than peter]
+==>josh=[looks like josh, younger than peter, pretty old]
+==>marko=[almost old, younger than peter]
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1084[TINKERPOP-1084]
+
 
 == TinkerPop 3.3.7
 


[tinkerpop] 01/06: TINKERPOP-1084 Allow predicates to be used as options in BranchSteps.

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit ce46f623b42af72d5fe3ad930655ebdc8142bcf5
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Mon Jun 10 12:45:16 2019 -0700

    TINKERPOP-1084 Allow predicates to be used as options in BranchSteps.
---
 CHANGELOG.asciidoc                                 |   1 +
 .../process/traversal/step/branch/BranchStep.java  | 102 ++++++++++++++++-----
 .../process/traversal/step/ComplexTest.java        |  58 +++++++++---
 .../tinkergraph/structure/TinkerGraphPlayTest.java |  22 +++--
 4 files changed, 141 insertions(+), 42 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index e60b668..226c536 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,6 +33,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Fixed bug in `MatchStep` where the correct was not properly determined.
 * Fixed bug where client/server exception mismatch when server throw StackOverflowError
 * Prevent exception when closing a session that doesn't exist
+* Allow predicates to be used as options in BranchSteps.
 
 [[release-3-3-7]]
 === TinkerPop 3.3.7 (Release Date: May 28, 2019)
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
index e35d51e..efc43cc 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
@@ -38,18 +38,23 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @author Daniel Kuppitz (http://gremlin.guru)
  */
 public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements TraversalOptionParent<M, S, E> {
 
     protected Traversal.Admin<S, M> branchTraversal;
     protected Map<Object, List<Traversal.Admin<S, E>>> traversalOptions = new HashMap<>();
+
     private boolean first = true;
-    private boolean hasBarrier = false;
+    private boolean hasBarrier;
+    private boolean hasPredicateOptions;
 
     public BranchStep(final Traversal.Admin traversal) {
         super(traversal);
@@ -61,7 +66,8 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
 
     @Override
     public void addGlobalChildOption(final M pickToken, final Traversal.Admin<S, E> traversalOption) {
-        final Object pickTokenKey = PickTokenKey.make(pickToken);
+        final Object pickTokenKey = makePickTokenKey(pickToken);
+        this.hasPredicateOptions |= pickTokenKey instanceof PredicateOption;
         if (this.traversalOptions.containsKey(pickTokenKey))
             this.traversalOptions.get(pickTokenKey).add(traversalOption);
         else
@@ -138,14 +144,13 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
     private void applyCurrentTraverser(final Traverser.Admin<S> start) {
         // first get the value of the choice based on the current traverser and use that to select the right traversal
         // option to which that traverser should be routed
-        final Object choice = PickTokenKey.make(TraversalUtil.apply(start, this.branchTraversal));
-        final List<Traversal.Admin<S, E>> branch = this.traversalOptions.containsKey(choice) ?
-                this.traversalOptions.get(choice) : this.traversalOptions.get(Pick.none);
+        final Object choice = makePickTokenKey(TraversalUtil.apply(start, this.branchTraversal));
+        final List<Traversal.Admin<S, E>> branches = pickBranches(choice);
 
         // if a branch is identified, then split the traverser and add it to the start of the option so that when
         // that option is iterated (in the calling method) that value can be applied.
-        if (null != branch)
-            branch.forEach(traversal -> traversal.addStart(start.split()));
+        if (null != branches)
+            branches.forEach(traversal -> traversal.addStart(start.split()));
 
         if (choice != Pick.any) {
             final List<Traversal.Admin<S, E>> anyBranch = this.traversalOptions.get(Pick.any);
@@ -158,10 +163,10 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
     protected Iterator<Traverser.Admin<E>> computerAlgorithm() {
         final List<Traverser.Admin<E>> ends = new ArrayList<>();
         final Traverser.Admin<S> start = this.starts.next();
-        final Object choice = PickTokenKey.make(TraversalUtil.apply(start, this.branchTraversal));
-        final List<Traversal.Admin<S, E>> branch = this.traversalOptions.containsKey(choice) ? this.traversalOptions.get(choice) : this.traversalOptions.get(Pick.none);
-        if (null != branch) {
-            branch.forEach(traversal -> {
+        final Object choice = makePickTokenKey(TraversalUtil.apply(start, this.branchTraversal));
+        final List<Traversal.Admin<S, E>> branches = pickBranches(choice);
+        if (null != branches) {
+            branches.forEach(traversal -> {
                 final Traverser.Admin<E> split = (Traverser.Admin<E>) start.split();
                 split.setStepId(traversal.getStartStep().getId());
                 //split.addLabels(this.labels);
@@ -182,6 +187,22 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
         return ends.iterator();
     }
 
+    private List<Traversal.Admin<S, E>> pickBranches(final Object choice) {
+        final List<Traversal.Admin<S, E>> branches = new ArrayList<>();
+        if (this.hasPredicateOptions) {
+            for (final Map.Entry<Object, List<Traversal.Admin<S, E>>> e : this.traversalOptions.entrySet()) {
+                if (Objects.equals(e.getKey(), choice)) {
+                    branches.addAll(e.getValue());
+                }
+            }
+        } else {
+            if (this.traversalOptions.containsKey(choice)) {
+                branches.addAll(this.traversalOptions.get(choice));
+            }
+        }
+        return branches.isEmpty() ? this.traversalOptions.get(Pick.none) : branches;
+    }
+
     @Override
     public BranchStep<S, E, M> clone() {
         final BranchStep<S, E, M> clone = (BranchStep<S, E, M>) super.clone();
@@ -230,26 +251,30 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
     }
 
     /**
-     * PickTokenKey is basically a wrapper for numbers that are used as a PickToken. This is
-     * required in order to treat equal numbers of different data types as a match.
+     * Converts numbers into {@link NumberOption} and predicates into {@link PredicateOption}.
+     */
+    private static Object makePickTokenKey(final Object o) {
+        return
+                o instanceof Number ? new NumberOption((Number) o) :
+                o instanceof Predicate ? new PredicateOption((Predicate) o) : o;
+    }
+
+    /**
+     * Wraps a single number and overrides equals/hashCode/compareTo in order to ignore the numeric data type.
      */
-    private static class PickTokenKey {
+    private static class NumberOption implements Comparable<Number> {
 
         final Number number;
 
-        private PickTokenKey(final Number number) {
+        NumberOption(final Number number) {
             this.number = number;
         }
 
-        static Object make(final Object value) {
-            return value instanceof Number ? new PickTokenKey((Number) value) : value;
-        }
-
         @Override
         public boolean equals(final Object o) {
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
-            final PickTokenKey other = (PickTokenKey) o;
+            final NumberOption other = (NumberOption) o;
             return 0 == NumberHelper.compare(number, other.number);
         }
 
@@ -262,5 +287,40 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
         public String toString() {
             return number.toString();
         }
+
+        @Override
+        public int compareTo(final Number other) {
+            return NumberHelper.compare(this.number, other);
+        }
+    }
+
+    /**
+     * Wraps a single predicate and overrides equals/hashCode so that the predicate can be matched against a concrete value.
+     */
+    private static class PredicateOption {
+
+        final Predicate predicate;
+
+        PredicateOption(final Predicate predicate) {
+            this.predicate = predicate;
+        }
+
+        @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass", "unchecked"})
+        @Override
+        public boolean equals(final Object o) {
+            if (o instanceof PredicateOption)
+                return ((PredicateOption) o).predicate.equals(predicate);
+            return predicate.test(o);
+        }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
+
+        @Override
+        public String toString() {
+            return predicate.toString();
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java
index 75dd0f5..a3bb1cd 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/ComplexTest.java
@@ -44,24 +44,14 @@ import java.util.Map;
 import static java.util.Collections.emptyList;
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
 import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.gte;
 import static org.apache.tinkerpop.gremlin.process.traversal.P.lt;
 import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
 import static org.apache.tinkerpop.gremlin.process.traversal.Pop.all;
 import static org.apache.tinkerpop.gremlin.process.traversal.Pop.first;
 import static org.apache.tinkerpop.gremlin.process.traversal.Pop.last;
 import static org.apache.tinkerpop.gremlin.process.traversal.Scope.local;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.constant;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.count;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.group;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.project;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.unfold;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.where;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
 import static org.apache.tinkerpop.gremlin.structure.Column.keys;
 import static org.apache.tinkerpop.gremlin.structure.Column.values;
 import static org.junit.Assert.assertEquals;
@@ -86,6 +76,8 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Map<String, List<String>>> getPlaylistPaths();
 
+    public abstract Traversal<Vertex, Map<String, List<String>>> getAgeComments();
+
     /**
      * Checks the result of both coworkerSummary tests, which is expected to look as follows:
      * <p>
@@ -243,6 +235,31 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
         assertTrue(map.get("artists").contains("Grateful_Dead"));
     }
 
+    @Test
+    @LoadGraphWith(LoadGraphWith.GraphData.MODERN)
+    public void ageComments() {
+        final Traversal<Vertex, Map<String, List<String>>> traversal = getAgeComments();
+        printTraversalForm(traversal);
+        assertTrue(traversal.hasNext());
+        Map<String, List<String>> map = traversal.next();
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey("marko"));
+        assertEquals(2, map.get("marko").size());
+        assertTrue(map.get("marko").contains("almost old"));
+        assertTrue(map.get("marko").contains("younger than peter"));
+        assertTrue(map.containsKey("vadas"));
+        assertEquals(2, map.get("vadas").size());
+        assertTrue(map.get("vadas").contains("pretty young"));
+        assertTrue(map.get("vadas").contains("younger than peter"));
+        assertTrue(map.containsKey("josh"));
+        assertEquals(2, map.get("josh").size());
+        assertTrue(map.get("josh").contains("younger than peter"));
+        assertTrue(map.get("josh").contains("pretty old"));
+        assertTrue(map.containsKey("peter"));
+        assertEquals(1, map.get("peter").size());
+        assertTrue(map.get("peter").contains("pretty old"));
+    }
+
     public static class Traversals extends ComplexTest {
 
         @Override
@@ -265,7 +282,7 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
         public Traversal<Vertex, Map<String, Map<String, Map<String, Object>>>> getCoworkerSummary() {
             return g.V().hasLabel("person").filter(outE("created")).aggregate("p").as("p1").values("name").as("p1n")
                     .select("p").unfold().where(neq("p1")).as("p2").values("name").as("p2n").select("p2")
-                    .out("created").choose(in("created").where(eq("p1")), values("name"), constant(emptyList()))
+                    .out("created").choose(in("created").where(eq("p1")), __.values("name"), constant(emptyList()))
                     .<String, Map<String, Map<String, Object>>>group().by(select("p1n")).
                             by(group().by(select("p2n")).
                                     by(unfold().fold().project("numCoCreated", "coCreated").by(count(local)).by()));
@@ -323,6 +340,17 @@ public abstract class ComplexTest extends AbstractGremlinProcessTest {
                     by("name").
                     by(__.coalesce(out("sungBy", "writtenBy").dedup().values("name"), constant("Unknown")).fold());
         }
-    }
-}
 
+        @Override
+        public Traversal<Vertex, Map<String, List<String>>> getAgeComments() {
+            return g.V().hasLabel("person")
+                    .<String, List<String>> group()
+                        .by("name")
+                        .by(branch(__.values("age"))
+                                .option(29, constant("almost old"))
+                                .option(lt(29), constant("pretty young"))
+                                .option(lt(35), constant("younger than peter"))
+                                .option(gte(30), constant("pretty old")).fold());
+        }
+    }
+}
\ No newline at end of file
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 d4f7d5d..3b241bc 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
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 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.TraversalOptionParent;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.EarlyLimitStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathRetractionStrategy;
 import org.apache.tinkerpop.gremlin.structure.*;
@@ -45,6 +46,10 @@ 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.between;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.gt;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.gte;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.lt;
 import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
 
@@ -124,12 +129,17 @@ public class TinkerGraphPlayTest {
     @Ignore
     public void testPlayDK() throws Exception {
 
-        final GraphTraversalSource g = TinkerFactory.createModern().traversal();
-        g.V().match(
-                __.as("b").out("created").as("c"),
-                __.as("a").hasLabel("person"),
-                __.as("b").hasLabel("person"),
-                __.as("a").out("knows").as("b")).forEachRemaining(System.out::println);
+        GraphTraversalSource g = TinkerFactory.createModern().traversal();
+        g./*withComputer().*/V().hasLabel("person")
+                .project("name", "age", "comments")
+                    .by("name")
+                    .by("age")
+                    .by(branch(values("age"))
+                            .option(29, constant("almost old"))
+                            .option(lt(29), constant("pretty young"))
+                            .option(lt(35), constant("younger than peter"))
+                            .option(gte(30), constant("pretty old")).fold())
+                .forEachRemaining(System.out::println);
     }
 
     @Test


[tinkerpop] 03/06: added more tests

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 9ca40a6b17bd8f5e0deab15cf114ff3fac2fdb36
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Mon Jun 17 14:24:46 2019 -0700

    added more tests
---
 gremlin-test/features/branch/Branch.feature        | 36 ++++++++++++++++-
 .../process/traversal/step/branch/BranchTest.java  | 47 ++++++++++++++++++++++
 2 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/gremlin-test/features/branch/Branch.feature b/gremlin-test/features/branch/Branch.feature
index 6ee261f..7bb3e04 100644
--- a/gremlin-test/features/branch/Branch.feature
+++ b/gremlin-test/features/branch/Branch.feature
@@ -89,4 +89,38 @@ Feature: Step - branch()
       | person |
       | person |
       | software |
-      | software |
\ No newline at end of file
+      | software |
+
+  Scenario: g_V_branchXageX_optionXltX30X__youngX_optionXgtX30X__oldX_optionXnone__on_the_edgeX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().hasLabel("person").
+        branch(values("age")).
+          option(P.lt(30), __.constant("young")).
+          option(P.gt(30), __.constant("old")).
+          option(Pick.none, __.constant("on the edge"))
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | young |
+      | young |
+      | old |
+      | old |
+
+  Scenario: g_V_branchXidentityX_optionXhasLabelXsoftwareX__inXcreatedX_name_order_foldX_optionXhasXname_vadasX__ageX_optionXneqX123X__bothE_countX
+    Given the modern graph
+    And the traversal of
+      """
+      g.V().
+        branch(__.identity()).
+          option(__.hasLabel("software"), __.in("created").values("name").order().fold()).
+          option(__.has("name","vadas"), __.values("age")).
+          option(P.neq(123), __.bothE().count())
+      """
+    When iterated to list
+    Then the result should be unordered
+      | l[josh,josh,marko,peter] |
+      | d[27].i |
+      | d[12].l |
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchTest.java
index 44a63bd..ed4b2e7 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchTest.java
@@ -29,9 +29,19 @@ import org.junit.runner.RunWith;
 import java.util.Arrays;
 
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.gt;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.lt;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.bothE;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.constant;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasLabel;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.identity;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.label;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
 import static org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent.Pick.any;
+import static org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent.Pick.none;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -45,6 +55,10 @@ public abstract class BranchTest extends AbstractGremlinProcessTest {
 
     public abstract Traversal<Vertex, Object> get_g_V_branchXlabel_isXpersonX_countX_optionX1__ageX_optionX0__langX_optionX0__nameX_optionXany__labelX();
 
+    public abstract Traversal<Vertex, Object> get_g_V_branchXageX_optionXltX30X__youngX_optionXgtX30X__oldX_optionXnone__on_the_edgeX();
+
+    public abstract Traversal<Vertex, Object> get_g_V_branchXidentityX_optionXhasLabelXsoftwareX__inXcreatedX_name_order_foldX_optionXhasXname_vadasX__ageX_optionXneqX123X__bothE_countX();
+
     @Test
     @LoadGraphWith(MODERN)
     public void g_V_branchXlabel_eq_person__a_bX_optionXa__ageX_optionXb__langX_optionXb__nameX() {
@@ -69,6 +83,22 @@ public abstract class BranchTest extends AbstractGremlinProcessTest {
         checkResults(Arrays.asList("java", "java", "lop", "ripple", 29, 27, 32, 35, "person", "person", "person", "person", "software", "software"), traversal);
     }
 
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_branchXageX_optionXltX30X__youngX_optionXgtX30X__oldX_optionXnone__on_the_edgeX() {
+        final Traversal<Vertex, Object> traversal = get_g_V_branchXageX_optionXltX30X__youngX_optionXgtX30X__oldX_optionXnone__on_the_edgeX();
+        printTraversalForm(traversal);
+        checkResults(Arrays.asList("young", "young", "old", "old"), traversal);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_branchXidentityX_optionXhasLabelXsoftwareX__inXcreatedX_name_order_foldX_optionXhasXname_vadasX__ageX_optionXneqX123X__bothE_countX() {
+        final Traversal<Vertex, Object> traversal = get_g_V_branchXidentityX_optionXhasLabelXsoftwareX__inXcreatedX_name_order_foldX_optionXhasXname_vadasX__ageX_optionXneqX123X__bothE_countX();
+        printTraversalForm(traversal);
+        checkResults(Arrays.asList(Arrays.asList("josh", "josh", "marko", "peter"), 27, 12L), traversal);
+    }
+
     public static class Traversals extends BranchTest {
 
         @Override
@@ -95,5 +125,22 @@ public abstract class BranchTest extends AbstractGremlinProcessTest {
                     .option(0L, values("name"))
                     .option(any, label());
         }
+
+        @Override
+        public Traversal<Vertex, Object> get_g_V_branchXageX_optionXltX30X__youngX_optionXgtX30X__oldX_optionXnone__on_the_edgeX() {
+            return g.V().hasLabel("person")
+                    .branch(values("age"))
+                    .option(lt(30), constant("young"))
+                    .option(gt(30), constant("old"))
+                    .option(none, constant("on the edge"));
+        }
+
+        @Override
+        public Traversal<Vertex, Object> get_g_V_branchXidentityX_optionXhasLabelXsoftwareX__inXcreatedX_name_order_foldX_optionXhasXname_vadasX__ageX_optionXneqX123X__bothE_countX() {
+            return g.V().branch(identity())
+                    .option(hasLabel("software"), in("created").values("name").order().fold())
+                    .option(has("name","vadas"), values("age"))
+                    .option(neq(123), bothE().count());
+        }
     }
 }
\ No newline at end of file


[tinkerpop] 06/06: fixed syntax error

Posted by dk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dkuppitz pushed a commit to branch TINKERPOP-1084
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 7a1df9fde753d7d71222da455fa022a47383e24c
Author: Daniel Kuppitz <da...@hotmail.com>
AuthorDate: Tue Jun 18 09:26:51 2019 -0700

    fixed syntax error
---
 gremlin-test/features/branch/Branch.feature | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gremlin-test/features/branch/Branch.feature b/gremlin-test/features/branch/Branch.feature
index 69bb54c..e160fc8 100644
--- a/gremlin-test/features/branch/Branch.feature
+++ b/gremlin-test/features/branch/Branch.feature
@@ -121,6 +121,7 @@ Feature: Step - branch()
       """
     When iterated to list
     Then the result should be unordered
+      | result |
       | l[josh,josh,marko,peter] |
       | d[27].i |
       | d[12].l |