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/04 21:15:13 UTC

incubator-tinkerpop git commit: Scoping steps now respect getting scoped values from sideEffects and then either map (local) or path (global). This fixes a major design flaw wheree sideEffects were only accessible via Scope.global (not what you always wa

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master 6b8bee856 -> f4a44a63f


Scoping steps now respect getting scoped values from sideEffects and then either map (local) or path (global). This fixes a major design flaw wheree sideEffects were only accessible via Scope.global (not what you always want). ScopingStrategy is now smarter about Scope.local converion based on path access labels.


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

Branch: refs/heads/master
Commit: f4a44a63f4e373becc07d014c32e5fa4dbc25a2f
Parents: 6b8bee8
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Jun 4 13:14:36 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Jun 4 13:14:52 2015 -0600

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  3 +++
 .../gremlin/process/traversal/step/Scoping.java | 22 ++++++++++++++-----
 .../traversal/step/filter/WhereStep.java        | 19 +++++++++++++++-
 .../process/traversal/step/map/AddEdgeStep.java | 11 ++++++++++
 .../traversal/step/map/SelectOneStep.java       |  9 +++++++-
 .../process/traversal/step/map/SelectStep.java  | 10 ++++++++-
 .../traversal/step/map/match/MatchStep.java     | 15 +++++++++++--
 .../strategy/finalization/ScopingStrategy.java  | 15 +++++++++++--
 .../process/traversal/util/TraversalHelper.java | 23 +++++++++++++++++++-
 9 files changed, 114 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 138cbd0..96abe2b 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,9 @@ image::http://www.tinkerpop.com/docs/current/images/gremlin-hindu.png[width=225]
 TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* `Scoping` now has `getScope()`, `setScope()`, and `getScopeKeys()`.
+* `ScopingStrategy` is smart about `Scope.global` settings based on traversal labels.
+* `Scope.global` and `Scope.local` both account for traversal side-effects. The distinction is between path and map.
 * Refactored SSL support in the Gremlin Server/Driver.
 * Factored out `ServerGremlinExecutor` which contains the core elements of server-side script execution in Gremlin Server.
 * Bumped to netty 4.0.28.Final.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
index 01f1485..0c387a9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/Scoping.java
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
 
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -34,23 +35,32 @@ import java.util.Optional;
 public interface Scoping {
 
     public default <S> S getScopeValueByKey(final String key, final Traverser.Admin<?> traverser) throws IllegalArgumentException {
+        if (traverser.getSideEffects().get(key).isPresent())
+            return traverser.getSideEffects().<S>get(key).get();
         if (Scope.local == this.getScope()) {
             final S s = ((Map<String, S>) traverser.get()).get(key);
-            if (null == s)
-                throw new IllegalArgumentException("The provided map does not have a " + key + "-key: " + traverser);
-            return s;
+            if (null != s)
+                return s;
+            else
+                throw new IllegalArgumentException("Neither the current map nor sideEffects have a " + key + "-key:" + this);
         } else {
             final Path path = traverser.path();
-            return path.hasLabel(key) ? path.get(key) : traverser.getSideEffects().<S>get(key).orElseThrow(() -> new IllegalArgumentException("Neither the current path nor sideEffects have a " + key + "-key: " + traverser));
+            if (path.hasLabel(key))
+                return path.get(key);
+            else
+                throw new IllegalArgumentException("Neither the current path nor sideEffects have a " + key + "-key: " + this);
         }
     }
 
     public default <S> Optional<S> getOptionalScopeValueByKey(final String key, final Traverser.Admin<?> traverser) {
+        if (traverser.getSideEffects().get(key).isPresent())
+            return traverser.getSideEffects().<S>get(key);
+
         if (Scope.local == this.getScope()) {
             return Optional.ofNullable(((Map<String, S>) traverser.get()).get(key));
         } else {
             final Path path = traverser.path();
-            return Optional.ofNullable(path.hasLabel(key) ? path.get(key) : traverser.getSideEffects().<S>get(key).orElse(null));
+            return path.hasLabel(key) ? Optional.of(path.get(key)) : Optional.<S>empty();
         }
     }
 
@@ -60,4 +70,6 @@ public interface Scoping {
 
     public void setScope(final Scope scope);
 
+    public Set<String> getScopeKeys();
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
index 9822b77..51c9647 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereStep.java
@@ -93,6 +93,22 @@ public final class WhereStep<S> extends FilterStep<S> implements TraversalParent
     }
 
     @Override
+    public Set<String> getScopeKeys() {
+        final Set<String> keys = new HashSet<>();
+        if(this.multiKeyedTraversal) {
+            keys.addAll(this.startKeys);
+            keys.addAll(this.endKeys);
+        } else {
+            if (null != this.startKey)
+                keys.add(this.startKey);
+            if (null != this.endKey)
+                keys.add(this.endKey);
+        }
+        return keys;
+
+    }
+
+    @Override
     public WhereStep<S> clone() {
         final WhereStep<S> clone = (WhereStep<S>) super.clone();
         clone.predicate = this.predicate.clone();
@@ -110,7 +126,8 @@ public final class WhereStep<S> extends FilterStep<S> implements TraversalParent
     @Override
     public Set<TraverserRequirement> getRequirements() {
         return this.getSelfAndChildRequirements(Scope.local == this.scope || this.noStartAndEndKeys() ?
-                TraverserRequirement.OBJECT : TraverserRequirement.OBJECT, TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS);
+                new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS} :
+                new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS});
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
index 5112977..e755454 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AddEdgeStep.java
@@ -34,6 +34,7 @@ import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
@@ -155,4 +156,14 @@ public final class AddEdgeStep<S> extends FlatMapStep<S, Edge> implements Scopin
     public Scope getScope() {
         return this.scope;
     }
+
+    @Override
+    public Set<String> getScopeKeys() {
+        final Set<String> keys = new HashSet<>();
+        if (null != this.firstVertexKey)
+            keys.add(this.firstVertexKey);
+        if (null != this.secondVertexKey)
+            keys.add(this.secondVertexKey);
+        return keys;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
index 4a0bebf..0df3899 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectOneStep.java
@@ -84,7 +84,9 @@ public final class SelectOneStep<S, E> extends MapStep<S, E> implements Traversa
 
     @Override
     public Set<TraverserRequirement> getRequirements() {
-        return this.getSelfAndChildRequirements(this.scope == Scope.local ? TraverserRequirement.OBJECT : TraverserRequirement.PATH);
+        return this.getSelfAndChildRequirements(Scope.local == this.scope ?
+                new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS} :
+                new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS});
     }
 
     @Override
