You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2015/06/25 00:31:39 UTC

incubator-tinkerpop git commit: added a new test case for MatchStep using dedup(a, b). Added a new ComputerVerificationStrategy realization as dedup(a, b) is no bueno as the last step of a computer traversal (for now). Updated the traversal docs with a ded

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master d16e07f52 -> e9d503a57


added a new test case for MatchStep using dedup(a,b). Added a new ComputerVerificationStrategy realization as dedup(a,b) is no bueno as the last step of a computer traversal (for now). Updated the traversal docs with a dedup() example in DedupStep and MatchStep sections.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/e9d503a5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/e9d503a5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/e9d503a5

Branch: refs/heads/master
Commit: e9d503a570d9520d3058a2a287296790cfcdd253
Parents: d16e07f
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Jun 24 16:31:24 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Jun 24 16:31:32 2015 -0600

----------------------------------------------------------------------
 docs/src/the-traversal.asciidoc                 | 16 ++++++-
 .../process/traversal/step/map/MatchStep.java   |  4 ++
 .../optimization/MatchPredicateStrategy.java    |  2 +-
 .../ComputerVerificationStrategy.java           |  2 +
 .../traversal/step/map/GroovyMatchTest.groovy   | 11 ++++-
 .../process/traversal/step/map/MatchTest.java   | 50 +++++++++++++++++---
 .../neo4j/process/NativeNeo4jCypherTest.java    | 11 ++++-
 7 files changed, 84 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/docs/src/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/the-traversal.asciidoc b/docs/src/the-traversal.asciidoc
index 007e9bf..06d54a5 100644
--- a/docs/src/the-traversal.asciidoc
+++ b/docs/src/the-traversal.asciidoc
@@ -476,6 +476,16 @@ g.V().valueMap(true, 'name')
 g.V().dedup().by(label).values('name')
 ----
 
+Finally, if `dedup()` is provided an array of strings, then it will ensure that the de-duplication is not with respect to the current traverser object, but to the path history of the traverser.
+
+[gremlin-groovy,modern]
+----
+g.V().as('a').out('created').as('b').in('created').as('c').select()
+g.V().as('a').out('created').as('b').in('created').as('c').dedup('a','b').select() <1>
+----
+
+<1> If the current `a` and `b` combination has been seen previously, then filter the traverser.
+
 [[drop-step]]
 Drop Step
 ~~~~~~~~~
@@ -809,7 +819,8 @@ g.V().as('a').out().as('b'). <1>
           __.as('a').out('knows').as('b'),
           __.as('b').in().count().as('c').and().as('c').is(gt(2))  <6>
         )
-    ).select('a','b','c').by('name').by('name').by() <7>
+    ).dedup('a','c') <7>
+    .select('a','b','c').by('name').by('name').by() <8>
 ----
 
 <1> A standard, step-labeled traversal can come prior to `match()`.
@@ -818,7 +829,8 @@ g.V().as('a').out().as('b'). <1>
 <4> It is possible to `not()` a pattern.
 <5> It is possible to nest `and()`- and `or()`-steps for conjunction matching.
 <6> Both infix and prefix conjunction notation is supported.
-<7> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c").
+<7> It is possible to "distinct" the specified label combination.
+<8> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c").
 
 [[using-where-with-match]]
 Using Where with Match

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
index 7582c32..67ffbe1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStep.java
@@ -253,6 +253,10 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
         }
     }
 
