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/22 19:29:23 UTC
incubator-tinkerpop git commit: P.hashCode() is now based on
P.originalValue() as it causes problems with MatchStep if not where
where()-steps have dynamic P's based on bindings. Added
MatchAlgorithmStrategy which allows the user to specify the MatchAlgo
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/master 859e90c4b -> c20b46ebd
P.hashCode() is now based on P.originalValue() as it causes problems with MatchStep if not where where()-steps have dynamic P's based on bindings. Added MatchAlgorithmStrategy which allows the user to specify the MatchAlgorithm they want to use. Default is CountMatchAlgorithm for now.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/c20b46eb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/c20b46eb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/c20b46eb
Branch: refs/heads/master
Commit: c20b46ebdbfd14b8320ee66cd54c5f0ee2e5be84
Parents: 859e90c
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Mon Jun 22 11:29:17 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Mon Jun 22 11:29:17 2015 -0600
----------------------------------------------------------------------
.../tinkerpop/gremlin/process/traversal/P.java | 8 +--
.../process/traversal/TraversalStrategies.java | 2 +
.../process/traversal/step/map/MatchStep.java | 59 +++++++--------
.../finalization/MatchAlgorithmStrategy.java | 75 ++++++++++++++++++++
.../step/filter/GroovyWhereTest.groovy | 4 +-
.../traversal/step/filter/WhereTest.java | 8 +--
6 files changed, 114 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c20b46eb/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
index 8fc78a0..2340048 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java
@@ -78,7 +78,7 @@ public class P<V> implements Predicate<V>, Serializable, Cloneable {
@Override
public int hashCode() {
- return this.biPredicate.hashCode() ^ (null == this.value ? "null".hashCode() : this.value.hashCode());
+ return this.biPredicate.hashCode() ^ (null == this.originalValue ? "null".hashCode() : this.originalValue.hashCode());
}
@Override
@@ -86,17 +86,17 @@ public class P<V> implements Predicate<V>, Serializable, Cloneable {
return other instanceof P &&
((P) other).getClass().equals(this.getClass()) &&
((P) other).getBiPredicate().equals(this.biPredicate) &&
- ((((P) other).getValue() == null && this.value == null) || ((P) other).getValue().equals(this.value));
+ ((((P) other).getOriginalValue() == null && this.originalValue == null) || ((P) other).getOriginalValue().equals(this.originalValue));
}
@Override
public String toString() {
- return null == this.value ? this.biPredicate.toString() : this.biPredicate.toString() + "(" + this.value + ")";
+ return null == this.originalValue ? this.biPredicate.toString() : this.biPredicate.toString() + "(" + this.originalValue + ")";
}
@Override
public P<V> negate() {
- return new P<>(this.biPredicate.negate(), this.value);
+ return new P<>(this.biPredicate.negate(), this.originalValue);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c20b46eb/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
index fb35ead..2fb7232 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java
@@ -18,8 +18,10 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConjunctionStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.EngineDependentStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.MatchAlgorithmStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.ProfileStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.finalization.ScopingStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.AdjacentToIncidentStrategy;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c20b46eb/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 1ac0663..97d509d 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
@@ -45,6 +45,7 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -56,7 +57,6 @@ import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
-import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -65,8 +65,6 @@ import java.util.stream.Stream;
*/
public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>> implements TraversalParent, Scoping {
- private static final Supplier<MatchAlgorithm> MATCH_ALGORITHM = CountMatchAlgorithm::new;
-
private List<Traversal.Admin<Object, Object>> matchTraversals = new ArrayList<>();
private boolean first = true;
private Set<String> matchStartLabels = new HashSet<>();
@@ -74,7 +72,8 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
private Set<String> scopeKeys = null;
private final ConjunctionStep.Conjunction conjunction;
private final String startKey;
- private MatchAlgorithm matchAlgorithm = MATCH_ALGORITHM.get();
+ private MatchAlgorithm matchAlgorithm;
+ private Class<? extends MatchAlgorithm> matchAlgorithmClass = CountMatchAlgorithm.class; // default is CountMatchAlgorithm (use MatchAlgorithmStrategy to change)
public MatchStep(final Traversal.Admin traversal, final String startKey, final ConjunctionStep.Conjunction conjunction, final Traversal... matchTraversals) {
super(traversal);
@@ -206,9 +205,11 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
this.first = true;
}
+ public void setMatchAlgorithm(final Class<? extends MatchAlgorithm> matchAlgorithmClass) {
+ this.matchAlgorithmClass = matchAlgorithmClass;
+ }
+
public MatchAlgorithm getMatchAlgorithm() {
- if (!this.matchAlgorithm.initialized()) // this is important in clone()ing situations where you need the match algorithm to reinitialize
- this.matchAlgorithm.initialize(this.matchTraversals);
return this.matchAlgorithm;
}
@@ -219,7 +220,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
for (final Traversal.Admin<Object, Object> traversal : this.matchTraversals) {
clone.matchTraversals.add(clone.integrateChild(traversal.clone()));
}
- clone.matchAlgorithm = MATCH_ALGORITHM.get();
+ clone.initializeMatchAlgorithm();
return clone;
}
@@ -246,12 +247,22 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
return bindings;
}
+ private void initializeMatchAlgorithm() {
+ try {
+ this.matchAlgorithm = this.matchAlgorithmClass.getConstructor().newInstance();
+ } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ this.matchAlgorithm.initialize(this.matchTraversals);
+ }
+
@Override
protected Iterator<Traverser<Map<String, E>>> standardAlgorithm() throws NoSuchElementException {
while (true) {
Traverser.Admin traverser = null;
if (this.first) {
this.first = false;
+ this.initializeMatchAlgorithm();
} else {
for (final Traversal.Admin<?, ?> matchTraversal : this.matchTraversals) {
if (matchTraversal.hasNext()) {
@@ -285,7 +296,6 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
traverser.setStepId(this.getNextStep().getId());
return IteratorUtils.of(traverser.split(this.getBindings(traverser), this));
}
-
if (this.conjunction == ConjunctionStep.Conjunction.AND) {
final Traversal.Admin<Object, Object> matchTraversal = this.getMatchAlgorithm().apply(traverser); // determine which sub-pattern the traverser should try next
traverser.setStepId(matchTraversal.getStartStep().getId()); // go down the traversal match sub-pattern
@@ -443,8 +453,6 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
return traversal.getStartStep() instanceof WhereStep || traversal.getStartStep().getNextStep() instanceof WhereStep;
}
- public boolean initialized();
-
public void initialize(final List<Traversal.Admin<Object, Object>> traversals);
public default void recordStart(final Traverser.Admin<Object> traverser, final Traversal.Admin<Object, Object> traversal) {
@@ -459,19 +467,14 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
public static class GreedyMatchAlgorithm implements MatchAlgorithm {
private List<Traversal.Admin<Object, Object>> traversals;
- private List<String> traversalLabels = new ArrayList<>();
- private List<Set<String>> requiredLabels = new ArrayList<>();
- private boolean initialized = false;
-
- @Override
- public boolean initialized() {
- return this.initialized;
- }
+ private List<String> traversalLabels;
+ private List<Set<String>> requiredLabels;
@Override
public void initialize(final List<Traversal.Admin<Object, Object>> traversals) {
- this.initialized = true;
this.traversals = traversals;
+ this.traversalLabels = new ArrayList<>();
+ this.requiredLabels = new ArrayList<>();
for (final Traversal.Admin<Object, Object> traversal : this.traversals) {
this.traversalLabels.add(traversal.getStartStep().getId());
this.requiredLabels.add(MatchAlgorithm.getRequiredLabels(traversal));
@@ -493,20 +496,13 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
public static class CountMatchAlgorithm implements MatchAlgorithm {
protected List<Traversal.Admin<Object, Object>> traversals;
- protected List<Integer[]> counts = new ArrayList<>();
- protected List<String> traversalLabels = new ArrayList<>();
- protected List<Set<String>> requiredLabels = new ArrayList<>();
- protected Map<Traversal.Admin<Object, Object>, Boolean> whereTraversals = new HashMap<>();
- private boolean initialized = false;
-
- @Override
- public boolean initialized() {
- return this.initialized;
- }
+ protected List<Integer[]> counts;
+ protected List<String> traversalLabels;
+ protected List<Set<String>> requiredLabels;
+ protected Map<Traversal.Admin<Object, Object>, Boolean> whereTraversals;
@Override
public void initialize(final List<Traversal.Admin<Object, Object>> traversals) {
- this.initialized = true;
this.traversals = traversals;
this.whereTraversals = new HashMap<>();
this.counts = new ArrayList<>();
@@ -535,8 +531,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
public void recordEnd(final Traverser.Admin<Object> traverser, final Traversal.Admin<Object, Object> traversal) {
final int currentIndex = this.traversals.indexOf(traversal);
this.counts.stream().filter(array -> currentIndex == array[0]).findAny().get()[1]++;
- final boolean isWhereTraversal = MatchAlgorithm.isWhereTraversal(traversal); // this.whereTraversals.get(traversal); // TODO: cloning issue again!
- Collections.sort(this.counts, (a, b) -> isWhereTraversal ? 1 : a[1].compareTo(b[1]));
+ Collections.sort(this.counts, (a, b) -> this.whereTraversals.get(traversal) ? 1 : a[1].compareTo(b[1]));
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c20b46eb/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
new file mode 100644
index 0000000..32e0ea0
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/finalization/MatchAlgorithmStrategy.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * * 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.strategy.finalization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class MatchAlgorithmStrategy extends AbstractTraversalStrategy<TraversalStrategy.FinalizationStrategy> implements TraversalStrategy.FinalizationStrategy {
+
+ private final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass;
+
+ private MatchAlgorithmStrategy(final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass) {
+ this.matchAlgorithmClass = matchAlgorithmClass;
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ if (!TraversalHelper.hasStepOfClass(MatchStep.class, traversal))
+ return;
+ TraversalHelper.getStepsOfClass(MatchStep.class, traversal).forEach(matchStep -> matchStep.setMatchAlgorithm(this.matchAlgorithmClass));
+ }
+
+ public static Builder build() {
+ return new Builder();
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.traversalStrategyString(this);
+ }
+
+ public final static class Builder {
+
+ private Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass = MatchStep.CountMatchAlgorithm.class;
+
+ private Builder() {
+ }
+
+ public Builder algorithm(final Class<? extends MatchStep.MatchAlgorithm> matchAlgorithmClass) {
+ this.matchAlgorithmClass = matchAlgorithmClass;
+ return this;
+ }
+
+
+ public MatchAlgorithmStrategy create() {
+ return new MatchAlgorithmStrategy(this.matchAlgorithmClass);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c20b46eb/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
index a52fe4f..0a1b13f 100644
--- a/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
+++ b/gremlin-groovy-test/src/main/groovy/org/apache/tinkerpop/gremlin/process/traversal/step/filter/GroovyWhereTest.groovy
@@ -81,8 +81,8 @@ public abstract class GroovyWhereTest {
}
@Override
- public Traversal<Vertex, Vertex> get_g_VX1X_out_aggregateXxX_out_whereXwithoutXaXX(final Object v1Id) {
- TraversalScriptHelper.compute("g.V(v1Id).out.aggregate('x').out.where(without('x'))", g, "v1Id", v1Id)
+ public Traversal<Vertex, Vertex> get_g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX(final Object v1Id) {
+ TraversalScriptHelper.compute("g.V(v1Id).out.aggregate('x').out.where(not(within('x')))", g, "v1Id", v1Id)
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c20b46eb/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
index 77e753c..de7939a 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTest.java
@@ -68,7 +68,7 @@ public abstract class WhereTest extends AbstractGremlinProcessTest {
public abstract Traversal<Vertex, String> get_g_VX1X_asXaX_outXcreatedX_inXcreatedX_whereXneqXaXX_name(final Object v1Id);
- public abstract Traversal<Vertex, Vertex> get_g_VX1X_out_aggregateXxX_out_whereXwithoutXaXX(final Object v1Id);
+ public abstract Traversal<Vertex, Vertex> get_g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX(final Object v1Id);
public abstract Traversal<Vertex, Vertex> get_g_withSideEffectXa_graph_verticesX2XX_VX1X_out_whereXneqXaXX(final Object v1Id, final Object v2Id);
@@ -221,7 +221,7 @@ public abstract class WhereTest extends AbstractGremlinProcessTest {
@Test
@LoadGraphWith(MODERN)
public void g_VX1X_out_aggregateXxX_out_whereXwithout_xX() {
- final Traversal<Vertex, Vertex> traversal = get_g_VX1X_out_aggregateXxX_out_whereXwithoutXaXX(convertToVertexId("marko"));
+ final Traversal<Vertex, Vertex> traversal = get_g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX(convertToVertexId("marko"));
printTraversalForm(traversal);
assertEquals("ripple", traversal.next().<String>value("name"));
assertFalse(traversal.hasNext());
@@ -369,8 +369,8 @@ public abstract class WhereTest extends AbstractGremlinProcessTest {
}
@Override
- public Traversal<Vertex, Vertex> get_g_VX1X_out_aggregateXxX_out_whereXwithoutXaXX(final Object v1Id) {
- return g.V(v1Id).out().aggregate("x").out().where(without("x"));
+ public Traversal<Vertex, Vertex> get_g_VX1X_out_aggregateXxX_out_whereXnotXwithinXaXXX(final Object v1Id) {
+ return g.V(v1Id).out().aggregate("x").out().where(not(within("x")));
}
@Override