@@ -101,6 +103,11 @@ public final class SelectOneStep<S, E> extends MapStep<S, E> implements Traversa
     public Scope getScope() {
         return this.scope;
     }
+
+    @Override
+    public Set<String> getScopeKeys() {
+        return Collections.singleton(this.selectLabel);
+    }
 }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
index f7da677..b9d8f55 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/SelectStep.java
@@ -31,6 +31,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -119,7 +120,9 @@ public final class SelectStep<S, E> extends MapStep<S, Map<String, E>> implement
 
     @Override
     public Set<TraverserRequirement> getRequirements() {
-        return this.getSelfAndChildRequirements(this.scope == Scope.local ? TraverserRequirement.OBJECT : TraverserRequirement.PATH);
+        return this.getSelfAndChildRequirements(Scope.local == this.scope ?
+                new TraverserRequirement[]{TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS} :
+                new TraverserRequirement[]{TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS});
     }
 
     @Override
@@ -136,4 +139,9 @@ public final class SelectStep<S, E> extends MapStep<S, Map<String, E>> implement
     public Scope recommendNextScope() {
         return Scope.local;
     }
+
+    @Override
+    public Set<String> getScopeKeys() {
+        return new HashSet<>(this.selectLabels);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/match/MatchStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/match/MatchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/match/MatchStep.java
index d4971c2..db00d80 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/match/MatchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/match/MatchStep.java
@@ -61,7 +61,7 @@ public final class MatchStep<S, E> extends AbstractStep<S, Map<String, E>> imple
 
     private final String startLabel;
     private final Map<String, List<TraversalWrapper<S, S>>> traversalsByStartAs;
-    private final List<Traversal> traversals = new ArrayList<>();
+    private final List<Traversal<?,?>> traversals = new ArrayList<>();
 
     private int startsPerOptimize = DEFAULT_STARTS_PER_OPTIMIZE;
     private int optimizeCounter = -1;
@@ -92,6 +92,17 @@ public final class MatchStep<S, E> extends AbstractStep<S, Map<String, E>> imple
     }
 
     @Override
