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 2017/10/03 23:37:26 UTC
tinkerpop git commit: first non-tested implementation of math()-step.
It uses the @twilmes model which parses a String representation of the
expression.
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1632 [created] 6f1a1f702
first non-tested implementation of math()-step. It uses the @twilmes model which parses a String representation of the expression.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6f1a1f70
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6f1a1f70
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6f1a1f70
Branch: refs/heads/TINKERPOP-1632
Commit: 6f1a1f7028f285c6e45b7e7596320710b91114c5
Parents: 4728916
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Oct 3 17:37:10 2017 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Oct 3 17:37:10 2017 -0600
----------------------------------------------------------------------
gremlin-core/pom.xml | 5 +
.../traversal/dsl/graph/GraphTraversal.java | 14 ++
.../gremlin/process/traversal/dsl/graph/__.java | 7 +
.../process/traversal/step/map/MathStep.java | 128 +++++++++++++++++++
.../process/traversal/util/TraversalHelper.java | 2 +-
.../traversal/dsl/graph/GraphTraversalTest.java | 2 +
.../Process/Traversal/GraphTraversal.cs | 9 ++
.../src/Gremlin.Net/Process/Traversal/__.cs | 8 ++
.../gremlin_python/process/graph_traversal.py | 12 ++
.../structure/TinkerGraphPlayTest.java | 42 +-----
10 files changed, 188 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-core/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-core/pom.xml b/gremlin-core/pom.xml
index 3d9e701..30c1b9f 100644
--- a/gremlin-core/pom.xml
+++ b/gremlin-core/pom.xml
@@ -68,6 +68,11 @@ limitations under the License.
<artifactId>javapoet</artifactId>
<version>1.8.0</version>
</dependency>
+ <dependency>
+ <groupId>net.objecthunter</groupId>
+ <artifactId>exp4j</artifactId>
+ <version>0.4.8</version>
+ </dependency>
<!-- LOGGING -->
<dependency>
<groupId>org.slf4j</groupId>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 44a7a3a..8cedbfb 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -86,6 +86,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaFlatMapStep
import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaMapStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.LoopsStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.MathStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MaxGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MaxLocalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanGlobalStep;
@@ -1097,6 +1098,18 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
return this;
}
+ /**
+ * Map the {@link Traverser} to a {@link Double} according to the mathematical expression provided in the argument.
+ *
+ * @param expression the mathematical expression with variables refering to scope variables.
+ * @return the traversal with the {@link MathStep} added.
+ * @since 3.3.1
+ */
+ public default GraphTraversal<S, Double> math(final String expression) {
+ this.asAdmin().getBytecode().addStep(Symbols.math, expression);
+ return this.asAdmin().addStep(new MathStep<>(this.asAdmin(), expression));
+ }
+
///////////////////// FILTER STEPS /////////////////////
/**
@@ -2691,6 +2704,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
public static final String value = "value";
public static final String path = "path";
public static final String match = "match";
+ public static final String math = "math";
public static final String sack = "sack";
public static final String loops = "loops";
public static final String project = "project";
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index 9dc3a93..39e5258 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -498,6 +498,13 @@ public class __ {
return __.<A>start().addE(edgeLabelTraversal);
}
+ /**
+ * @see GraphTraversal#math(String)
+ */
+ public static <A> GraphTraversal<A, Double> math(final String expression) {
+ return __.<A>start().math(expression);
+ }
+
///////////////////// FILTER STEPS /////////////////////
/**
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
new file mode 100644
index 0000000..645ea06
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MathStep.java
@@ -0,0 +1,128 @@
+/*
+ * 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.step.map;
+
+import net.objecthunter.exp4j.Expression;
+import net.objecthunter.exp4j.ExpressionBuilder;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalRing;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class MathStep<S> extends MapStep<S, Double> implements ByModulating, TraversalParent, Scoping {
+
+ private static final String CURRENT = "_";
+ private final String equation;
+ private final Set<String> variables;
+ private final Expression expression;
+ private TraversalRing<Object, Number> traversalRing = new TraversalRing<>();
+
+ public MathStep(final Traversal.Admin traversal, final String equation) {
+ super(traversal);
+ this.equation = equation;
+ final Set<String> labels = TraversalHelper.getLabels(TraversalHelper.getRootTraversal(this.getTraversal()));
+ this.variables = new LinkedHashSet<>();
+ for (final String label : labels) {
+ if (this.equation.contains(label))
+ this.variables.add(label);
+ }
+ if (this.equation.contains(CURRENT))
+ this.variables.add(CURRENT);
+ this.expression = new ExpressionBuilder(this.equation)
+ .variables(this.variables)
+ .build();
+ }
+
+ @Override
+ protected Double map(final Traverser.Admin<S> traverser) {
+ for (final String var : this.variables) {
+ this.expression.setVariable(var, TraversalUtil.applyNullable(
+ var.equals(CURRENT) ?
+ traverser.get() :
+ this.getNullableScopeValue(Pop.last, var, traverser),
+ this.traversalRing.next()).doubleValue());
+ }
+ this.traversalRing.reset();
+ return this.expression.evaluate();
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> selectTraversal) {
+ this.traversalRing.addTraversal(this.integrateChild(selectTraversal));
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.equation, this.traversalRing);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() ^ this.equation.hashCode() ^ this.traversalRing.hashCode();
+ }
+
+ @Override
+ public List<Traversal.Admin<Object, Number>> getLocalChildren() {
+ return this.traversalRing.getTraversals();
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ this.traversalRing.reset();
+ }
+
+ @Override
+ public MathStep<S> clone() {
+ final MathStep<S> clone = (MathStep<S>) super.clone();
+ clone.traversalRing = this.traversalRing.clone();
+ return clone;
+ }
+
+ @Override
+ public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+ super.setTraversal(parentTraversal);
+ this.traversalRing.getTraversals().forEach(this::integrateChild);
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS);
+ }
+
+ @Override
+ public Set<String> getScopeKeys() {
+ return this.variables;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/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 56f2eca..9db3ea8 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
@@ -560,7 +560,7 @@ public final class TraversalHelper {
}
public static Set<String> getLabels(final Traversal.Admin<?, ?> traversal) {
- return TraversalHelper.getLabels(new HashSet<>(), traversal);
+ return TraversalHelper.getLabels(new LinkedHashSet<>(), traversal);
}
private static Set<String> getLabels(final Set<String> labels, final Traversal.Admin<?, ?> traversal) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
index cfa63fa..d3fe1c4 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversalTest.java
@@ -112,6 +112,8 @@ public class GraphTraversalTest {
list.add(arguments[0] = (long) (Math.abs(random.nextInt(10))));
list.add(arguments[1] = (long) (Math.abs(random.nextInt(10) + 100)));
}
+ } else if (stepMethod.getName().equals("math")) {
+ list.add(arguments[0] = random.nextInt(100) + " + " + random.nextInt(100));
} else {
for (int i = 0; i < stepMethod.getParameterTypes().length; i++) {
final Class<?> type = stepMethod.getParameterTypes()[i];
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index 00bfd4b..6c6d174 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -495,6 +495,15 @@ namespace Gremlin.Net.Process.Traversal
}
/// <summary>
+ /// Adds the math step to this <see cref="GraphTraversal{SType, EType}" />.
+ /// </summary>
+ public GraphTraversal< S , Double > Math (params object[] args)
+ {
+ Bytecode.AddStep("math", args);
+ return Wrap< S , Double >(this);
+ }
+
+ /// <summary>
/// Adds the max step to this <see cref="GraphTraversal{SType, EType}" />.
/// </summary>
public GraphTraversal< S , E2 > Max<E2> (params object[] args)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
----------------------------------------------------------------------
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
index dfe114d..0e0c527 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
@@ -409,6 +409,14 @@ namespace Gremlin.Net.Process.Traversal
}
/// <summary>
+ /// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the math step to that traversal.
+ /// </summary>
+ public static GraphTraversal<object, Double> Math(params object[] args)
+ {
+ return new GraphTraversal<object, object>().Math(args);
+ }
+
+ /// <summary>
/// Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds the max step to that traversal.
/// </summary>
public static GraphTraversal<object, E2> Max<E2>(params object[] args)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index f7bb201..d5630c0 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -317,6 +317,10 @@ class GraphTraversal(Traversal):
self.bytecode.add_step("match", *args)
return self
+ def math(self, *args):
+ self.bytecode.add_step("math", *args)
+ return self
+
def max(self, *args):
self.bytecode.add_step("max", *args)
return self
@@ -697,6 +701,10 @@ class __(object):
return cls.graph_traversal(None, None, Bytecode()).match(*args)
@classmethod
+ def math(cls, *args):
+ return cls.graph_traversal(None, None, Bytecode()).math(*args)
+
+ @classmethod
def max(cls, *args):
return cls.graph_traversal(None, None, Bytecode()).max(*args)
@@ -1046,6 +1054,10 @@ def match(*args):
return __.match(*args)
statics.add_static('match', match)
+def math(*args):
+ return __.math(*args)
+statics.add_static('math', math)
+
def max(*args):
return __.max(*args)
statics.add_static('max', max)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6f1a1f70/tinkergraph-gremlin/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraphPlayTest.java
----------------------------------------------------------------------
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 eeb4f38..0af81bd 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
@@ -50,6 +50,7 @@ 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.__.as;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.both;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.bothE;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.choose;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.has;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
@@ -70,48 +71,9 @@ public class TinkerGraphPlayTest {
public void testPlay8() throws Exception {
Graph graph = TinkerFactory.createModern();
GraphTraversalSource g = graph.traversal();
-
- final Traversal<?, ?> traversal = g.V().repeat(out()).times(2).groupCount().by("name").select(Column.keys).order().by(Order.decr);
- final Bytecode bytecode = traversal.asAdmin().getBytecode();
- //final JavaTranslator translator = JavaTranslator.of(g);
- final Map<Bytecode, Traversal.Admin<?, ?>> cache = new HashMap<>();
- cache.put(bytecode, traversal.asAdmin());
- final HashSet<?> result = new LinkedHashSet<>(Arrays.asList("ripple", "lop"));
-
- System.out.println("BYTECODE: " + bytecode + "\n");
- System.out.println("Bytecode->Traversal.clone() cache: " + TimeUtil.clock(1000, () -> {
- final Traversal.Admin<?, ?> t = cache.get(bytecode).clone();
- //assertEquals(result, t.next());
- }));
-
- System.out.println("Bytecode->JavaTranslator call : " + TimeUtil.clock(1000, () -> {
- final Traversal t = JavaTranslator.of(g).translate(bytecode);
- //assertEquals(result, t.next());
- }));
-
- System.out.println("\n==Second test with reversed execution==\n");
-
- System.out.println("BYTECODE: " + bytecode + "\n");
- System.out.println("Bytecode->JavaTranslator call : " + TimeUtil.clock(1000, () -> {
- final Traversal t = JavaTranslator.of(g).translate(bytecode);
- //assertEquals(result, t.next());
- }));
-
- System.out.println("Bytecode->Traversal.clone() cache: " + TimeUtil.clock(1000, () -> {
- final Traversal.Admin<?, ?> t = cache.get(bytecode).clone();
- //assertEquals(result, t.next());
- }));
+ System.out.println(g.V().as("a").out("knows").math("((a ^ _) / a)").by("age").by(bothE().count()).toList());
}
- /* @Test
- public void testTraversalDSL() throws Exception {
- Graph g = TinkerFactory.createClassic();
- assertEquals(2, g.of(TinkerFactory.SocialTraversal.class).people("marko").knows().name().toList().size());
- g.of(TinkerFactory.SocialTraversal.class).people("marko").knows().name().forEachRemaining(name -> assertTrue(name.equals("josh") || name.equals("vadas")));
- assertEquals(1, g.of(TinkerFactory.SocialTraversal.class).people("marko").created().name().toList().size());
- g.of(TinkerFactory.SocialTraversal.class).people("marko").created().name().forEachRemaining(name -> assertEquals("lop", name));
- }*/
-
@Test
@Ignore
public void benchmarkStandardTraversals() throws Exception {