You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/09/29 20:09:47 UTC

[08/50] tinkerpop git commit: Added support for SubgraphStrategy.vertexProperties(). Added some test cases to verify proper functioning. Also, cleaned up Stream-stuff in SubgraphStrategy. Going to do some more cleanup there to make things clean and effic

Added support for SubgraphStrategy.vertexProperties(). Added some test cases to verify proper functioning. Also, cleaned up Stream-stuff in SubgraphStrategy. Going to do some more cleanup there to make things clean and efficient.


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

Branch: refs/heads/TINKERPOP-1458
Commit: c01b52a966c595fac54b3c53dea210e659bf4b08
Parents: dc60e07
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Mon Sep 19 13:52:33 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Sep 27 12:45:49 2016 -0600

----------------------------------------------------------------------
 .../strategy/decoration/SubgraphStrategy.java   | 107 ++++++++++++++-----
 .../decoration/SubgraphStrategyProcessTest.java |  25 ++++-
 2 files changed, 105 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c01b52a9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
index 967a19b..f1a42cd 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategy.java
@@ -23,6 +23,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.LambdaFilterStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.OrStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.filter.TraversalFilterStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
@@ -30,14 +32,19 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertiesStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PropertyValueStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
 import org.apache.tinkerpop.gremlin.structure.Direction;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.PropertyType;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -58,9 +65,10 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
 
     private final Traversal.Admin<Vertex, ?> vertexCriterion;
     private final Traversal.Admin<Edge, ?> edgeCriterion;
+    private final Traversal.Admin<VertexProperty, ?> vertexPropertyCriterion;
     private final String MARKER = Graph.Hidden.hide(UUID.randomUUID().toString());
 
-    private SubgraphStrategy(final Traversal<Vertex, ?> vertexCriterion, final Traversal<Edge, ?> edgeCriterion) {
+    private SubgraphStrategy(final Traversal<Vertex, ?> vertexCriterion, final Traversal<Edge, ?> edgeCriterion, final Traversal<VertexProperty, ?> vertexPropertyCriterion) {
         this.vertexCriterion = null == vertexCriterion ? null : vertexCriterion.asAdmin();
 
         // if there is no vertex predicate there is no need to test either side of the edge
@@ -79,10 +87,14 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
                 this.edgeCriterion = edgeCriterion.asAdmin().addStep(new TraversalFilterStep<>(edgeCriterion.asAdmin(), vertexPredicate));
         }
 
+        this.vertexPropertyCriterion = null == vertexPropertyCriterion ? null : vertexPropertyCriterion.asAdmin();
+
         if (null != this.vertexCriterion)
             this.metadataLabelStartStep(this.vertexCriterion);
         if (null != this.edgeCriterion)
             this.metadataLabelStartStep(this.edgeCriterion);
+        if (null != this.vertexPropertyCriterion)
+            this.metadataLabelStartStep(this.vertexPropertyCriterion);
     }
 
     private final void metadataLabelStartStep(final Traversal.Admin<?, ?> traversal) {
@@ -123,61 +135,101 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
             applyCriterion(edgeStepsToInsertFilterAfter, traversal, this.edgeCriterion);
         }
 
-        // explode g.V().out() to g.V().outE().inV() only if there is an edge predicate otherwise
-        vertexSteps.stream().filter(VertexStep::returnsVertex).forEach(step -> {
+        // turn g.V().out() to g.V().outE().inV() only if there is an edge predicate otherwise
+        for (final VertexStep<?> step : vertexSteps) {
+            if (step.returnsEdge())
+                continue;
             if (null != this.vertexCriterion && null == edgeCriterion) {
-                TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.vertexCriterion.clone()), step, traversal);
+                TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, (Traversal) this.vertexCriterion.clone()), step, traversal);
             } else {
-                final VertexStep someEStep = new VertexStep<>(traversal, Edge.class, step.getDirection(), step.getEdgeLabels());
-                final Step someVStep = step.getDirection() == Direction.BOTH ?
+                final VertexStep<Edge> someEStep = new VertexStep<>(traversal, Edge.class, step.getDirection(), step.getEdgeLabels());
+                final Step<Edge, Vertex> someVStep = step.getDirection() == Direction.BOTH ?
                         new EdgeOtherVertexStep(traversal) :
                         new EdgeVertexStep(traversal, step.getDirection().opposite());
 
-                // if step was labeled then propagate those labels to the new step that will return the vertex
-                transferLabels(step, someVStep);
-
-                TraversalHelper.replaceStep(step, someEStep, traversal);
+                TraversalHelper.replaceStep((Step<Vertex, Edge>) step, someEStep, traversal);
                 TraversalHelper.insertAfterStep(someVStep, someEStep, traversal);
+                // if step was labeled then propagate those labels to the new step that will return the vertex
+                for (final String label : step.getLabels()) {
+                    step.removeLabel(label);
+                    someVStep.addLabel(label);
+                }
 
                 if (null != this.edgeCriterion)
                     TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.edgeCriterion.clone()), someEStep, traversal);
                 if (null != this.vertexCriterion)
                     TraversalHelper.insertAfterStep(new TraversalFilterStep<>(traversal, this.vertexCriterion.clone()), someVStep, traversal);
             }