+    public Set<String> getScopeKeys() {
+        final Set<String> keys = new HashSet<>();
+        keys.add(this.startLabel);
+        this.traversals.forEach(t -> {
+            keys.addAll(t.asAdmin().getStartStep().getLabels());
+            keys.addAll(t.asAdmin().getEndStep().getLabels());
+        });
+        return keys;
+    }
+
+    @Override
     public String toString() {
         return StringFactory.stepString(this, this.traversalsByStartAs);
     }
@@ -402,7 +413,7 @@ public final class MatchStep<S, E> extends AbstractStep<S, Map<String, E>> imple
     }
 
     @Override
-    public List<Traversal> getLocalChildren() {
+    public List<Traversal<?,?>> getLocalChildren() {
         return this.traversals;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
index 40f8e10..42ad68b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/ScopingStrategy.java
@@ -21,10 +21,14 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization;
 
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -38,9 +42,16 @@ public final class ScopingStrategy extends AbstractTraversalStrategy<TraversalSt
 
     @Override
     public void apply(final Traversal.Admin<?, ?> traversal) {
+        final Set<String> pathLabels = TraversalHelper.getLabels(TraversalHelper.getRootTraversal(traversal));
         traversal.getSteps().stream().forEach(step -> {
-            if (step instanceof Scoping && step.getPreviousStep() instanceof Scoping) {
-                ((Scoping) step).setScope(((Scoping) step.getPreviousStep()).recommendNextScope());
+            if (step instanceof Scoping) {
+                if (step.getPreviousStep() instanceof Scoping)
+                    ((Scoping) step).setScope(((Scoping) step.getPreviousStep()).recommendNextScope());
+                else if (Scope.global == ((Scoping) step).getScope()) {
+                    final Set<String> keys = ((Scoping) step).getScopeKeys();
+                    if (!keys.isEmpty() && !((Scoping) step).getScopeKeys().stream().filter(pathLabels::contains).findAny().isPresent())
+                        ((Scoping) step).setScope(Scope.local);
+                }
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/f4a44a63/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
index 4f94071..95e26c1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
@@ -30,7 +30,13 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -285,4 +291,19 @@ public final class TraversalHelper {
         }
         return traversal;
     }
+
+    public static Set<String> getLabels(final Traversal.Admin<?, ?> traversal) {
+        return getLabels(new HashSet<>(), traversal);
+    }
+
+    private static Set<String> getLabels(final Set<String> labels, final Traversal.Admin<?, ?> traversal) {
+        for (final Step<?, ?> step : traversal.getSteps()) {
+            labels.addAll(step.getLabels());
+            if (step instanceof TraversalParent) {
+                ((TraversalParent) step).getLocalChildren().forEach(child -> getLabels(labels, child));
+                ((TraversalParent) step).getGlobalChildren().forEach(child -> getLabels(labels, child));
+            }
+        }
+        return labels;
+    }
 }