+    public boolean isDeduping() {
+        return this.dedupLabels != null;
+    }
+
     private boolean isDuplicate(final Traverser<S> traverser) {
         if (null == this.dedups)
             return false;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
index fb8c69d..c1ea7ed 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/MatchPredicateStrategy.java
@@ -79,7 +79,7 @@ public final class MatchPredicateStrategy extends AbstractTraversalStrategy<Trav
                     traversal.removeStep(nextStep);
                     matchStep.addGlobalChild(new DefaultTraversal<>().addStep(nextStep));
                     nextStep = matchStep.getNextStep();
-                } else if (nextStep instanceof DedupGlobalStep && !((DedupGlobalStep) nextStep).getScopeKeys().isEmpty() && ((DedupGlobalStep) nextStep).getLocalChildren().isEmpty()) {
+                } else if (nextStep instanceof DedupGlobalStep && !((DedupGlobalStep) nextStep).getScopeKeys().isEmpty() && ((DedupGlobalStep) nextStep).getLocalChildren().isEmpty() && !traversal.getEngine().isComputer()) {
                     traversal.removeStep(nextStep);
                     matchStep.setDedupLabels(((DedupGlobalStep<?>) nextStep).getScopeKeys());
                     nextStep = matchStep.getNextStep();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
index 0fd0e82..b610215 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/ComputerVerificationStrategy.java
@@ -90,6 +90,8 @@ public final class ComputerVerificationStrategy extends AbstractTraversalStrateg
             ///
             if (endStep instanceof RangeGlobalStep || endStep instanceof TailGlobalStep || endStep instanceof DedupGlobalStep)
                 ((Bypassing) endStep).setBypass(true);
+            if (endStep instanceof DedupGlobalStep && !((DedupGlobalStep) endStep).getScopeKeys().isEmpty())
+                throw new ComputerVerificationException("Path history de-duplication is not possible in GraphComputer:" + endStep, traversal);
         }
 
         for (final Step<?, ?> step : traversal.getSteps()) {

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
index d4c6da0..d91569e 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroovyMatchTest.groovy
@@ -317,12 +317,21 @@ public abstract class GroovyMatchTest {
         }
 
         @Override
-        public Traversal<Vertex, Map<String, Object>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX() {
+        public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX() {
             TraversalScriptHelper.compute("""
              g.V.match('a',
                     __.as('a').both.as('b'),
                     __.as('b').both.as('c')).dedup('a','b')
             """, g)
         }
+
+        @Override
+        public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX_byXlabelX() {
+            TraversalScriptHelper.compute("""
+             g.V.match('a',
+                    __.as('a').both.as('b'),
+                    __.as('b').both.as('c')).dedup('a','b').by(label)
+            """, g)
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
index 989c855..7fe0164 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchTest.java
@@ -34,8 +34,10 @@ import org.junit.runner.RunWith;
 
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.GRATEFUL;
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
@@ -125,8 +127,11 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
     // uses 'out of order' conjunction nested where()
     public abstract Traversal<Vertex, Map<String, Object>> get_g_V_matchXa__whereXandXa_created_b__b_0created_count_isXeqX3XXXX__a_both_b__whereXb_inXX();
 
-    // testing distinct key values
-    public abstract Traversal<Vertex, Map<String, Object>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX();
+    // distinct values
+    public abstract Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX();
+
+    // distinct values with by()-modulation
+    public abstract Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX_byXlabelX();
 
     @Test
     @LoadGraphWith(MODERN)
@@ -416,9 +421,35 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
     @Test
     @LoadGraphWith(MODERN)
     public void g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX() {
-        final Traversal<Vertex, Map<String, Object>> traversal = get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX();
+        final Traversal<Vertex, Map<String, Vertex>> traversal = get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX();
         printTraversalForm(traversal);
-        assertEquals(12, traversal.toList().size());
+        int counter = 0;
+        final Set<List<Vertex>> results = new HashSet<>();
+        while (traversal.hasNext()) {
+            final Map<String, Vertex> map = traversal.next();
+            assertEquals(3, map.size());
+            assertTrue(results.add(Arrays.asList(map.get("a"), map.get("b"))));
+            counter++;
+        }
+        assertEquals(12, counter);
+        assertEquals(results.size(), counter);
+    }
+
+    @Test
+    @LoadGraphWith(MODERN)
+    public void g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX_byXlabelX() {
+        final Traversal<Vertex, Map<String, Vertex>> traversal = get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX_byXlabelX();
+        printTraversalForm(traversal);
+        int counter = 0;
+        final Set<List<String>> results = new HashSet<>();
+        while (traversal.hasNext()) {
+            final Map<String, Vertex> map = traversal.next();
+            assertEquals(3, map.size());
+            assertTrue(results.add(Arrays.asList(map.get("a").label(), map.get("b").label())));
+            counter++;
+        }
+        assertEquals(3, counter);
+        assertEquals(results.size(), counter);
     }
 
     public static class GreedyMatchTraversals extends Traversals {
@@ -660,10 +691,17 @@ public abstract class MatchTest extends AbstractGremlinProcessTest {
         }
 
         @Override
-        public Traversal<Vertex, Map<String, Object>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX() {
-            return g.V().match("a",
+        public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX() {
+            return g.V().<Vertex>match("a",
                     as("a").both().as("b"),
                     as("b").both().as("c")).dedup("a", "b");
         }
+
+        @Override
+        public Traversal<Vertex, Map<String, Vertex>> get_g_V_matchXa__a_both_b__b_both_cX_dedupXa_bX_byXlabelX() {
+            return g.V().<Vertex>match("a",
+                    as("a").both().as("b"),
+                    as("b").both().as("c")).dedup("a", "b").by(T.label);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/e9d503a5/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherTest.java
----------------------------------------------------------------------
diff --git a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherTest.java b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherTest.java
index d462336..bee7add 100644
--- a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherTest.java
+++ b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/process/NativeNeo4jCypherTest.java
@@ -27,9 +27,15 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.util.TimeUtil;
+import org.junit.Ignore;
 import org.junit.Test;
 
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.function.Supplier;
 
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
@@ -126,6 +132,7 @@ public class NativeNeo4jCypherTest extends AbstractNeo4jGremlinTest {
     }
 
     @Test
+    @Ignore
     @LoadGraphWith(LoadGraphWith.GraphData.GRATEFUL)
     public void benchmarkCypherAndMatch() throws Exception {
         final Neo4jGraph n = (Neo4jGraph) graph;
@@ -194,7 +201,7 @@ public class NativeNeo4jCypherTest extends AbstractNeo4jGremlinTest {
         for (final Supplier<GraphTraversal<?, ?>> traversal : traversals) {
             System.out.println("pre-strategy:  " + traversal.get());
             System.out.println("post-strategy: " + traversal.get().iterate());
-            System.out.println(TimeUtil.clockWithResult(50, () -> traversal.get().count().next()));
+            System.out.println(TimeUtil.clockWithResult(25, () -> traversal.get().count().next()));
             if (++counter % 2 == 0)
                 System.out.println("------------------");
         }