-        });
+        }
+
+        // turn g.V().properties() to g.V().properties().xxx
+        // turn g.V().values() to g.V().properties().xxx.value()\
+        if (null != this.vertexPropertyCriterion) {
+            final OrStep<Object> wrappedCriterion = new OrStep<>(traversal,
+                    new DefaultTraversal<>().addStep(new LambdaFilterStep<>(traversal, t -> !(t.get() instanceof VertexProperty))),
+                    new DefaultTraversal<>().addStep(new TraversalFilterStep<>(traversal, this.vertexPropertyCriterion.clone())));
+            for (final PropertiesStep<?> step : TraversalHelper.getStepsOfAssignableClass(PropertiesStep.class, traversal)) {
+                if (PropertyType.PROPERTY.equals(step.getReturnType())) {
+                    // if the property step returns a property, then simply append the criterion
+                    final OrStep<Object> clonedWrappedCriterion = (OrStep) wrappedCriterion.clone();
+                    TraversalHelper.insertAfterStep(clonedWrappedCriterion, (Step) step, traversal);
+                    for (final String label : step.getLabels()) {
+                        step.removeLabel(label);
+                        clonedWrappedCriterion.addLabel(label);
+                    }
+                } else {
+                    // if the property step returns value, then replace it with a property step, append criterion, then append a value() step
+                    final Step propertiesStep = new PropertiesStep(traversal, PropertyType.PROPERTY, step.getPropertyKeys());
+                    TraversalHelper.replaceStep(step, propertiesStep, traversal);
+                    final Step filterStep = wrappedCriterion.clone();
+                    TraversalHelper.insertAfterStep(filterStep, propertiesStep, traversal);
+                    final Step propertyValueStep = new PropertyValueStep(traversal);
+                    TraversalHelper.insertAfterStep(propertyValueStep, filterStep, traversal);
+                    // add labels to the value step after the filter has been applied
+                    for (final String label : step.getLabels()) {
+                        propertyValueStep.addLabel(label);
+                    }
+                }
+            }
+        }
     }
 
+
     public Traversal<Vertex, ?> getVertexCriterion() {
-        return vertexCriterion;
+        return this.vertexCriterion;
     }
 
     public Traversal<Edge, ?> getEdgeCriterion() {
-        return edgeCriterion;
+        return this.edgeCriterion;
     }
 
+    public Traversal<VertexProperty, ?> getVertexPropertyCriterion() {
+        return this.vertexPropertyCriterion;
+    }
+
+
     public static Builder build() {
         return new Builder();
     }
 
     private void applyCriterion(final List<Step> stepsToApplyCriterionAfter, final Traversal.Admin traversal,
                                 final Traversal.Admin<? extends Element, ?> criterion) {
-        stepsToApplyCriterionAfter.forEach(s -> {
+        for (final Step<?, ?> step : stepsToApplyCriterionAfter) {
             // re-assign the step label to the criterion because the label should apply seamlessly after the filter
             final Step filter = new TraversalFilterStep<>(traversal, criterion.clone());
-            transferLabels(s, filter);
-            TraversalHelper.insertAfterStep(filter, s, traversal);
-        });
-    }
-
-    private static void transferLabels(final Step from, final Step to) {
-        from.getLabels().forEach(label -> to.addLabel((String) label));
-        to.getLabels().forEach(label -> from.removeLabel((String) label));
+            for (final String label : step.getLabels()) {
+                step.removeLabel(label);
+                filter.addLabel(label);
+            }
+            TraversalHelper.insertAfterStep(filter, step, traversal);
+        }
     }
 
     public final static class Builder {
 
         private Traversal<Vertex, ?> vertexPredicate = null;
         private Traversal<Edge, ?> edgePredicate = null;
+        private Traversal<VertexProperty, ?> vertexPropertyPredicate = null;
 
         private Builder() {
         }
@@ -192,6 +244,11 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
             return this;
         }
 
+        public Builder vertexProperties(final Traversal<VertexProperty, ?> vertexPropertyPredicate) {
+            this.vertexPropertyPredicate = vertexPropertyPredicate;
+            return this;
+        }
+
         @Deprecated
         /**
          * @deprecated Since 3.2.2, use {@code Builder#vertices} instead.
@@ -209,9 +266,9 @@ public final class SubgraphStrategy extends AbstractTraversalStrategy<TraversalS
         }
 
         public SubgraphStrategy create() {
-            if (null == this.edgePredicate && null == this.vertexPredicate)
-                throw new IllegalStateException("A subgraph must be filtered by an edge or vertex criterion");
-            return new SubgraphStrategy(this.vertexPredicate, this.edgePredicate);
+            if (null == this.vertexPredicate && null == this.edgePredicate && null == this.vertexPropertyPredicate)
+                throw new IllegalStateException("A subgraph must be filtered by a vertex, edge, or vertex property criterion");
+            return new SubgraphStrategy(this.vertexPredicate, this.edgePredicate, this.vertexPropertyPredicate);
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c01b52a9/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
index 41a730a..1d49d92 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/SubgraphStrategyProcessTest.java
@@ -21,10 +21,8 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
 import org.apache.tinkerpop.gremlin.process.GremlinProcessRunner;
-import org.apache.tinkerpop.gremlin.process.IgnoreEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.P;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
 import org.apache.tinkerpop.gremlin.structure.Edge;
@@ -36,6 +34,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.NoSuchElementException;
 
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.CREW;
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.bothE;
@@ -366,6 +365,28 @@ public class SubgraphStrategyProcessTest extends AbstractGremlinProcessTest {
         sg.E(sg.E(convertToEdgeId("marko", "knows", "vadas")).next()).next();
     }
 
+    @Test
+    @LoadGraphWith(CREW)
+    public void shouldFilterVertexProperties() throws Exception {
+        GraphTraversalSource sg = create(SubgraphStrategy.build().vertexProperties(has("startTime", P.gt(2005))).create());
+        checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().properties("location").value());
+        checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().values("location"));
+        // check to make sure edge properties are not analyzed
+        sg = create(SubgraphStrategy.build().vertexProperties(has("startTime", P.gt(2005))).create());
+        checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().as("a").properties("location").as("b").select("a").outE().properties().select("b").value().dedup());
+        checkResults(Arrays.asList("purcellville", "baltimore", "oakland", "seattle", "aachen"), sg.V().as("a").values("location").as("b").select("a").outE().properties().select("b").dedup());
+        //
+        //
+        sg = create(SubgraphStrategy.build().vertices(has("name", P.neq("stephen"))).vertexProperties(has("startTime", P.gt(2005))).create());
+        checkResults(Arrays.asList("baltimore", "oakland", "seattle", "aachen"), sg.V().properties("location").value());
+        checkResults(Arrays.asList("baltimore", "oakland", "seattle", "aachen"), sg.V().values("location"));
+        //
+        sg = create(SubgraphStrategy.build().vertices(has("name", P.not(P.within("stephen", "daniel")))).vertexProperties(has("startTime", P.gt(2005))).create());
+        checkResults(Arrays.asList("baltimore", "oakland", "seattle"), sg.V().properties("location").value());
+        checkResults(Arrays.asList("baltimore", "oakland", "seattle"), sg.V().values("location"));
+    }
+
+
     private GraphTraversalSource create(final SubgraphStrategy strategy) {
         return graphProvider.traversal(graph, strategy);
     }