You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by tw...@apache.org on 2016/07/08 12:39:19 UTC
[01/50] [abbrv] tinkerpop git commit: Made TinkerGraph validate that
ids be homogeneous up front. [Forced Update!]
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1254 e32808a32 -> 88c5d27bd (forced update)
Made TinkerGraph validate that ids be homogeneous up front.
Take this approach rather than doing it during iteration so that TinkerPop semantics are respected and appropriate validation exceptions are thrown at the right time.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e59b93ca
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e59b93ca
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e59b93ca
Branch: refs/heads/TINKERPOP-1254
Commit: e59b93ca4ec7ffbde4a4b91319f35f5d3fd9caeb
Parents: 70dd324
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 16 15:08:30 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 16 15:08:30 2016 -0400
----------------------------------------------------------------------
.../tinkergraph/structure/TinkerGraph.java | 41 ++++++++------------
1 file changed, 17 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e59b93ca/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
index 168dd7f..edffab9 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
@@ -326,30 +326,15 @@ public final class TinkerGraph implements Graph {
return elements.values().iterator();
} else {
final List<Object> idList = Arrays.asList(ids);
- // base the conversion function on the first item in the id list as the expectation is that these
- // id values will be a uniform list
- if (clazz.isAssignableFrom(ids[0].getClass())) {
- // got a bunch of Elements - have to look each up because it might be an Attachable instance or
- // other implementation. the assumption is that id conversion is not required for detached
- // stuff - doesn't seem likely someone would detach a Titan vertex then try to expect that
- // vertex to be findable in OrientDB
- return IteratorUtils.filter(IteratorUtils.map(idList, id -> {
- // based on the first item assume all vertices in the argument list
- if (!clazz.isAssignableFrom(id.getClass()))
- throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
-
- return elements.get(clazz.cast(id).id());
- }).iterator(), Objects::nonNull);
- } else {
- final Class<?> firstClass = ids[0].getClass();
- return IteratorUtils.filter(IteratorUtils.map(idList, id -> {
- // all items in the list should be of the same class - don't get fancy on a Graph
- if (!id.getClass().equals(firstClass))
- throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
-
- return elements.get(idManager.convert(id));
- }).iterator(), Objects::nonNull);
- }
+ validateHomogenousIds(idList);
+
+ // if the type is of Element - have to look each up because it might be an Attachable instance or
+ // other implementation. the assumption is that id conversion is not required for detached
+ // stuff - doesn't seem likely someone would detach a Titan vertex then try to expect that
+ // vertex to be findable in OrientDB
+ return clazz.isAssignableFrom(ids[0].getClass()) ?
+ IteratorUtils.filter(IteratorUtils.map(idList, id -> elements.get(clazz.cast(id).id())).iterator(), Objects::nonNull)
+ : IteratorUtils.filter(IteratorUtils.map(idList, id -> elements.get(idManager.convert(id))).iterator(), Objects::nonNull);
}
}
@@ -365,6 +350,14 @@ public final class TinkerGraph implements Graph {
return features;
}
+ private void validateHomogenousIds(final List<Object> ids) {
+ final Class firstClass = ids.get(0).getClass();
+ for (Object id : ids) {
+ if (!id.getClass().equals(firstClass))
+ throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
+ }
+ }
+
public class TinkerGraphFeatures implements Features {
private final TinkerGraphGraphFeatures graphFeatures = new TinkerGraphGraphFeatures();
[22/50] [abbrv] tinkerpop git commit: came up with a nice
optimization. If the step after the repeat() is a Barrier,
then there is no need to add a NoOpBarrier on the last loop serialization.
Also, discovered a severe clone() bug in AbstractStep around l
Posted by tw...@apache.org.
came up with a nice optimization. If the step after the repeat() is a Barrier, then there is no need to add a NoOpBarrier on the last loop serialization. Also, discovered a severe clone() bug in AbstractStep around label cloning. Can't believe this never popped up before now.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6208b90b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6208b90b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6208b90b
Branch: refs/heads/TINKERPOP-1254
Commit: 6208b90b2ca297186b4f75f356e0093d4b6ed280
Parents: 8753366
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 28 13:03:15 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 28 13:03:15 2016 -0600
----------------------------------------------------------------------
.../process/traversal/step/util/AbstractStep.java | 5 +++--
.../optimization/RepeatUnrollStrategy.java | 17 ++++++++++++-----
.../optimization/RepeatUnrollStrategyTest.java | 1 +
3 files changed, 16 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6208b90b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
index 2f83e9e..9eb1b3c 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/AbstractStep.java
@@ -124,7 +124,7 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
}
} else {
while (true) {
- if(Thread.interrupted()) throw new TraversalInterruptedException();
+ if (Thread.interrupted()) throw new TraversalInterruptedException();
final Traverser.Admin<E> traverser = this.processNextStart();
if (null != traverser.get() && 0 != traverser.bulk())
return this.prepareTraversalForNextStep(traverser);
@@ -139,7 +139,7 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
else {
try {
while (true) {
- if(Thread.interrupted()) throw new TraversalInterruptedException();
+ if (Thread.interrupted()) throw new TraversalInterruptedException();
this.nextEnd = this.processNextStart();
if (null != this.nextEnd.get() && 0 != this.nextEnd.bulk())
return true;
@@ -179,6 +179,7 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
clone.nextStep = EmptyStep.instance();
clone.nextEnd = null;
clone.traversal = EmptyTraversal.instance();
+ clone.labels = new LinkedHashSet<>(this.labels);
clone.reset();
return clone;
} catch (final CloneNotSupportedException e) {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6208b90b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
index 9047478..2139e81 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
@@ -23,6 +23,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.LoopTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
@@ -50,18 +51,24 @@ public final class RepeatUnrollStrategy extends AbstractTraversalStrategy<Traver
if (null == repeatStep.getEmitTraversal() && repeatStep.getUntilTraversal() instanceof LoopTraversal) {
final Traversal.Admin<?, ?> repeatTraversal = repeatStep.getGlobalChildren().get(0);
final int repeatLength = repeatTraversal.getSteps().size() - 1;
- repeatTraversal.removeStep(repeatLength);
+ repeatTraversal.removeStep(repeatLength); // removes the RepeatEndStep
int insertIndex = i;
final int loops = (int) ((LoopTraversal) repeatStep.getUntilTraversal()).getMaxLoops();
for (int j = 0; j < loops; j++) {
- TraversalHelper.insertTraversal(insertIndex, repeatTraversal.clone(), traversal); // removes the RepeatEndStep
+ TraversalHelper.insertTraversal(insertIndex, repeatTraversal.clone(), traversal);
insertIndex = insertIndex + repeatLength + 1;
traversal.addStep(insertIndex, new NoOpBarrierStep<>(traversal));
}
- if (!repeatStep.getLabels().isEmpty()) {
- final Step<?, ?> lastStep = (Step) traversal.getSteps().get(insertIndex);
- repeatStep.getLabels().forEach(lastStep::addLabel);
+
+ final NoOpBarrierStep<?> lastStep = (NoOpBarrierStep) traversal.getSteps().get(insertIndex);
+ Step<?, ?> labelStep = lastStep;
+ if (lastStep.getNextStep() instanceof Barrier) {
+ labelStep = traversal.getSteps().get(insertIndex - 1);
+ traversal.removeStep(insertIndex); // remove last NoOpBarrierStep
}
+ if (!repeatStep.getLabels().isEmpty())
+ repeatStep.getLabels().forEach(labelStep::addLabel);
+
traversal.removeStep(i); // remove the RepeatStep
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6208b90b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
index 1c4c4b7..b819331 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
@@ -90,6 +90,7 @@ public class RepeatUnrollStrategyTest {
{__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)},
{__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()},
{__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()},
+ {__.in().repeat(__.out("knows")).times(3).as("a").count().is(0), __.in().out("knows").barrier().out("knows").barrier().out("knows").as("a").count().is(0)},
});
}
[50/50] [abbrv] tinkerpop git commit: TINKERPOP-1254 Support dropping
traverser path information when it is no longer needed
Posted by tw...@apache.org.
TINKERPOP-1254 Support dropping traverser path information when it is no longer needed
This commit adds support for path retraction to increase the likelihood of bulking in OLTP and OLAP modes. Traversal analysis is performed during the application of the PrunePathStrategy to identify labels that may be dropped at various points in the traversal. MatchStep also performs runtime analysis to determine which labels it can drop in addition to the labels identified during traversal strategy application.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/88c5d27b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/88c5d27b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/88c5d27b
Branch: refs/heads/TINKERPOP-1254
Commit: 88c5d27bd4d0e2bb898be7f4c3a86007d6422174
Parents: a138d55
Author: Ted Wilmes <tw...@gmail.com>
Authored: Fri Jul 8 07:37:41 2016 -0500
Committer: Ted Wilmes <tw...@gmail.com>
Committed: Fri Jul 8 07:37:41 2016 -0500
----------------------------------------------------------------------
.../gremlin/process/traversal/Path.java | 8 +
.../process/traversal/TraversalStrategies.java | 4 +-
.../gremlin/process/traversal/Traverser.java | 6 +
.../process/traversal/step/PathProcessor.java | 15 ++
.../traversal/step/filter/DedupGlobalStep.java | 16 ++
.../step/filter/WherePredicateStep.java | 21 ++-
.../step/filter/WhereTraversalStep.java | 15 ++
.../process/traversal/step/map/MatchStep.java | 78 ++++++++-
.../process/traversal/step/map/PathStep.java | 16 ++
.../traversal/step/map/SelectOneStep.java | 18 ++
.../process/traversal/step/map/SelectStep.java | 16 ++
.../process/traversal/step/map/TreeStep.java | 9 +
.../step/sideEffect/TreeSideEffectStep.java | 9 +
.../process/traversal/step/util/EmptyPath.java | 3 +
.../traversal/step/util/ImmutablePath.java | 126 ++++++++++++++
.../traversal/step/util/MutablePath.java | 33 +++-
.../optimization/PrunePathStrategy.java | 172 +++++++++++++++++++
.../traverser/B_LP_O_S_SE_SL_Traverser.java | 42 +++++
.../traverser/LP_O_OB_P_S_SE_SL_Traverser.java | 28 +++
.../traverser/util/AbstractTraverser.java | 16 ++
.../traverser/util/EmptyTraverser.java | 15 ++
.../process/traversal/util/PathUtil.java | 77 +++++++++
.../gremlin/process/traversal/PathTest.java | 11 ++
.../traversal/step/map/MatchStepTest.java | 46 +++++
.../optimization/PrunePathStrategyTest.java | 118 +++++++++++++
.../structure/TinkerGraphPlayTest.java | 16 +-
26 files changed, 925 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
index a302165..c4bc347 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Path.java
@@ -66,6 +66,14 @@ public interface Path extends Cloneable, Iterable<Object> {
public Path extend(final Set<String> labels);
/**
+ * Remove labels from path.
+ *
+ * @param labels the labels to remove
+ * @return the path with removed labels
+ */
+ public Path retract(final Set<String> labels);
+
+ /**
* Get the object associated with the particular label of the path.
* If the path as multiple labels of the type, then return a {@link List} of those objects.
*
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/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 b093676..850db9f 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
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.Inci
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.MatchPredicateStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.OrderLimitStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathProcessorStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PrunePathStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ComputerVerificationStrategy;
@@ -197,7 +198,8 @@ public interface TraversalStrategies extends Serializable, Cloneable {
RepeatUnrollStrategy.instance(),
RangeByIsCountStrategy.instance(),
ProfileStrategy.instance(),
- StandardVerificationStrategy.instance());
+ StandardVerificationStrategy.instance(),
+ PrunePathStrategy.instance());
GRAPH_CACHE.put(Graph.class, graphStrategies);
GRAPH_CACHE.put(EmptyGraph.class, new DefaultTraversalStrategies());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
index 0a36b2c..0c37a34 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traverser.java
@@ -183,6 +183,12 @@ public interface Traverser<T> extends Serializable, Comparable<Traverser<T>>, Cl
public void addLabels(final Set<String> labels);
+ public void keepLabels(final Set<String> labels);
+
+ public void dropLabels(final Set<String> labels);
+
+ public void dropPath();
+
/**
* Set the current object location of the traverser.
*
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PathProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PathProcessor.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PathProcessor.java
index 48a9cc3..7d8a497 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PathProcessor.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/PathProcessor.java
@@ -19,11 +19,14 @@
package org.apache.tinkerpop.gremlin.process.traversal.step;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
import org.apache.tinkerpop.gremlin.structure.T;
+import java.util.Set;
+
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
@@ -56,4 +59,16 @@ public interface PathProcessor {
}
return max;
}
+
+ void setKeepLabels(final Set<String> labels);
+
+ static void keepLabels(final Traverser traverser, final Set<String> labels) {
+ if(labels == null || labels.isEmpty()) {
+ return;
+ } else {
+ traverser.asAdmin().keepLabels(labels);
+ }
+ }
+
+ Set<String> getKeepLabels();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
index 9336a1a..78fd429 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/DedupGlobalStep.java
@@ -56,6 +56,7 @@ public final class DedupGlobalStep<S> extends FilterStep<S> implements Traversal
private Set<Object> duplicateSet = new HashSet<>();
private boolean onGraphComputer = false;
private final Set<String> dedupLabels;
+ private Set<String> keepLabels;
public DedupGlobalStep(final Traversal.Admin traversal, final String... dedupLabels) {
super(traversal);
@@ -81,6 +82,13 @@ public final class DedupGlobalStep<S> extends FilterStep<S> implements Traversal
}
@Override
+ protected Traverser.Admin<S> processNextStart() {
+ final Traverser.Admin<S> traverser = super.processNextStart();
+ PathProcessor.keepLabels(traverser, keepLabels);
+ return traverser;
+ }
+
+ @Override
public List<Traversal<S, Object>> getLocalChildren() {
return null == this.dedupTraversal ? Collections.emptyList() : Collections.singletonList(this.dedupTraversal);
}
@@ -193,4 +201,12 @@ public final class DedupGlobalStep<S> extends FilterStep<S> implements Traversal
public MemoryComputeKey<Map<Object, Traverser.Admin<S>>> getMemoryComputeKey() {
return MemoryComputeKey.of(this.getId(), (BinaryOperator) Operator.addAll, false, true);
}
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
index 6fea7d6..0ee7832 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WherePredicateStep.java
@@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.P;
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.PathProcessor;
import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
@@ -33,12 +34,13 @@ import java.util.*;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public final class WherePredicateStep<S> extends FilterStep<S> implements Scoping {
+public final class WherePredicateStep<S> extends FilterStep<S> implements Scoping, PathProcessor {
protected String startKey;
protected List<String> selectKeys;
protected P<Object> predicate;
protected final Set<String> scopeKeys = new HashSet<>();
+ protected Set<String> keepLabels;
public WherePredicateStep(final Traversal.Admin traversal, final Optional<String> startKey, final P<String> predicate) {
super(traversal);
@@ -115,4 +117,21 @@ public final class WherePredicateStep<S> extends FilterStep<S> implements Scopin
TYPICAL_GLOBAL_REQUIREMENTS :
TYPICAL_LOCAL_REQUIREMENTS;
}
+
+ @Override
+ protected Traverser.Admin<S> processNextStart() {
+ final Traverser.Admin<S> traverser = super.processNextStart();
+ PathProcessor.keepLabels(traverser, keepLabels);
+ return traverser;
+ }
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() {
+ return this.keepLabels;
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
index 388104d..078a370 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/WhereTraversalStep.java
@@ -46,6 +46,7 @@ public final class WhereTraversalStep<S> extends FilterStep<S> implements Traver
protected Traversal.Admin<?, ?> whereTraversal;
protected final Set<String> scopeKeys = new HashSet<>();
+ protected Set<String> keepLabels;
public WhereTraversalStep(final Traversal.Admin traversal, final Traversal<?, ?> whereTraversal) {
super(traversal);
@@ -88,6 +89,12 @@ public final class WhereTraversalStep<S> extends FilterStep<S> implements Traver
ElementRequirement.ID;
}
+ @Override
+ protected Traverser.Admin<S> processNextStart() {
+ final Traverser.Admin<S> traverser = super.processNextStart();
+ PathProcessor.keepLabels(traverser, keepLabels);
+ return traverser;
+ }
@Override
protected boolean filter(final Traverser.Admin<S> traverser) {
@@ -134,6 +141,14 @@ public final class WhereTraversalStep<S> extends FilterStep<S> implements Traver
TYPICAL_LOCAL_REQUIREMENTS;
}
+ @Override
+ public void setKeepLabels(Set<String> keepLabels) {
+ this.keepLabels = keepLabels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
+
//////////////////////////////
public static class WhereStartStep<S> extends MapStep<S, Object> implements Scoping {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/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 c6e3bbe..3fb45fc 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
@@ -19,6 +19,7 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
import org.apache.tinkerpop.gremlin.process.traversal.*;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PathProcessor;
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.step.filter.*;
@@ -30,6 +31,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierS
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConnectiveStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.util.PathUtil;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
@@ -44,7 +46,7 @@ import java.util.stream.Stream;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>> implements TraversalParent, Scoping {
+public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>> implements TraversalParent, Scoping, PathProcessor {
public enum TraversalType {WHERE_PREDICATE, WHERE_TRAVERSAL, MATCH_TRAVERSAL}
@@ -60,6 +62,7 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
private Set<List<Object>> dedups = null;
private Set<String> dedupLabels = null;
+ private Set<String> keepLabels = null;
public MatchStep(final Traversal.Admin traversal, final ConnectiveStep.Connective connective, final Traversal... matchTraversals) {
super(traversal);
@@ -135,6 +138,8 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
}
}
+
+
public ConnectiveStep.Connective getConnective() {
return this.connective;
}
@@ -368,6 +373,26 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
}
}
+ protected List<Traversal.Admin> getRemainingTraversals(final Traverser.Admin traverser) {
+ final Set<String> tags = traverser.getTags();
+ final List<Traversal.Admin> remainingTraversals = new ArrayList<>();
+ for (final Traversal.Admin matchTraversal : matchTraversals) {
+ if (!tags.contains(matchTraversal.getStartStep().getId())) {
+ remainingTraversals.add(matchTraversal);
+ } else {
+ // include the current traversal that the traverser is executing in the list of
+ // remaining traversals
+ for (final Step<?, ?> s : (List<Step<?, ?>>)matchTraversal.getSteps()) {
+ if (s.getId().equals(traverser.getStepId())) {
+ remainingTraversals.add(matchTraversal);
+ break;
+ }
+ }
+ }
+ }
+ return remainingTraversals;
+ }
+
@Override
public int hashCode() {
int result = super.hashCode() ^ this.connective.hashCode();
@@ -382,6 +407,21 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
return this.getSelfAndChildRequirements(TraverserRequirement.LABELED_PATH, TraverserRequirement.SIDE_EFFECTS);
}
+ @Override
+ protected Traverser.Admin<Map<String, E>> processNextStart() throws NoSuchElementException {
+ final Traverser.Admin<Map<String, E>> traverser = super.processNextStart();
+ if (keepLabels != null) {
+ final Set<String> keepers = new HashSet<>();
+ List<Traversal.Admin> remainingTraversals = getRemainingTraversals(traverser);
+ for (Traversal.Admin trav : remainingTraversals) {
+ keepers.addAll(PathUtil.getReferencedLabels(trav));
+ }
+ keepers.addAll(keepLabels);
+ PathProcessor.keepLabels(traverser, keepers);
+ }
+ return traverser;
+ }
+
//////////////////////////////
public static class MatchStartStep extends AbstractStep<Object, Object> implements Scoping {
@@ -517,7 +557,13 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
}
public static boolean hasExecutedTraversal(final Traverser.Admin<Object> traverser, final Traversal.Admin<Object, Object> traversal) {
- return traverser.getTags().contains(traversal.getStartStep().getId());
+ final boolean hasExecuted = traverser.getTags().contains(traversal.getStartStep().getId());
+ if (hasExecuted) {
+ // This traverser has finished this traversal so it is safe to drop the tag label.
+ String traversalId = traversal.getStartStep().getId();
+ traverser.dropLabels(Collections.singleton(traversalId));
+ }
+ return hasExecuted;
}
public static TraversalType getTraversalType(final Traversal.Admin<Object, Object> traversal) {
@@ -552,7 +598,6 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
}
return 0;
});
- //System.out.println(sort);
return sort.get(0);
}
}
@@ -678,4 +723,31 @@ public final class MatchStep<S, E> extends ComputerAwareStep<S, Map<String, E>>
}
}
}
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ if (this.keepLabels != null) {
+ this.keepLabels.addAll(labels);
+ } else {
+ this.keepLabels = new HashSet<>(labels);
+ }
+ }
+
+ @Override
+ public Set<String> getKeepLabels() {
+ // add in start and end labels for this match b/c it's children may need to keep them
+ HashSet<String> keepThese = new HashSet<>();
+ if (keepLabels != null) {
+ keepThese.addAll(this.keepLabels);
+ }
+ keepThese.addAll(this.getMatchStartLabels());
+ keepThese.addAll(this.getMatchEndLabels());
+ return keepThese;
+ }
+
+ public Set<String> getMatchEndLabels() {
+ return this.matchEndLabels;
+ }
+
+ public Set<String> getMatchStartLabels() { return this.matchStartLabels; }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
index 039c2a9..885afc1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/PathStep.java
@@ -39,6 +39,7 @@ import java.util.Set;
public final class PathStep<S> extends MapStep<S, Path> implements TraversalParent, PathProcessor, ByModulating {
private TraversalRing<Object, Object> traversalRing;
+ private Set<String> keepLabels;
public PathStep(final Traversal.Admin traversal) {
super(traversal);
@@ -101,4 +102,19 @@ public final class PathStep<S> extends MapStep<S, Path> implements TraversalPare
public Set<TraverserRequirement> getRequirements() {
return this.getSelfAndChildRequirements(TraverserRequirement.PATH);
}
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ protected Traverser.Admin<Path> processNextStart() {
+ final Traverser.Admin<Path> traverser = super.processNextStart();
+ PathProcessor.keepLabels(traverser, keepLabels);
+ return traverser;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/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 fa38903..3bd5c1d 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
@@ -42,6 +42,7 @@ public final class SelectOneStep<S, E> extends MapStep<S, E> implements Traversa
private final Pop pop;
private final String selectKey;
private Traversal.Admin<S, E> selectTraversal = null;
+ private Set<String> keepLabels;
public SelectOneStep(final Traversal.Admin traversal, Pop pop, final String selectKey) {
super(traversal);
@@ -115,6 +116,23 @@ public final class SelectOneStep<S, E> extends MapStep<S, E> implements Traversa
public Pop getPop() {
return this.pop;
}
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
+
+ @Override
+ protected Traverser.Admin<E> processNextStart() {
+ final Traverser.Admin<E> traverser = super.processNextStart();
+ if(!(this.getTraversal().getParent() instanceof MatchStep)) {
+ PathProcessor.keepLabels(traverser, keepLabels);
+ }
+ return traverser;
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/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 af8cfdb..ecd5581 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
@@ -49,6 +49,7 @@ public final class SelectStep<S, E> extends MapStep<S, Map<String, E>> implement
private final Pop pop;
private final List<String> selectKeys;
private final Set<String> selectKeysSet;
+ private Set<String> keepLabels;
public SelectStep(final Traversal.Admin traversal, final Pop pop, final String... selectKeys) {
super(traversal);
@@ -141,4 +142,19 @@ public final class SelectStep<S, E> extends MapStep<S, Map<String, E>> implement
public Pop getPop() {
return this.pop;
}
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
+
+ @Override
+ protected Traverser.Admin<Map<String, E>> processNextStart() {
+ final Traverser.Admin<Map<String, E>> traverser = super.processNextStart();
+ PathProcessor.keepLabels(traverser, keepLabels);
+ return traverser;
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TreeStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TreeStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TreeStep.java
index 3573b98..a3fb054 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TreeStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TreeStep.java
@@ -44,6 +44,7 @@ import java.util.function.Supplier;
public final class TreeStep<S> extends ReducingBarrierStep<S, Tree> implements TraversalParent, ByModulating, PathProcessor {
private TraversalRing<Object, Object> traversalRing = new TraversalRing<>();
+ private Set<String> keepLabels;
public TreeStep(final Traversal.Admin traversal) {
super(traversal);
@@ -111,6 +112,14 @@ public final class TreeStep<S> extends ReducingBarrierStep<S, Tree> implements T
this.traversalRing.reset();
}
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
+
///////////
public static final class TreeBiOperator implements BinaryOperator<Tree>, Serializable {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TreeSideEffectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TreeSideEffectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TreeSideEffectStep.java
index 18a4798..6351455 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TreeSideEffectStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/TreeSideEffectStep.java
@@ -44,6 +44,7 @@ public final class TreeSideEffectStep<S> extends SideEffectStep<S> implements Si
private TraversalRing<Object, Object> traversalRing;
private String sideEffectKey;
+ private Set<String> keepLabels;
public TreeSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey) {
super(traversal);
@@ -115,4 +116,12 @@ public final class TreeSideEffectStep<S> extends SideEffectStep<S> implements Si
public Set<TraverserRequirement> getRequirements() {
return this.getSelfAndChildRequirements(TraverserRequirement.PATH, TraverserRequirement.SIDE_EFFECTS);
}
+
+ @Override
+ public void setKeepLabels(Set<String> labels) {
+ this.keepLabels = labels;
+ }
+
+ @Override
+ public Set<String> getKeepLabels() { return this.keepLabels; }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/EmptyPath.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/EmptyPath.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/EmptyPath.java
index c40f228..0c6827e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/EmptyPath.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/EmptyPath.java
@@ -52,6 +52,9 @@ public final class EmptyPath implements Path, Serializable {
}
@Override
+ public Path retract(final Set<String> labels) { return this; }
+
+ @Override
public <A> A get(final String label) {
throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
index 1e936c8..68ee2b9 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ImmutablePath.java
@@ -24,6 +24,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -76,6 +77,125 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
}
@Override
+ public Path retract(final Set<String> labels) {
+ if (labels == null || labels.isEmpty()) {
+ return this;
+ }
+
+ // first see if the labels in the set are even present in this path
+ boolean found = false;
+ for (final Set<String> labelSet : labels()) {
+ if (!Collections.disjoint(labelSet, labels)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ return this;
+ }
+
+ if (this.previousPath instanceof TailPath) {
+ ImmutablePath clone = cloneImmutablePath(this);
+ clone.currentLabels.removeAll(labels);
+ clone.previousPath = TailPath.instance();
+ if (clone.currentLabels.isEmpty()) {
+ // return the previous tail path because this path segment can be dropped
+ return clone.previousPath;
+ }
+ return clone;
+ }
+
+ ImmutablePath parent;
+ ImmutablePath child;
+ if (this.previousPath != null) {
+ parent = this;
+ child = (ImmutablePath)this.previousPath;
+ } else {
+ parent = (ImmutablePath)this.previousPath;
+ child = this;
+ }
+
+ if (!Collections.disjoint(parent.currentLabels, labels)) {
+ ImmutablePath clonedParent = cloneImmutablePath(parent);
+ clonedParent.currentLabels.removeAll(labels);
+ if (clonedParent.currentLabels.isEmpty()) {
+ parent = (ImmutablePath) parent.previousPath;
+ } else {
+ parent = clonedParent;
+ }
+ }
+
+ // store the head and return it at the end of this
+ ImmutablePath head = parent;
+
+ // parents can be a mixture of ImmutablePaths and collapsed
+ // cloned ImmutablePaths that are a result of branching
+ List<Object> parents = new ArrayList<>();
+ parents.add(parent);
+
+ while(true) {
+ if (Collections.disjoint(child.currentLabels, labels)) {
+ parents.add(child);
+ if (child.previousPath instanceof TailPath) {
+ break;
+ }
+ child = (ImmutablePath)child.previousPath;
+ continue;
+ }
+ // split path
+ // clone child
+ ImmutablePath clone = cloneImmutablePath(child);
+ clone.currentLabels.removeAll(labels);
+ if (clone.currentLabels.isEmpty()) {
+ clone.currentObject = null;
+ }
+
+ // walk back up and build parent clones or reuse
+ // other previously cloned paths
+ boolean headFound = false;
+ if (parents.size() > 0) {
+ boolean first = true;
+ // construct parents up to this point
+ ImmutablePath newPath = cloneImmutablePath((ImmutablePath)parents.get(0));
+ // replace the previous
+ ImmutablePath prevPath = newPath;
+ ImmutablePath lastPath = prevPath;
+ if (!headFound) {
+ head = newPath;
+ }
+ for (int i = 1; i < parents.size(); i++) {
+ ImmutablePath clonedPrev = cloneImmutablePath((ImmutablePath) parents.get(i));
+ prevPath.previousPath = clonedPrev;
+ lastPath = clonedPrev;
+ prevPath = clonedPrev;
+ }
+
+ if (clone.currentLabels.isEmpty()) {
+ lastPath.previousPath = clone.previousPath;
+ } else {
+ lastPath.previousPath = clone;
+ }
+
+ parents = new ArrayList<>();
+ parents.add(lastPath);
+
+ if (child.previousPath instanceof TailPath) {
+ break;
+ }
+
+ child = (ImmutablePath)child.previousPath;
+ }
+ }
+
+ return head;
+ }
+
+ private static ImmutablePath cloneImmutablePath(final ImmutablePath path) {
+ return new ImmutablePath(path.previousPath, path.currentObject, new HashSet<>(path.currentLabels));
+ }
+
+ @Override
public <A> A get(final int index) {
return (this.size() - 1) == index ? (A) this.currentObject : this.previousPath.get(index);
}
@@ -195,6 +315,12 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
@Override
public Path extend(final Set<String> labels) {
+ if (labels.size() == 0) { return this; }
+ throw new UnsupportedOperationException("A head path can not have labels added to it");
+ }
+
+ @Override
+ public Path retract(final Set<String> labels) {
throw new UnsupportedOperationException("A head path can not have labels added to it");
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
index 0a35f90..02d95c1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/MutablePath.java
@@ -80,7 +80,38 @@ public class MutablePath implements Path, Serializable {
@Override
public Path extend(final Set<String> labels) {
- this.labels.get(this.labels.size() - 1).addAll(labels);
+ if(labels.size() > 0) {
+ this.labels.get(this.labels.size() - 1).addAll(labels);
+ }
+ return this;
+ }
+
+ @Override
+ public Path retract(final Set<String> removeLabels) {
+ for (int i = this.labels.size() - 1; i >= 0; i--) {
+ for (final String label : removeLabels) {
+ synchronized (this.labels.get(i)) {
+ if (this.labels.get(i).isEmpty()) {
+ this.labels.remove(i);
+ this.objects.remove(i);
+ continue;
+ }
+ if (this.labels.get(i).contains(label)) {
+ this.labels.get(i).remove(label);
+ boolean empty = false;
+ if (this.labels.get(i).size() == 0) {
+ this.labels.remove(i);
+ this.objects.remove(i);
+ empty = true;
+ }
+ // label was found, so break out
+ if (empty) {
+ break;
+ }
+ }
+ }
+ }
+ }
return this;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
new file mode 100644
index 0000000..ebb6b66
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategy.java
@@ -0,0 +1,172 @@
+/*
+ * 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.optimization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PathProcessor;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.PathStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.SubgraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.PathUtil;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Ted Wilmes (http://twilmes.org)
+ */
+public final class PrunePathStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements TraversalStrategy.OptimizationStrategy {
+
+ private static final PrunePathStrategy INSTANCE = new PrunePathStrategy();
+ private static final Set<Class<? extends OptimizationStrategy>> PRIORS = new HashSet<>();
+
+ static {
+ PRIORS.add(PathProcessorStrategy.class);
+ }
+
+ private PrunePathStrategy() {
+ }
+
+ public static PrunePathStrategy instance() {
+ return INSTANCE;
+ }
+
+ protected Set<String> getAndPropagateReferencedLabels(final Traversal.Admin<?, ?> traversal) {
+ if (traversal.getParent().equals(EmptyStep.instance())) {
+ return Collections.EMPTY_SET;
+ }
+ Step<?, ?> parent = traversal.getParent().asStep();
+ Set<String> referencedLabels = new HashSet<>();
+ // get referenced labels from this traversal
+ referencedLabels.addAll(PathUtil.getReferencedLabels(traversal));
+ Set<String> topLevelLabels = new HashSet<>();
+ while (true) {
+ // is this parent step in the top level traversal? If so, walk forwards and gather labels
+ // that should be kept because they are required in latter parts of the traversal
+ Step<?, ?> step;
+ boolean topLevelParent = false;
+ if (parent.getTraversal().getParent().equals(EmptyStep.instance())) {
+ step = parent;
+ topLevelParent = true;
+ } else {
+ // start at the beginning of the traversal
+ step = parent.getTraversal().getStartStep();
+ }
+ do {
+ Set<String> labels = PathUtil.getReferencedLabels(step);
+ if (topLevelParent) {
+ topLevelLabels.addAll(labels);
+ } else {
+ referencedLabels.addAll(labels);
+ }
+ step = step.getNextStep();
+ } while(!(step.equals(EmptyStep.instance())));
+ if (topLevelParent) {
+ step = parent;
+ do {
+ // if this is the top level traversal, propagate all nested labels
+ // to previous PathProcess steps
+ if (step instanceof PathProcessor) {
+ ((PathProcessor) step).getKeepLabels().addAll(referencedLabels);
+ }
+ step = step.getPreviousStep();
+ } while (!(step.equals(EmptyStep.instance())));
+ break;
+ } else {
+ parent = parent.getTraversal().getParent().asStep();
+ }
+ }
+ referencedLabels.addAll(topLevelLabels);
+ return referencedLabels;
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ TraversalParent parent = traversal.getParent();
+
+ Set<String> foundLabels = new HashSet<>();
+ Set<String> keepLabels = new HashSet<>();
+
+ // If this traversal has a parent, it will need to inherit its
+ // parent's keep labels. If its direct parent is not a PathProcessor,
+ // walk back up to the top level traversal and work forwards to determine which labels
+ // must be kept.
+ if (!parent.equals(EmptyStep.instance())) {
+ // start with parents keep labels
+ if (parent instanceof PathProcessor) {
+ PathProcessor parentPathProcess = (PathProcessor) parent;
+ if (parentPathProcess.getKeepLabels() != null) keepLabels.addAll(parentPathProcess.getKeepLabels());
+ } else {
+ Set<String> labels = getAndPropagateReferencedLabels(traversal);
+ keepLabels.addAll(labels);
+ }
+ }
+
+ // check if the traversal contains any path or subgraph steps and if
+ // it does, note it so that the keep labels are set to null later on
+ // which signals PathProcessors to not drop path information
+ boolean hasPathStep = false;
+ final List<PathStep> pathSteps = TraversalHelper.getStepsOfAssignableClassRecursively(PathStep.class, traversal);
+ final List<SubgraphStep> subgraphSteps = TraversalHelper.getStepsOfAssignableClassRecursively(SubgraphStep.class, traversal);
+ if (!pathSteps.isEmpty() || !subgraphSteps.isEmpty()) {
+ hasPathStep = true;
+ }
+
+ final List<Step> steps = traversal.getSteps();
+ for(int i = steps.size() - 1; i >= 0; i--) {
+ Step currentStep = steps.get(i);
+ if (!hasPathStep) {
+ // maintain our list of labels to keep, repeatedly adding labels that were found during
+ // the last iteration
+ keepLabels.addAll(foundLabels);
+
+ final Set<String> labels = PathUtil.getReferencedLabels(currentStep);
+ for (final String label : labels) {
+ if (foundLabels.contains(label)) {
+ keepLabels.add(label);
+ } else {
+ foundLabels.add(label);
+ }
+ }
+
+ if (currentStep instanceof PathProcessor) {
+ ((PathProcessor) currentStep).setKeepLabels(new HashSet<>(keepLabels));
+ }
+ } else {
+ // if there is a PathStep or SubgraphStep in the traversal, do not drop labels
+ if (currentStep instanceof PathProcessor) {
+ // set keep labels to null so that no labels are dropped
+ ((PathProcessor) currentStep).setKeepLabels(null);
+ }
+ }
+ }
+ }
+
+ @Override
+ public Set<Class<? extends OptimizationStrategy>> applyPrior() {
+ return PRIORS;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_Traverser.java
index b32126b..793ead6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_Traverser.java
@@ -23,8 +23,11 @@ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Step;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MutablePath;
import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
@@ -85,6 +88,45 @@ public class B_LP_O_S_SE_SL_Traverser<T> extends B_O_S_SE_SL_Traverser<T> {
}
@Override
+ public void keepLabels(final Set<String> labels) {
+ if (!labels.isEmpty()) {
+ Set<String> retractLabels = new HashSet<>();
+ List<Set<String>> existingLabels = this.path.labels();
+ for(Set<String> labelSet : existingLabels) {
+ for(String l : labelSet) {
+ if(labels.contains(l) == false) { retractLabels.add(l); };
+ }
+ }
+ this.path = this.path.retract(retractLabels);
+ } else if (labels.isEmpty()) {
+ Set<String> retractLabels = new HashSet<>();
+ List<Set<String>> existingLabels = this.path.labels();
+ for(Set<String> labelSet : existingLabels) {
+ retractLabels.addAll(labelSet);
+ }
+ if(!retractLabels.isEmpty()) {
+ this.path = this.path.retract(retractLabels);
+ }
+ }
+ }
+
+ @Override
+ public void dropLabels(final Set<String> labels) {
+ if(!labels.isEmpty()) {
+ this.path = this.path.retract(labels);
+ }
+ }
+
+ @Override
+ public void dropPath() {
+ if(path instanceof ImmutablePath) {
+ this.path = ImmutablePath.make();
+ } else {
+ this.path = MutablePath.make();
+ }
+ }
+
+ @Override
public int hashCode() {
return super.hashCode() + this.path.hashCode();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_O_OB_P_S_SE_SL_Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_O_OB_P_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_O_OB_P_S_SE_SL_Traverser.java
index 353d1ef..2e13a33 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_O_OB_P_S_SE_SL_Traverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/LP_O_OB_P_S_SE_SL_Traverser.java
@@ -25,6 +25,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath;
import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+import java.util.HashSet;
+import java.util.List;
import java.util.Set;
/**
@@ -81,6 +83,32 @@ public class LP_O_OB_P_S_SE_SL_Traverser<T> extends O_OB_S_SE_SL_Traverser<T> {
}
@Override
+ public void keepLabels(final Set<String> labels) {
+ if (!labels.isEmpty()) {
+ Set<String> retractLabels = new HashSet<>();
+ List<Set<String>> existingLabels = this.path.labels();
+ for(Set<String> labelSet : existingLabels) {
+ for(String l : labelSet) {
+ if(labels.contains(l) == false) { retractLabels.add(l); };
+ }
+ }
+ this.path = this.path.retract(retractLabels);
+ }
+ }
+
+ @Override
+ public void dropLabels(final Set<String> labels) {
+ if(!labels.isEmpty()) {
+ this.path = path.retract(new HashSet(labels));
+ }
+ }
+
+ @Override
+ public void dropPath() {
+ this.path = ImmutablePath.make();
+ }
+
+ @Override
public int hashCode() {
return super.hashCode() + this.path.hashCode();
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/AbstractTraverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/AbstractTraverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/AbstractTraverser.java
index 1ced9ef..f23ac6e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/AbstractTraverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/AbstractTraverser.java
@@ -78,6 +78,22 @@ public abstract class AbstractTraverser<T> implements Traverser<T>, Traverser.Ad
}
@Override
+ public void keepLabels(final Set<String> labels) {
+
+ }
+
+ @Override
+ public void dropLabels(final Set<String> labesl) {
+
+ }
+
+ @Override
+ public void dropPath() {
+
+ }
+
+
+ @Override
public void set(final T t) {
this.t = t;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/EmptyTraverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/EmptyTraverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/EmptyTraverser.java
index da391f5..7c99cb5 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/EmptyTraverser.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/EmptyTraverser.java
@@ -50,6 +50,21 @@ public final class EmptyTraverser<T> implements Traverser<T>, Traverser.Admin<T>
}
@Override
+ public void keepLabels(final Set<String> labels) {
+
+ }
+
+ @Override
+ public void dropLabels(final Set<String> labels) {
+
+ }
+
+ @Override
+ public void dropPath() {
+
+ }
+
+ @Override
public void set(final T t) {
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
new file mode 100644
index 0000000..d07de50
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/PathUtil.java
@@ -0,0 +1,77 @@
+/*
+ * 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.util;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Parameterizing;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Scoping;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.MatchStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Parameters;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Ted Wilmes (http://twilmes.org)
+ */
+public class PathUtil {
+
+ public static Set<String> getReferencedLabels(Traversal.Admin<?, ?> traversal) {
+ final Set<String> referencedLabels = new HashSet<>();
+ for(final Step<?, ?> step : traversal.getSteps()) {
+ referencedLabels.addAll(getReferencedLabels(step));
+ }
+ return referencedLabels;
+ }
+
+ public static Set<String> getReferencedLabels(Step step) {
+ final Set<String> referencedLabels = new HashSet<>();
+
+ if (step instanceof Parameterizing) {
+ Parameters parameters = ((Parameterizing) step).getParameters();
+ for (Traversal.Admin trav : parameters.getTraversals()) {
+ for (Object ss : trav.getSteps()) {
+ if (ss instanceof Scoping) {
+ Set<String> labels = ((Scoping) ss).getScopeKeys();
+ for (String label : labels) {
+ referencedLabels.add(label);
+ }
+ }
+ }
+ }
+ }
+
+ if (step instanceof Scoping) {
+ Set<String> labels = new HashSet<>(((Scoping) step).getScopeKeys());
+ if (step instanceof MatchStep) {
+ // if this is the last step, keep everything, else just add founds
+ if (step.getNextStep() instanceof EmptyStep) {
+ labels.addAll(((MatchStep) step).getMatchEndLabels());
+ labels.addAll(((MatchStep) step).getMatchStartLabels());
+ }
+ }
+ referencedLabels.addAll(labels);
+
+ }
+
+ return referencedLabels;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
index 66c1a4d..21f1ec8 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/PathTest.java
@@ -76,6 +76,17 @@ public class PathTest {
assertEquals(Integer.valueOf(2), path.get(1));
assertEquals(Integer.valueOf(3), path.get(2));
assertEquals(Integer.valueOf(3), path.get(3));
+ Path retractedPath = path.retract(Collections.singleton("f"));
+ assertFalse(path.hasLabel("f"));
+ assertEquals(retractedPath, path);
+ path = path.retract(Collections.singleton("b"));
+ assertFalse(path.hasLabel("b"));
+ path = path.retract(Collections.singleton("a"));
+ assertFalse(path.hasLabel("a"));
+ assertTrue(path.hasLabel("d"));
+ path = path.retract(new HashSet<>(Arrays.asList("c", "d")));
+ assertFalse(path.hasLabel("c"));
+ assertFalse(path.hasLabel("d"));
});
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
index 37e70bf..e47ab4b 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MatchStepTest.java
@@ -21,17 +21,23 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.map;
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.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PathProcessor;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PrunePathStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_P_S_SE_SL_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.junit.Test;
import java.util.Arrays;
@@ -418,4 +424,44 @@ public class MatchStepTest extends StepTest {
as("b").in("created").count().is(P.gt(1))).asAdmin();
assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren()));
}
+
+ @Test
+ public void testGetRemainingTraversals() {
+ Traverser.Admin traverser = B_LP_O_P_S_SE_SL_TraverserGenerator.instance().generate(1, EmptyStep.instance(), 1l);
+ traverser.addLabels(Collections.singleton("a"));
+
+ Traversal<Object, Vertex> mTraversal1 = as("a").out().as("b");
+ Traversal<Object, Vertex> mTraversal2 = as("b").out().as("c");
+ Traversal<Object, Vertex> mTraversal3 = as("a").out().as("d");
+ Traversal<Object, Vertex> mTraversal4 = as("c").out().as("e");
+ Traversal<Object, Vertex> mTraversal5 = as("c").out().as("f");
+
+
+ Traversal.Admin<?, ?> traversal = __.match(
+ mTraversal1,
+ mTraversal2,
+ mTraversal3,
+ mTraversal4,
+ mTraversal5).asAdmin();
+
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(PrunePathStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
+
+ MatchStep matchStep = (MatchStep) traversal.getStartStep();
+ assertEquals(new HashSet<>(Arrays.asList("a", "b", "c", "d", "e", "f")), matchStep.getKeepLabels());
+
+ traverser.getTags().add(mTraversal1.asAdmin().getStartStep().getId());
+ traverser.setStepId(mTraversal2.asAdmin().getStartStep().getId());
+
+ List<Traversal.Admin<?, ?>> remainingTraversals = matchStep.getRemainingTraversals(traverser);
+ assertEquals(Arrays.asList(mTraversal2, mTraversal3, mTraversal4, mTraversal5), remainingTraversals);
+
+ traverser.getTags().add(mTraversal2.asAdmin().getStartStep().getId());
+ traverser.setStepId(mTraversal3.asAdmin().getStartStep().getId());
+
+ remainingTraversals = matchStep.getRemainingTraversals(traverser);
+ assertEquals(Arrays.asList(mTraversal3, mTraversal4, mTraversal5), remainingTraversals);
+ }
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
new file mode 100644
index 0000000..e510066
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/PrunePathStrategyTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.optimization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.PathProcessor;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.tinkerpop.gremlin.process.traversal.P.gte;
+import static org.apache.tinkerpop.gremlin.process.traversal.P.neq;
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Ted Wilmes (http://twilmes.org)
+ */
+@RunWith(Parameterized.class)
+public class PrunePathStrategyTest {
+
+ @Parameterized.Parameter(value = 0)
+ public Traversal.Admin traversal;
+
+ @Parameterized.Parameter(value = 1)
+ public List<Set<String>> labels;
+
+ void applyPrunePathStrategy(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(PrunePathStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
+ }
+
+ @Test
+ public void doTest() {
+ applyPrunePathStrategy(traversal);
+ // get all path processors
+ List<Object> keepLabels = getKeepLabels(traversal);
+
+ assertEquals(labels, keepLabels);
+ }
+
+ private List<Object> getKeepLabels(Traversal.Admin traversal) {
+ List<Object> keepLabels = new ArrayList<>();
+ for(Step step : (List<Step>)traversal.getSteps()) {
+ if(step instanceof PathProcessor) {
+ final Set<String> keepers = ((PathProcessor) step).getKeepLabels();
+ if(keepers != null) {
+ keepLabels.add(keepers);
+ }
+ }
+ if(step instanceof TraversalParent) {
+ TraversalParent parent = (TraversalParent) step;
+ List<Traversal.Admin<?, ?>> children = new ArrayList<>();
+ children.addAll(parent.getGlobalChildren());
+ children.addAll(parent.getLocalChildren());
+ for(Traversal.Admin<?, ?> child : children) {
+ List<Object> childLabels = getKeepLabels(child);
+ if(childLabels.size() > 0) {
+ keepLabels.add(childLabels);
+ }
+ }
+ }
+ }
+ return keepLabels;
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+
+ return Arrays.asList(new Object[][]{
+ {__.V().as("a").out().as("b").where(neq("a")).out(), Arrays.asList(Collections.EMPTY_SET)},
+ {__.V().as("a").out().where(neq("a")).out().select("a"), Arrays.asList(Collections.singleton("a"), Collections.EMPTY_SET)},
+ {__.V().match(__.as("a").out().as("b")), Arrays.asList(new HashSet<>(Arrays.asList("a", "b")))},
+ {__.V().match(__.as("a").out().as("b")).select("a"), Arrays.asList(new HashSet<>(Arrays.asList("a", "b")), Collections.EMPTY_SET)},
+ {__.V().out().out().match(
+ as("a").in("created").as("b"),
+ as("b").in("knows").as("c")).select("c").out("created").where(neq("a")).values("name"),
+ Arrays.asList(new HashSet<>(Arrays.asList("a", "b", "c")), Collections.singleton("a"), Collections.EMPTY_SET)},
+ {__.V().as("a").out().select("a").path(), Arrays.asList()},
+ {__.V().as("a").out().select("a").subgraph("b"), Arrays.asList()},
+ {__.V().out().as("a").where(neq("a")).out().where(neq("a")), Arrays.asList(Collections.singleton("a"), Collections.EMPTY_SET)},
+ {__.V().out().as("a").where(__.out().select("a").values("prop").count().is(gte(1))).out().where(neq("a")), Arrays.asList(Arrays.asList(Collections.singleton("a")), Collections.EMPTY_SET)},
+ {__.outE().inV().group().by(__.inE().outV().groupCount().by(__.both().count().is(P.gt(2)))), Arrays.asList()},
+ {__.V().as("a").repeat(__.out().where(neq("a"))).emit().select("a").values("test"), Arrays.asList(Arrays.asList(Collections.singleton("a")), Collections.EMPTY_SET)}
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88c5d27b/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 7097b1c..d6dfa9a 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
@@ -18,8 +18,8 @@
*/
package org.apache.tinkerpop.gremlin.tinkergraph.structure;
+
import org.apache.tinkerpop.gremlin.process.traversal.Operator;
-import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Scope;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLIo;
+
import org.apache.tinkerpop.gremlin.util.TimeUtil;
import org.junit.Ignore;
import org.junit.Test;
@@ -40,6 +41,7 @@ import java.util.List;
import java.util.function.Supplier;
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.__.choose;
@@ -52,7 +54,6 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.outE;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.select;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.union;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.valueMap;
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
/**
* @author Stephen Mallette (http://stephen.genoprime.com)
@@ -262,7 +263,7 @@ public class TinkerGraphPlayTest {
as("a").in("writtenBy").as("b"),
as("b").out("followedBy").as("c"),
as("c").out("writtenBy").as("d"),
- as("d").where(P.neq("a"))).select("a", "b", "c", "d").by("name");
+ as("d").where(neq("a"))).select("a", "b", "c", "d").by("name");
logger.info(traversal.get().toString());
@@ -289,4 +290,13 @@ public class TinkerGraphPlayTest {
graph.vertices(50).next().addEdge("uncle", graph.vertices(70).next());
logger.info(TimeUtil.clockWithResult(500, () -> g.V().match(as("a").out("knows").as("b"), as("a").out("uncle").as("b")).toList()).toString());
}
+
+ @Test
+ public void testBugs() {
+ GraphTraversalSource g = TinkerFactory.createModern().traversal();
+
+ System.out.println(g.V().as("a").both().as("b").dedup("a", "b").by(T.label).select("a", "b").explain());
+ System.out.println(g.V().as("a").both().as("b").dedup("a", "b").by(T.label).select("a", "b").toList());
+
+ }
}
[43/50] [abbrv] tinkerpop git commit: Update changelog.
Posted by tw...@apache.org.
Update changelog.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/4e0b5b1a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/4e0b5b1a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/4e0b5b1a
Branch: refs/heads/TINKERPOP-1254
Commit: 4e0b5b1a13c877245892f75599c8a3b63631b7e4
Parents: 0fd1706
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 10:31:41 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:32:29 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/4e0b5b1a/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 9523d52..07e1951 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -257,6 +257,7 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Enured calls to `Result.hasNext()` were idempotent.
* Avoid hamcrest conflict by using mockito-core instead of mockito-all dependency in `gremlin-test`.
* Fixed bug in `SubgraphStrategy` where step labels were not being propogated properly to new steps injected by the strategy.
* Defaulted to `Edge.DEFAULT` if no edge label was supplied in GraphML.
[48/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/tp31'
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/tp31'
Conflicts:
gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e5cbe53e
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e5cbe53e
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e5cbe53e
Branch: refs/heads/TINKERPOP-1254
Commit: e5cbe53e4a339151782e0723f60be43423202e06
Parents: 88f3da5 6836f2f
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 11:45:52 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 11:45:52 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../upgrade/release-3.1.x-incubating.asciidoc | 12 ++++
.../gremlin/process/traversal/Scope.java | 2 -
.../server/op/AbstractEvalOpProcessor.java | 59 +++++++++++++++++---
.../server/GremlinServerIntegrateTest.java | 20 +++++++
5 files changed, 83 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5cbe53e/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5cbe53e/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index c8371f3,f712b44..813174c
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@@ -24,9 -25,18 +24,17 @@@ import org.apache.tinkerpop.gremlin.dri
import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
import org.apache.tinkerpop.gremlin.driver.message.ResponseMessage;
import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
-import org.apache.tinkerpop.gremlin.driver.ser.MessageTextSerializer;
import org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor;
import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptTimeoutException;
+ import org.apache.tinkerpop.gremlin.process.traversal.Operator;
+ import org.apache.tinkerpop.gremlin.process.traversal.Order;
+ import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+ import org.apache.tinkerpop.gremlin.process.traversal.Scope;
+ import org.apache.tinkerpop.gremlin.server.GraphManager;
+ import org.apache.tinkerpop.gremlin.server.handler.Frame;
import org.apache.tinkerpop.gremlin.server.handler.GremlinResponseFrameEncoder;
+ import org.apache.tinkerpop.gremlin.server.handler.StateKey;
+ import org.apache.tinkerpop.gremlin.structure.Column;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.server.Context;
import org.apache.tinkerpop.gremlin.server.GremlinServer;
@@@ -45,7 -59,9 +53,8 @@@ import java.util.Iterator
import java.util.List;
import java.util.Map;
import java.util.Optional;
+ import java.util.Set;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import java.util.regex.Pattern;
@@@ -85,15 -107,42 +100,40 @@@ public abstract class AbstractEvalOpPro
* Use of {@code toUpperCase()} on the accessor values of {@link T} solves an issue where the {@code ScriptEngine}
* ignores private scope on {@link T} and imports static fields.
*/
- private static final List<String> invalidBindingsKeys = Arrays.asList(
- T.id.getAccessor(), T.key.getAccessor(),
- T.label.getAccessor(), T.value.getAccessor(),
- T.id.getAccessor().toUpperCase(), T.key.getAccessor().toUpperCase(),
- T.label.getAccessor().toUpperCase(), T.value.getAccessor().toUpperCase());
- private static final String invalidBindingKeysJoined = String.join(",", invalidBindingsKeys);
+ protected static final Set<String> INVALID_BINDINGS_KEYS = new HashSet<>();
+
+ static {
+ INVALID_BINDINGS_KEYS.addAll(Arrays.asList(
+ T.id.name(), T.key.name(),
+ T.label.name(), T.value.name(),
+ T.id.getAccessor(), T.key.getAccessor(),
+ T.label.getAccessor(), T.value.getAccessor(),
+ T.id.getAccessor().toUpperCase(), T.key.getAccessor().toUpperCase(),
+ T.label.getAccessor().toUpperCase(), T.value.getAccessor().toUpperCase()));
+
+ for (Column enumItem : Column.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Order enumItem : Order.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Operator enumItem : Operator.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Scope enumItem : Scope.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Pop enumItem : Pop.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+ }
- protected final boolean manageTransactions;
-
protected AbstractEvalOpProcessor(final boolean manageTransactions) {
- this.manageTransactions = manageTransactions;
+ super(manageTransactions);
}
/**
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e5cbe53e/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --cc gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index a2b415d,2f091d9..37c310f
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@@ -440,8 -409,28 +440,28 @@@ public class GremlinServerIntegrateTes
if (!latch.await(3000, TimeUnit.MILLISECONDS))
fail("Request should have returned error, but instead timed out");
- assertTrue(pass.get());
+ assertThat(pass.get(), is(true));
}
+
+ try (SimpleClient client = new WebSocketClient()) {
+ final Map<String, Object> bindings = new HashMap<>();
+ bindings.put("id", "123");
+ final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+ .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+ .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AtomicBoolean pass = new AtomicBoolean(false);
+ client.submit(request, result -> {
+ if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+ pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+ latch.countDown();
+ }
+ });
+
+ if (!latch.await(3000, TimeUnit.MILLISECONDS))
+ fail("Request should have returned error, but instead timed out");
+ assertTrue(pass.get());
+ }
}
@Test
[24/50] [abbrv] tinkerpop git commit: took into account a @dkuppitz
comment about not checking for hasStepOfAssignableClass as it just wastes
clock cycles. Also,
came up with a cleaner algorithm for determing whether the final
NoOpBarrierStep should be a
Posted by tw...@apache.org.
took into account a @dkuppitz comment about not checking for hasStepOfAssignableClass as it just wastes clock cycles. Also, came up with a cleaner algorithm for determing whether the final NoOpBarrierStep should be added or not. Faster and less memory usage.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/d634953f
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/d634953f
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/d634953f
Branch: refs/heads/TINKERPOP-1254
Commit: d634953fd1d016c8d840183e3fb0d29d0b92a2c1
Parents: 6208b90
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 28 14:42:44 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 28 14:42:44 2016 -0600
----------------------------------------------------------------------
.../optimization/RepeatUnrollStrategy.java | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d634953f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
index 2139e81..79135a3 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
@@ -41,8 +41,7 @@ public final class RepeatUnrollStrategy extends AbstractTraversalStrategy<Traver
@Override
public void apply(final Traversal.Admin<?, ?> traversal) {
- if (!TraversalHelper.hasStepOfAssignableClass(RepeatStep.class, traversal) ||
- TraversalHelper.onGraphComputer(traversal))
+ if (TraversalHelper.onGraphComputer(traversal))
return;
for (int i = 0; i < traversal.getSteps().size(); i++) {
@@ -56,18 +55,15 @@ public final class RepeatUnrollStrategy extends AbstractTraversalStrategy<Traver
final int loops = (int) ((LoopTraversal) repeatStep.getUntilTraversal()).getMaxLoops();
for (int j = 0; j < loops; j++) {
TraversalHelper.insertTraversal(insertIndex, repeatTraversal.clone(), traversal);
- insertIndex = insertIndex + repeatLength + 1;
- traversal.addStep(insertIndex, new NoOpBarrierStep<>(traversal));
+ insertIndex = insertIndex + repeatLength;
+ if (j != (loops - 1) || !(traversal.getSteps().get(insertIndex).getNextStep() instanceof Barrier)) // only add a final NoOpBarrier is subsequent step is not a barrier
+ traversal.addStep(++insertIndex, new NoOpBarrierStep<>(traversal));
}
-
- final NoOpBarrierStep<?> lastStep = (NoOpBarrierStep) traversal.getSteps().get(insertIndex);
- Step<?, ?> labelStep = lastStep;
- if (lastStep.getNextStep() instanceof Barrier) {
- labelStep = traversal.getSteps().get(insertIndex - 1);
- traversal.removeStep(insertIndex); // remove last NoOpBarrierStep
+ // label last step if repeat() was labeled
+ if (!repeatStep.getLabels().isEmpty()) {
+ final Step<?, ?> lastStep = traversal.getSteps().get(insertIndex);
+ repeatStep.getLabels().forEach(lastStep::addLabel);
}
- if (!repeatStep.getLabels().isEmpty())
- repeatStep.getLabels().forEach(labelStep::addLabel);
traversal.removeStep(i); // remove the RepeatStep
}
[21/50] [abbrv] tinkerpop git commit: Cancellation of a timeout
should occur in existing thread pool
Posted by tw...@apache.org.
Cancellation of a timeout should occur in existing thread pool
Prior to this change, the cancellation of a timeout occured in the ForkJoinPool when an existing thread pool in the GremlinExecutor was present to handle that job. CTR
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/d699cb6c
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/d699cb6c
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/d699cb6c
Branch: refs/heads/TINKERPOP-1254
Commit: d699cb6c00ccef02a7b93948cf185a61481dc12b
Parents: 8c04d61
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Jun 28 13:59:36 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Jun 28 13:59:36 2016 -0400
----------------------------------------------------------------------
.../apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/d699cb6c/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
index 2476114..63721eb 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
@@ -310,7 +310,7 @@ public class GremlinExecutor implements AutoCloseable {
evaluationFuture.handleAsync((v, t) -> {
logger.debug("Killing scheduled timeout on script evaluation as the eval completed (possibly with exception).");
return sf.cancel(true);
- });
+ }, scheduledExecutorService);
}
return evaluationFuture;
[42/50] [abbrv] tinkerpop git commit: ResultSet.hasNext should be
idempotent
Posted by tw...@apache.org.
ResultSet.hasNext should be idempotent
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/0fd1706e
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/0fd1706e
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/0fd1706e
Branch: refs/heads/TINKERPOP-1254
Commit: 0fd1706e95998204c61e43b78f204e118c059fc8
Parents: f9706a3
Author: Robert Dale <Ro...@sensus.com>
Authored: Fri Jun 24 16:13:33 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:32:29 2016 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/driver/ResultSet.java | 4 +++-
.../tinkerpop/gremlin/driver/ResultSetTest.java | 19 +++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0fd1706e/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
index d4e233b..78a4892 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
@@ -127,7 +127,9 @@ public final class ResultSet implements Iterable<Result> {
@Override
public boolean hasNext() {
- nextOne = one();
+ if (null == nextOne) {
+ nextOne = one();
+ }
return nextOne != null;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0fd1706e/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
index 392566a..ea3729f 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
@@ -174,4 +174,23 @@ public class ResultSetTest extends AbstractResultQueueTest {
assertEquals(100, counter.get());
}
+
+ @Test
+ public void shouldCallHasNextWithoutSideEffect() throws Exception {
+ final Iterator itty = resultSet.iterator();
+ final AtomicInteger counter = new AtomicInteger(0);
+
+ addToQueue(100, 1, true, true);
+
+ for (int i = 0; i < 101; i++) {
+ assertThat(itty.hasNext(), is(true));
+ }
+
+ while (itty.hasNext()) {
+ itty.next();
+ counter.incrementAndGet();
+ }
+
+ assertEquals(100, counter.get());
+ }
}
[11/50] [abbrv] tinkerpop git commit: realized why various providers
OPT_OUT of a particular OrderTest. The traversal should be compiled and then
setLimit() called. CTR.
Posted by tw...@apache.org.
realized why various providers OPT_OUT of a particular OrderTest. The traversal should be compiled and then setLimit() called. CTR.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/2eafeef8
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/2eafeef8
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/2eafeef8
Branch: refs/heads/TINKERPOP-1254
Commit: 2eafeef8d174834b65bfbea532d4829f84bcd8a7
Parents: 9ff14b7
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 21 08:54:45 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 21 08:54:45 2016 -0600
----------------------------------------------------------------------
.../tinkerpop/gremlin/process/traversal/step/map/OrderTest.java | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2eafeef8/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
index ca7b8bd..453a663 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/OrderTest.java
@@ -406,6 +406,7 @@ public abstract class OrderTest extends AbstractGremlinProcessTest {
@LoadGraphWith(MODERN)
public void g_V_both_hasLabelXpersonX_order_byXage_decrX_name() {
final Traversal<Vertex, String> traversal = get_g_V_both_hasLabelXpersonX_order_byXage_decrX_name();
+ traversal.asAdmin().applyStrategies();
if (!TraversalHelper.getFirstStepOfAssignableClass(OrderGlobalStep.class, traversal.asAdmin()).isPresent())
return; // total hack to avoid providers that don't compile to OrderGlobalStep
TraversalHelper.getFirstStepOfAssignableClass(OrderGlobalStep.class, traversal.asAdmin()).get().setLimit(1);
[09/50] [abbrv] tinkerpop git commit: removed NOTE: Neo4jGraph
currently does not support HA and added an image for the HA section. CTR.
Posted by tw...@apache.org.
removed NOTE: Neo4jGraph currently does not support HA and added an image for the HA section. CTR.
(cherry picked from commit da26cf1862b7827223205c5410731c96d3cca70a)
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/8c04d617
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/8c04d617
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/8c04d617
Branch: refs/heads/TINKERPOP-1254
Commit: 8c04d617e90bc374764b06d502e2fc50c89335a8
Parents: 45e19af
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Jun 17 07:33:37 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri Jun 17 08:16:05 2016 -0600
----------------------------------------------------------------------
docs/src/reference/implementations-neo4j.asciidoc | 5 +----
docs/static/images/neo4j-ha.png | Bin 0 -> 108249 bytes
2 files changed, 1 insertion(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8c04d617/docs/src/reference/implementations-neo4j.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/implementations-neo4j.asciidoc b/docs/src/reference/implementations-neo4j.asciidoc
index 998eb74..d1fc30b 100644
--- a/docs/src/reference/implementations-neo4j.asciidoc
+++ b/docs/src/reference/implementations-neo4j.asciidoc
@@ -54,9 +54,6 @@ gremlin> graph = Neo4jGraph.open('/tmp/neo4j')
==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
----
-NOTE: Neo4j link:http://docs.neo4j.org/chunked/stable/ha.html[High Availability] is currently not supported by
-Neo4j-Gremlin.
-
TIP: To host Neo4j in <<gremlin-server,Gremlin Server>>, the dependencies must first be "installed" or otherwise
copied to the Gremlin Server path. The automated method for doing this would be to execute
`bin/gremlin-server.sh -i org.apache.tinkerpop neo4j-gremlin x.y.z`.
@@ -263,7 +260,7 @@ gremlin.neo4j.conf.relationship_auto_indexing=true
High Availability Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-TinkerPop supports running Neo4j with its fault tolerant master-slave replication configuration, referred to as its
+image:neo4j-ha.png[width=400,float=right] TinkerPop supports running Neo4j with its fault tolerant master-slave replication configuration, referred to as its
link:http://neo4j.com/docs/operations-manual/current/#_neo4j_cluster_install[High Availability (HA) cluster]. From the
TinkerPop perspective, configuring for HA is not that different than configuring for embedded mode as shown above. The
main difference is the usage of HA configuration options that enable the cluster. Once connected to a cluster, usage
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8c04d617/docs/static/images/neo4j-ha.png
----------------------------------------------------------------------
diff --git a/docs/static/images/neo4j-ha.png b/docs/static/images/neo4j-ha.png
new file mode 100644
index 0000000..b21393c
Binary files /dev/null and b/docs/static/images/neo4j-ha.png differ
[03/50] [abbrv] tinkerpop git commit: Fixed path to log file for
`bin/validate-distribution.sh` and log only errors in `mvn clean install`.
Posted by tw...@apache.org.
Fixed path to log file for `bin/validate-distribution.sh` and log only errors in `mvn clean install`.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/ce0dc48b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/ce0dc48b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/ce0dc48b
Branch: refs/heads/TINKERPOP-1254
Commit: ce0dc48b5f46ce0fa7f106d4619070a339bb9964
Parents: 6edca75
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Thu Jun 16 21:41:06 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Thu Jun 16 21:41:06 2016 +0200
----------------------------------------------------------------------
bin/validate-distribution.sh | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ce0dc48b/bin/validate-distribution.sh
----------------------------------------------------------------------
diff --git a/bin/validate-distribution.sh b/bin/validate-distribution.sh
index a6fb927..eea1ba1 100755
--- a/bin/validate-distribution.sh
+++ b/bin/validate-distribution.sh
@@ -114,15 +114,13 @@ echo "OK"
if [ "${TYPE}" = "SOURCE" ]; then
cd ${DIR_NAME}
-LOG_DIR="${DIR_NAME}/target/validate-distribution"
-LOG_FILE="mvn-clean-install.log"
echo -n "* building project ... "
-mkdir -p ${LOG_DIR}
-mvn clean install 2>&1 > "${LOG_DIR}/${LOG_FILE}" || {
+LOG_FILE="mvn-clean-install.log"
+mvn clean install -q 2>&1 > "${LOG_FILE}" || {
echo "failed"
echo
- tail -n100 target/validate-distribution/mvn-clean-install.log
- echo -e "\n\e[1mThe full log file can be inspected under ${LOG_DIR}/${LOG_FILE}.\e[0m\n"
+ tail -n50 "${LOG_FILE}"
+ echo -e "\n\e[1mThe full log file can be inspected under `pwd`/${LOG_FILE}.\e[0m\n"
exit 1
}
echo "OK"
[30/50] [abbrv] tinkerpop git commit: TINKERPOP-1341 Add missing
classes to GryoRegistrator
Posted by tw...@apache.org.
TINKERPOP-1341 Add missing classes to GryoRegistrator
GryoRegistrator is missing registrations for three classes registered
in GryoSerializer:
* void
* Void
* CompactBuffer[]
This commit adds all three to GryoRegistrator.getExtraRegistrations().
So far, CompactBuffer[] is the only omission known to cause practical
problems, as detailed by Dylan Bethune-Waddell on the mailing list and
in the referenced issue. It's not clear whether omitting Void and
void causes practical problems, but they're trivial, so the cost
associated with registering them is tiny. Might as well.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f19121b4
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f19121b4
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f19121b4
Branch: refs/heads/TINKERPOP-1254
Commit: f19121b487258beebc4f86ff7ce58cd452d5ddef
Parents: 5395aae
Author: Dan LaRocque <da...@hopcount.org>
Authored: Wed Jun 29 15:14:32 2016 -0400
Committer: Dan LaRocque <da...@hopcount.org>
Committed: Wed Jun 29 15:17:11 2016 -0400
----------------------------------------------------------------------
.../gremlin/spark/structure/io/gryo/GryoRegistrator.java | 5 +++++
1 file changed, 5 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f19121b4/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
----------------------------------------------------------------------
diff --git a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
index 412fd3b..9e5d4e1 100644
--- a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
+++ b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
@@ -22,6 +22,7 @@ import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.serializers.JavaSerializer;
import org.apache.spark.serializer.KryoRegistrator;
+import org.apache.spark.util.collection.CompactBuffer;
import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopEdge;
import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopProperty;
import org.apache.tinkerpop.gremlin.hadoop.structure.HadoopVertex;
@@ -215,6 +216,10 @@ public class GryoRegistrator implements KryoRegistrator {
} catch (final ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
+ //
+ m.put(CompactBuffer[].class, null);
+ m.put(void.class, null);
+ m.put(Void.class, null);
return m;
}
[40/50] [abbrv] tinkerpop git commit: Void and void can not use
FieldSerializers. However,
note that Void and void are in DefaultSerializers and thus,
don't need to be registered by GryoRegistrator. Commented them out and added a
note if for some reason
Posted by tw...@apache.org.
Void and void can not use FieldSerializers. However, note that Void and void are in DefaultSerializers and thus, don't need to be registered by GryoRegistrator. Commented them out and added a note if for some reason Void and void require serializaion registration. However, integration tests pass now and Void/void were not a problem. CTR. cc/ @dalaro
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f9706a38
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f9706a38
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f9706a38
Branch: refs/heads/TINKERPOP-1254
Commit: f9706a38fbe546c0a7e5b038a6b99303d21aec01
Parents: ca8a4f9
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Jul 6 08:27:00 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Jul 6 08:27:00 2016 -0600
----------------------------------------------------------------------
.../gremlin/spark/structure/io/gryo/GryoRegistrator.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f9706a38/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
----------------------------------------------------------------------
diff --git a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
index 9e5d4e1..ffd731a 100644
--- a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
+++ b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
@@ -218,8 +218,10 @@ public class GryoRegistrator implements KryoRegistrator {
}
//
m.put(CompactBuffer[].class, null);
- m.put(void.class, null);
- m.put(Void.class, null);
+ // TODO: VoidSerializer is a default serializer and thus, may not be needed (if it is, you can't use FieldSerializer)
+ // TODO: We will have to copy/paste the shaded DefaultSerializer.VoidSerializer into an unshaded form.
+ //m.put(void.class, null);
+ //m.put(Void.class, null);
return m;
}
[29/50] [abbrv] tinkerpop git commit: prevent division by zero
Posted by tw...@apache.org.
prevent division by zero
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/857e2e2c
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/857e2e2c
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/857e2e2c
Branch: refs/heads/TINKERPOP-1254
Commit: 857e2e2c104283aef0b251402668ca73c92c1ab6
Parents: 05d4c32
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed Jun 29 20:43:24 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Wed Jun 29 20:43:24 2016 +0200
----------------------------------------------------------------------
.../traversal/strategy/TraversalStrategyPerformanceTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/857e2e2c/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
index 4ddd877..f589cc3 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
@@ -114,7 +114,7 @@ public abstract class TraversalStrategyPerformanceTest {
assertEquals(originalResult, optimizedResult);
}
- if (getAssertionPercentile() < 100)
+ if (getAssertionPercentile() < 100 && numTraversals > 0)
assertTrue(((faster * 100.0) / numTraversals) >= getAssertionPercentile());
}
}
[35/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/tp31'
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/tp31'
Conflicts:
tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/78f7f3e5
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/78f7f3e5
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/78f7f3e5
Branch: refs/heads/TINKERPOP-1254
Commit: 78f7f3e506ec18fe2d61ad3dbc0a015854c353fb
Parents: 44ad2eb 1c9bd08
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 30 11:49:15 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 30 11:49:15 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../gremlin/groovy/engine/GremlinExecutor.java | 2 +-
.../step/sideEffect/TinkerGraphStep.java | 15 +++----
.../tinkergraph/structure/TinkerGraph.java | 44 +++++++++++---------
4 files changed, 35 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/78f7f3e5/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/78f7f3e5/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/78f7f3e5/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
----------------------------------------------------------------------
diff --cc tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
index 73a4205,af7245a..4cf264e
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
@@@ -320,35 -322,20 +322,26 @@@ public final class TinkerGraph implemen
private <T extends Element> Iterator<T> createElementIterator(final Class<T> clazz, final Map<Object, T> elements,
final IdManager idManager,
final Object... ids) {
+ final Iterator<T> iterator;
if (0 == ids.length) {
- return elements.values().iterator();
+ iterator = elements.values().iterator();
} else {
- // base the conversion function on the first item in the id list as the expectation is that these
- // id values will be a uniform list
- if (clazz.isAssignableFrom(ids[0].getClass())) {
- // based on the first item assume all vertices in the argument list
- if (!Stream.of(ids).allMatch(id -> clazz.isAssignableFrom(id.getClass())))
- throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
-
- // got a bunch of Elements - have to look each upup because it might be an Attachable instance or
- // other implementation. the assumption is that id conversion is not required for detached
- // stuff - doesn't seem likely someone would detach a Titan vertex then try to expect that
- // vertex to be findable in OrientDB
- iterator = Stream.of(ids).map(id -> elements.get(((T) id).id())).filter(Objects::nonNull).iterator();
- } else {
- final Class<?> firstClass = ids[0].getClass();
- if (!Stream.of(ids).map(Object::getClass).allMatch(firstClass::equals))
- throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
- iterator = Stream.of(ids).map(id -> idManager.convert(id)).map(elements::get).filter(Objects::nonNull).iterator();
- }
+ final List<Object> idList = Arrays.asList(ids);
+ validateHomogenousIds(idList);
+
+ // if the type is of Element - have to look each up because it might be an Attachable instance or
+ // other implementation. the assumption is that id conversion is not required for detached
+ // stuff - doesn't seem likely someone would detach a Titan vertex then try to expect that
+ // vertex to be findable in OrientDB
+ return clazz.isAssignableFrom(ids[0].getClass()) ?
+ IteratorUtils.filter(IteratorUtils.map(idList, id -> elements.get(clazz.cast(id).id())).iterator(), Objects::nonNull)
+ : IteratorUtils.filter(IteratorUtils.map(idList, id -> elements.get(idManager.convert(id))).iterator(), Objects::nonNull);
}
+ return TinkerHelper.inComputerMode(this) ?
+ (Iterator<T>) (clazz.equals(Vertex.class) ?
+ IteratorUtils.filter((Iterator<Vertex>) iterator, t -> this.graphComputerView.legalVertex(t)) :
+ IteratorUtils.filter((Iterator<Edge>) iterator, t -> this.graphComputerView.legalEdge(t.outVertex(), t))) :
+ iterator;
}
/**
[41/50] [abbrv] tinkerpop git commit: Update changelog.
Posted by tw...@apache.org.
Update changelog.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/320071d3
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/320071d3
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/320071d3
Branch: refs/heads/TINKERPOP-1254
Commit: 320071d351005e562a23f4f58bc1fcf55f52ac7f
Parents: e25c1d5
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 10:31:41 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:31:41 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/320071d3/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 2ae2e77..a6cbad0 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Enured calls to `Result.hasNext()` were idempotent.
* Avoid hamcrest conflict by using mockito-core instead of mockito-all dependency in `gremlin-test`.
* Fixed bug in `SubgraphStrategy` where step labels were not being propogated properly to new steps injected by the strategy.
* Defaulted to `Edge.DEFAULT` if no edge label was supplied in GraphML.
[47/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/TINKERPOP-1354' into tp31
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/TINKERPOP-1354' into tp31
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6836f2ff
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6836f2ff
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6836f2ff
Branch: refs/heads/TINKERPOP-1254
Commit: 6836f2ff50f2d53193180718510a478ceb30fccd
Parents: 17aab3e c37c301
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 11:23:03 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 11:23:03 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../upgrade/release-3.1.x-incubating.asciidoc | 12 +++++
.../gremlin/process/traversal/Scope.java | 2 -
.../server/op/AbstractEvalOpProcessor.java | 54 +++++++++++++++++---
.../server/GremlinServerIntegrateTest.java | 21 +++++++-
5 files changed, 79 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6836f2ff/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6836f2ff/docs/src/upgrade/release-3.1.x-incubating.asciidoc
----------------------------------------------------------------------
diff --cc docs/src/upgrade/release-3.1.x-incubating.asciidoc
index d8c5de2,504baaa..060d842
--- a/docs/src/upgrade/release-3.1.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
@@@ -52,18 -62,10 +62,20 @@@ still possible to get a timeout on a re
refers to how long the console will wait for a response from the server before giving up. By default, the timeout is
set to `none`.
-See: https://issues.apache.org/jira/browse/TINKERPOP-1267[TINKERPOP-1267]
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1267[TINKERPOP-1267]
+
+Gremlin Server Workers
+^^^^^^^^^^^^^^^^^^^^^^
+
+Past configuration recommendations for the `threadPoolWorker` setting on Gremlin Server stated this value could be
+safely set to `1` at the low end. A size of `1` is still valid for most cases, however, if Gremlin Server is being used
+with sessions that accept parallel requests, then this value should be no less than `2` or else certain scripts (i.e.
+those that block for an extended period of time) may cause Gremlin Server to lock up the session.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1350[TINKERPOP-1350]
+
+
Upgrading for Providers
~~~~~~~~~~~~~~~~~~~~~~~
[31/50] [abbrv] tinkerpop git commit: Removed potential for NPEs when
validating IDs given to vertices()/edges()
Posted by tw...@apache.org.
Removed potential for NPEs when validating IDs given to vertices()/edges()
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/1e0c581c
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/1e0c581c
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/1e0c581c
Branch: refs/heads/TINKERPOP-1254
Commit: 1e0c581c90b67a44121f8ec7258ea171e7c0bfe7
Parents: 099e6bc
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 30 05:48:01 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 30 05:48:01 2016 -0400
----------------------------------------------------------------------
.../gremlin/tinkergraph/structure/TinkerGraph.java | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/1e0c581c/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
index edffab9..af7245a 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
@@ -351,9 +351,14 @@ public final class TinkerGraph implements Graph {
}
private void validateHomogenousIds(final List<Object> ids) {
- final Class firstClass = ids.get(0).getClass();
- for (Object id : ids) {
- if (!id.getClass().equals(firstClass))
+ final Iterator<Object> iterator = ids.iterator();
+ Object id = iterator.next();
+ if (id == null)
+ throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
+ final Class firstClass = id.getClass();
+ while (iterator.hasNext()) {
+ id = iterator.next();
+ if (id == null || !id.getClass().equals(firstClass))
throw Graph.Exceptions.idArgsMustBeEitherIdOrElement();
}
}
[05/50] [abbrv] tinkerpop git commit: Merge branch 'TINKERPOP-939'
into tp31
Posted by tw...@apache.org.
Merge branch 'TINKERPOP-939' into tp31
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/45e19af7
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/45e19af7
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/45e19af7
Branch: refs/heads/TINKERPOP-1254
Commit: 45e19af71e9130658435e0e6af98a606252627f5
Parents: ce0dc48 6220653
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 17 06:24:50 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 17 06:24:50 2016 -0400
----------------------------------------------------------------------
.../reference/implementations-neo4j.asciidoc | 74 ++++++++++++++++++++
1 file changed, 74 insertions(+)
----------------------------------------------------------------------
[45/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/TINKERPOP-1350' into tp31
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/TINKERPOP-1350' into tp31
Conflicts:
CHANGELOG.asciidoc
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/17aab3e3
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/17aab3e3
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/17aab3e3
Branch: refs/heads/TINKERPOP-1254
Commit: 17aab3e3d25fa4de078e8cc24a55a166657ea38d
Parents: 320071d cd0e58b
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 10:38:21 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:38:21 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 +
.../src/reference/gremlin-applications.asciidoc | 6 ++-
.../upgrade/release-3.1.x-incubating.asciidoc | 14 ++++-
.../gremlin/groovy/engine/GremlinExecutor.java | 51 +++++++++++-------
.../server/GremlinDriverIntegrateTest.java | 54 ++++++++++++++++++++
5 files changed, 105 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/17aab3e3/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --cc CHANGELOG.asciidoc
index a6cbad0,6fcd00a..0096209
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@@ -26,8 -26,9 +26,10 @@@ image::https://raw.githubusercontent.co
TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* Avoided hamcrest conflict by using mockito-core instead of mockito-all dependency in `gremlin-test`.
+* Enured calls to `Result.hasNext()` were idempotent.
+* Avoid hamcrest conflict by using mockito-core instead of mockito-all dependency in `gremlin-test`.
+ * Fixed bug in `GremlinExecutor` causing Gremlin Server to lock up when parallel requests were submitted on the same session if those parallel requests included a script that blocked indefinitely.
+ * Changed `GremlinExecutor` timeout scheduling so that the timer would not start until a time closer to the actual start of script evaluation.
* Fixed bug in `SubgraphStrategy` where step labels were not being propogated properly to new steps injected by the strategy.
* Defaulted to `Edge.DEFAULT` if no edge label was supplied in GraphML.
* Fixed bug in `IoGraphTest` causing IllegalArgumentException: URI is not hierarchical error for external graph implementations.
[25/50] [abbrv] tinkerpop git commit: learned how to used
Enclosed.class to have parameterized and non-parameterized sections of a
test. I think all our Strategy tests should have a 'isFaster' test to ensure
that our optimizations are actually making thi
Posted by tw...@apache.org.
learned how to used Enclosed.class to have parameterized and non-parameterized sections of a test. I think all our Strategy tests should have a 'isFaster' test to ensure that our optimizations are actually making things faster. cc/ @dkuppitz.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/857deabf
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/857deabf
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/857deabf
Branch: refs/heads/TINKERPOP-1254
Commit: 857deabf97582c4eb73b0f8f3edae3ea618831dd
Parents: d634953
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 28 14:58:42 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 28 14:58:42 2016 -0600
----------------------------------------------------------------------
.../IdentityRemovalStrategyTest.java | 103 ++++++-----
.../optimization/RepeatUnrollStrategyTest.java | 181 ++++++++++---------
2 files changed, 144 insertions(+), 140 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/857deabf/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
index c71ad99..3a84813 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
@@ -24,6 +24,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.util.TimeUtil;
import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -36,69 +37,71 @@ import static org.junit.Assert.assertTrue;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-@RunWith(Parameterized.class)
+@RunWith(Enclosed.class)
public class IdentityRemovalStrategyTest {
- private static boolean executedshouldBeFaster = false;
+ @RunWith(Parameterized.class)
+ public static class ParameterizedTests {
- @Parameterized.Parameter(value = 0)
- public Traversal original;
+ @Parameterized.Parameter(value = 0)
+ public Traversal original;
- @Parameterized.Parameter(value = 1)
- public Traversal optimized;
+ @Parameterized.Parameter(value = 1)
+ public Traversal optimized;
- private void applyIdentityRemovalStrategy(final Traversal traversal) {
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(IdentityRemovalStrategy.instance());
- traversal.asAdmin().setStrategies(strategies);
- traversal.asAdmin().applyStrategies();
+ private void applyIdentityRemovalStrategy(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(IdentityRemovalStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
- }
+ }
- @Test
- public void doTest() {
- applyIdentityRemovalStrategy(original);
- assertEquals(optimized, original);
- }
+ @Test
+ public void doTest() {
+ applyIdentityRemovalStrategy(original);
+ assertEquals(optimized, original);
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+
+ return Arrays.asList(new Traversal[][]{
+ {__.identity(), __.identity()},
+ {__.identity().out(), __.out()},
+ {__.identity().out().identity(), __.out()},
+ {__.identity().as("a").out().identity(), __.identity().as("a").out()},
+ {__.identity().as("a").out().identity().as("b"), __.identity().as("a").out().as("b")},
+ {__.identity().as("a").out().in().identity().identity().as("b").identity().out(), __.identity().as("a").out().in().as("b").out()},
+ {__.out().identity().as("a").out().in().identity().identity().as("b").identity().out(), __.out().as("a").out().in().as("b").out()},
+ });
+ }
- @Parameterized.Parameters(name = "{0}")
- public static Iterable<Object[]> generateTestParameters() {
-
- return Arrays.asList(new Traversal[][]{
- {__.identity(), __.identity()},
- {__.identity().out(), __.out()},
- {__.identity().out().identity(), __.out()},
- {__.identity().as("a").out().identity(), __.identity().as("a").out()},
- {__.identity().as("a").out().identity().as("b"), __.identity().as("a").out().as("b")},
- {__.identity().as("a").out().in().identity().identity().as("b").identity().out(), __.identity().as("a").out().in().as("b").out()},
- {__.out().identity().as("a").out().in().identity().identity().as("b").identity().out(), __.out().as("a").out().in().as("b").out()},
- });
}
- @Test
- public void shouldBeFaster() {
- if (executedshouldBeFaster)
- return;
- else
- executedshouldBeFaster = true;
- final int startSize = 1000;
- final int clockRuns = 1000;
- final Integer[] starts = new Integer[startSize];
- for (int i = 0; i < startSize; i++) {
- starts[i] = i;
- }
+ public static class NonParameterizedTests {
+ @Test
+ public void shouldBeFaster() {
- final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate();
+ final int startSize = 1000;
+ final int clockRuns = 1000;
+ final Integer[] starts = new Integer[startSize];
+ for (int i = 0; i < startSize; i++) {
+ starts[i] = i;
+ }
- final Runnable optimized = () -> {
- final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity();
- traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance()));
- traversal.iterate();
- };
+ final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate();
- //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized));
- assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
- assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
+ final Runnable optimized = () -> {
+ final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity();
+ traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance()));
+ traversal.iterate();
+ };
+
+ //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized));
+ assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
+ assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/857deabf/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
index b819331..3d47a10 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
@@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.util.TimeUtil;
import org.javatuples.Pair;
import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -43,113 +44,113 @@ import static org.junit.Assert.assertTrue;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-@RunWith(Parameterized.class)
+
+@RunWith(Enclosed.class)
public class RepeatUnrollStrategyTest {
private static final Random RANDOM = new Random();
- private static boolean shouldBeFasterWithUniqueStreamExecuted = false;
- private static boolean shouldBeFasterWithDuplicateStreamExecuted = false;
-
- @Parameterized.Parameter(value = 0)
- public Traversal original;
- @Parameterized.Parameter(value = 1)
- public Traversal optimized;
+ @RunWith(Parameterized.class)
+ public static class ParameterizedTests {
+ @Parameterized.Parameter(value = 0)
+ public Traversal original;
- private void applyRepeatUnrollStrategy(final Traversal traversal) {
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(RepeatUnrollStrategy.instance());
- traversal.asAdmin().setStrategies(strategies);
- traversal.asAdmin().applyStrategies();
+ @Parameterized.Parameter(value = 1)
+ public Traversal optimized;
- }
- @Test
- public void doTest() {
- applyRepeatUnrollStrategy(original);
- assertEquals(optimized, original);
- }
+ private void applyRepeatUnrollStrategy(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(RepeatUnrollStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
- @Parameterized.Parameters(name = "{0}")
- public static Iterable<Object[]> generateTestParameters() {
-
- final Predicate<Traverser<Vertex>> predicate = t -> t.loops() > 5;
- return Arrays.asList(new Traversal[][]{
- {__.identity(), __.identity()},
- {__.out().as("a").in().repeat(__.outE("created").bothV()).times(2).in(), __.out().as("a").in().outE("created").bothV().barrier().outE("created").bothV().barrier().in()},
- {__.out().repeat(__.outE("created").bothV()).times(1).in(), __.out().outE("created").bothV().barrier().in()},
- {__.repeat(__.outE("created").bothV()).times(1).in(), __.outE("created").bothV().barrier().in()},
- {__.repeat(__.out()).times(2).as("x").repeat(__.in().as("b")).times(3), __.out().barrier().out().barrier().as("x").in().as("b").barrier().in().as("b").barrier().in().as("b").barrier()},
- {__.repeat(__.outE("created").inV()).times(2), __.outE("created").inV().barrier().outE("created").inV().barrier()},
- {__.repeat(__.out()).times(3), __.out().barrier().out().barrier().out().barrier()},
- {__.repeat(__.local(__.select("a").out("knows"))).times(2), __.local(__.select("a").out("knows")).barrier().local(__.select("a").out("knows")).barrier()},
- {__.<Vertex>times(2).repeat(__.out()), __.out().barrier().out().barrier()},
- {__.<Vertex>out().times(2).repeat(__.out().as("a")).as("x"), __.out().out().as("a").barrier().out().as("a").barrier().as("x")},
- {__.repeat(__.out()).emit().times(2), __.repeat(__.out()).emit().times(2)},
- {__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)},
- {__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()},
- {__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()},
- {__.in().repeat(__.out("knows")).times(3).as("a").count().is(0), __.in().out("knows").barrier().out("knows").barrier().out("knows").as("a").count().is(0)},
- });
- }
+ }
- @Test
- public void shouldBeFasterWithUniqueStream() {
- if (shouldBeFasterWithUniqueStreamExecuted)
- return;
- shouldBeFasterWithUniqueStreamExecuted = true;
- final int startSize = 1000;
- final int clockRuns = 1000;
- final Integer[] starts = new Integer[startSize];
- for (int i = 0; i < startSize; i++) {
- starts[i] = i; // 1000 unique objects
+ @Test
+ public void doTest() {
+ applyRepeatUnrollStrategy(original);
+ assertEquals(optimized, original);
}
- assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size());
- clockTraversals(starts, clockRuns);
- }
- @Test
- public void shouldBeFasterWithDuplicateStream() {
- if (shouldBeFasterWithDuplicateStreamExecuted)
- return;
- shouldBeFasterWithDuplicateStreamExecuted = true;
- final int startSize = 1000;
- final int clockRuns = 1000;
- final int uniques = 100;
- final Integer[] starts = new Integer[startSize];
- for (int i = 0; i < startSize; i++) {
- starts[i] = i % uniques; // 100 unique objects
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+
+ final Predicate<Traverser<Vertex>> predicate = t -> t.loops() > 5;
+ return Arrays.asList(new Traversal[][]{
+ {__.identity(), __.identity()},
+ {__.out().as("a").in().repeat(__.outE("created").bothV()).times(2).in(), __.out().as("a").in().outE("created").bothV().barrier().outE("created").bothV().barrier().in()},
+ {__.out().repeat(__.outE("created").bothV()).times(1).in(), __.out().outE("created").bothV().barrier().in()},
+ {__.repeat(__.outE("created").bothV()).times(1).in(), __.outE("created").bothV().barrier().in()},
+ {__.repeat(__.out()).times(2).as("x").repeat(__.in().as("b")).times(3), __.out().barrier().out().barrier().as("x").in().as("b").barrier().in().as("b").barrier().in().as("b").barrier()},
+ {__.repeat(__.outE("created").inV()).times(2), __.outE("created").inV().barrier().outE("created").inV().barrier()},
+ {__.repeat(__.out()).times(3), __.out().barrier().out().barrier().out().barrier()},
+ {__.repeat(__.local(__.select("a").out("knows"))).times(2), __.local(__.select("a").out("knows")).barrier().local(__.select("a").out("knows")).barrier()},
+ {__.<Vertex>times(2).repeat(__.out()), __.out().barrier().out().barrier()},
+ {__.<Vertex>out().times(2).repeat(__.out().as("a")).as("x"), __.out().out().as("a").barrier().out().as("a").barrier().as("x")},
+ {__.repeat(__.out()).emit().times(2), __.repeat(__.out()).emit().times(2)},
+ {__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)},
+ {__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()},
+ {__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()},
+ {__.in().repeat(__.out("knows")).times(3).as("a").count().is(0), __.in().out("knows").barrier().out("knows").barrier().out("knows").as("a").count().is(0)},
+ });
}
- assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size());
- clockTraversals(starts, clockRuns);
}
- private void clockTraversals(final Integer[] starts, final int clockRuns) {
- final int times = RANDOM.nextInt(4) + 2;
- assertTrue(times > 1 && times < 6);
- final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next();
+ public static class NonParameterizedTests {
+
+ @Test
+ public void shouldBeFasterWithUniqueStream() {
+ final int startSize = 1000;
+ final int clockRuns = 1000;
+ final Integer[] starts = new Integer[startSize];
+ for (int i = 0; i < startSize; i++) {
+ starts[i] = i; // 1000 unique objects
+ }
+ assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size());
+ clockTraversals(starts, clockRuns);
+ }
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(RepeatUnrollStrategy.instance());
- final Supplier<Long> optimized = () -> {
- final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum();
- traversal.asAdmin().setStrategies(strategies);
- return traversal.next();
- };
-
- final Pair<Double, Long> originalResult;
- final Pair<Double, Long> optimizedResult;
- if (RANDOM.nextBoolean()) {
- originalResult = TimeUtil.clockWithResult(clockRuns, original);
- optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
- } else {
- optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
- originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ @Test
+ public void shouldBeFasterWithDuplicateStream() {
+ final int startSize = 1000;
+ final int clockRuns = 1000;
+ final int uniques = 100;
+ final Integer[] starts = new Integer[startSize];
+ for (int i = 0; i < startSize; i++) {
+ starts[i] = i % uniques; // 100 unique objects
+ }
+ assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size());
+ clockTraversals(starts, clockRuns);
}
- // System.out.println(originalResult + "---" + optimizedResult);
- assertEquals(originalResult.getValue1(), optimizedResult.getValue1());
- assertTrue(originalResult.getValue0() > optimizedResult.getValue0());
+ private void clockTraversals(final Integer[] starts, final int clockRuns) {
+ final int times = RANDOM.nextInt(4) + 2;
+ assertTrue(times > 1 && times < 6);
+ final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next();
+
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(RepeatUnrollStrategy.instance());
+ final Supplier<Long> optimized = () -> {
+ final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum();
+ traversal.asAdmin().setStrategies(strategies);
+ return traversal.next();
+ };
+
+ final Pair<Double, Long> originalResult;
+ final Pair<Double, Long> optimizedResult;
+ if (RANDOM.nextBoolean()) {
+ originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
+ } else {
+ optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
+ originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ }
+
+ // System.out.println(originalResult + "---" + optimizedResult);
+ assertEquals(originalResult.getValue1(), optimizedResult.getValue1());
+ assertTrue(originalResult.getValue0() > optimizedResult.getValue0());
+ }
}
}
[33/50] [abbrv] tinkerpop git commit: updated changelog.
Posted by tw...@apache.org.
updated changelog.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/44ad2ebd
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/44ad2ebd
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/44ad2ebd
Branch: refs/heads/TINKERPOP-1254
Commit: 44ad2ebdcd5d4f20d2e3f26a8538328b5cf5abb6
Parents: 7f22595
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Jun 30 07:16:05 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Jun 30 07:16:05 2016 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/44ad2ebd/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 94bb67e..71d394d 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,10 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.2.1 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Added `RepeatUnrollStrategy` to linearize a `repeat()`-traversal if loop amount is known at compile time.
+* Fixed a bug in `BranchStep` around child integration during `clone()`.
+* Fixed a bug in `AbstractStep` around label set cloning.
+* Added `TraversalStrategyPerformanceTest` for verifying the performance gains of optimization-based traversal strategies.
* `TraversalExplanation.prettyPrint()` exists which provides word wrapping and GremlinConsole is smart to use console width to control `toString()`.
* `TraversalOpProcessor` (`RemoteConnection`) uses `HaltedTraverserStrategy` metadata to determine detachment procedure prior to returning results.
* Allow DFS paths in `HADOOP_GREMLIN_LIBS`.
[06/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/tp31'
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/tp31'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/b2cf6d87
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/b2cf6d87
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/b2cf6d87
Branch: refs/heads/TINKERPOP-1254
Commit: b2cf6d8717a70148f0a9595217c30e6d2158afb4
Parents: 668bee3 45e19af
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 17 06:25:30 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 17 06:25:30 2016 -0400
----------------------------------------------------------------------
.../reference/implementations-neo4j.asciidoc | 74 ++++++++++++++++++++
1 file changed, 74 insertions(+)
----------------------------------------------------------------------
[28/50] [abbrv] tinkerpop git commit: added missing license header
Posted by tw...@apache.org.
added missing license header
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/05d4c32d
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/05d4c32d
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/05d4c32d
Branch: refs/heads/TINKERPOP-1254
Commit: 05d4c32dcb72620cfff983e5b17bb9690ba91d30
Parents: f87ef12
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed Jun 29 18:08:03 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Wed Jun 29 18:08:03 2016 +0200
----------------------------------------------------------------------
.../TraversalStrategyPerformanceTest.java | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/05d4c32d/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
index 5e496f1..4ddd877 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
@@ -1,3 +1,21 @@
+/*
+ * 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;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
[10/50] [abbrv] tinkerpop git commit: Updated instructions on how to
process a single AsciiDoc file.
Posted by tw...@apache.org.
Updated instructions on how to process a single AsciiDoc file.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/9ff14b73
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/9ff14b73
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/9ff14b73
Branch: refs/heads/TINKERPOP-1254
Commit: 9ff14b7305eeb527f53baaf3590d295f1fdb52a1
Parents: da26cf1
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Fri Jun 17 16:50:11 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Fri Jun 17 16:50:11 2016 +0200
----------------------------------------------------------------------
docs/src/dev/developer/development-environment.asciidoc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/9ff14b73/docs/src/dev/developer/development-environment.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/developer/development-environment.asciidoc b/docs/src/dev/developer/development-environment.asciidoc
index 70e0dcd..23df9ee 100644
--- a/docs/src/dev/developer/development-environment.asciidoc
+++ b/docs/src/dev/developer/development-environment.asciidoc
@@ -41,7 +41,7 @@ mvn -Dmaven.javadoc.skip=true --projects tinkergraph-gremlin test
** Build AsciiDocs (but don't evaluate code blocks): `bin/process-docs.sh --dryRun`
** Build AsciiDocs (but don't evaluate code blocks in specific files): `bin/process-docs.sh --dryRun docs/src/reference/the-graph.asciidoc,docs/src/tutorial/getting-started,...`
** Build AsciiDocs (but evaluate code blocks only in specific files): `bin/process-docs.sh --fullRun docs/src/reference/the-graph.asciidoc,docs/src/tutorial/getting-started,...`
-** Process a single AsciiDoc file: +pass:[docs/preprocessor/preprocess-file.sh `pwd`/gremlin-console/target/apache-gremlin-console-*-standalone `pwd`/docs/src/xyz.asciidoc]+
+** Process a single AsciiDoc file: +pass:[docs/preprocessor/preprocess-file.sh `pwd`/gremlin-console/target/apache-gremlin-console-*-standalone "" "*" `pwd`/docs/src/xyz.asciidoc]+
* Build JavaDocs: `mvn process-resources -Djavadoc`
* Check for Apache License headers: `mvn apache-rat:check`
* Check for newer dependencies: `mvn versions:display-dependency-updates` or `mvn versions:display-plugin-updates`
@@ -96,4 +96,4 @@ Developers working on the `neo4j-gremlin` module should enabled the `include-neo
This will ensure that tests will properly execute within the IDE.
If Intellij complains about "duplicate sources" for the Groovy files when attempting to compile/run tests, then
-install the link:http://plugins.jetbrains.com/plugin/7442?pr=idea[GMavenPlus Intellij plugin].
\ No newline at end of file
+install the link:http://plugins.jetbrains.com/plugin/7442?pr=idea[GMavenPlus Intellij plugin].
[17/50] [abbrv] tinkerpop git commit: Enhanced pre-processor output
for failure cases.
Posted by tw...@apache.org.
Enhanced pre-processor output for failure cases.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/98f09bad
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/98f09bad
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/98f09bad
Branch: refs/heads/TINKERPOP-1254
Commit: 98f09bad615c2be3b5f8a4145f9a106977f13d6b
Parents: 82afed3
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Tue Jun 28 14:02:32 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Tue Jun 28 14:02:32 2016 +0200
----------------------------------------------------------------------
docs/preprocessor/preprocess-file.sh | 7 +++++++
1 file changed, 7 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/98f09bad/docs/preprocessor/preprocess-file.sh
----------------------------------------------------------------------
diff --git a/docs/preprocessor/preprocess-file.sh b/docs/preprocessor/preprocess-file.sh
index 35b1f15..57a8b98 100755
--- a/docs/preprocessor/preprocess-file.sh
+++ b/docs/preprocessor/preprocess-file.sh
@@ -71,6 +71,13 @@ fi
trap cleanup INT
function cleanup {
+ if [ -f "${output}" ]; then
+ if [ `wc -l /tmp/foo | awk '{print $1}'` -gt 0 ]; then
+ echo -e "\n\e[1mLast 10 lines of ${output}:\e[0m\n"
+ tail -n10 ${output}
+ echo
+ fi
+ fi
rm -rf ${output} ${CONSOLE_HOME}/.ext
exit 255
}
[14/50] [abbrv] tinkerpop git commit: Merge branch 'master' into
TINKERPOP-1332
Posted by tw...@apache.org.
Merge branch 'master' into TINKERPOP-1332
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/7dfd0ddc
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/7dfd0ddc
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/7dfd0ddc
Branch: refs/heads/TINKERPOP-1254
Commit: 7dfd0ddcd836aba34d2eec83bc2844cbc1d03c67
Parents: 090efe3 408755d
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 21 16:44:29 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 21 16:44:29 2016 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 +
bin/validate-distribution.sh | 9 +-
docs/src/dev/developer/administration.asciidoc | 5 +-
.../developer/development-environment.asciidoc | 4 +-
docs/src/dev/provider/index.asciidoc | 67 +
docs/src/recipes/centrality.asciidoc | 6 +
.../reference/implementations-hadoop.asciidoc | 70 +-
.../reference/implementations-neo4j.asciidoc | 77 +-
docs/src/reference/the-traversal.asciidoc | 3 +-
docs/static/images/neo4j-ha.png | Bin 0 -> 108249 bytes
docs/static/images/tinkerpop3.graffle | 23433 ++++++++---------
.../gremlin/process/remote/RemoteGraph.java | 20 +-
.../decoration/HaltedTraverserStrategy.java | 8 +-
.../strategy/decoration/SubgraphStrategy.java | 40 +-
.../driver/remote/DriverRemoteConnection.java | 3 +-
.../op/traversal/TraversalOpProcessor.java | 21 +-
.../process/traversal/step/map/OrderTest.java | 1 +
.../decoration/SubgraphStrategyProcessTest.java | 22 +
18 files changed, 11866 insertions(+), 11925 deletions(-)
----------------------------------------------------------------------
[12/50] [abbrv] tinkerpop git commit: Fixed up TraversalOpProcessor
to use HaltedTraversalStrategy to decide detachement with ReferenceFactory
being the default (as before). This allowed me to open uup a bunch more
OPT_OUT tests on RemoteGraph.
Posted by tw...@apache.org.
Fixed up TraversalOpProcessor to use HaltedTraversalStrategy to decide detachement with ReferenceFactory being the default (as before). This allowed me to open uup a bunch more OPT_OUT tests on RemoteGraph.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/408755de
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/408755de
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/408755de
Branch: refs/heads/TINKERPOP-1254
Commit: 408755de33de1eb23441347ac6bbe0b084828d9c
Parents: 2eafeef
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 21 11:43:14 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 21 12:06:24 2016 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../gremlin/process/remote/RemoteGraph.java | 20 ++++++++-----------
.../decoration/HaltedTraverserStrategy.java | 8 +++++---
.../driver/remote/DriverRemoteConnection.java | 3 ++-
.../op/traversal/TraversalOpProcessor.java | 21 ++++++++++++--------
5 files changed, 29 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/408755de/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index ea940a8..1ba08d4 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.2.1 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* `TraversalOpProcessor` (`RemoteConnection`) uses `HaltedTraverserStrategy` metadata to determine detachment procedure prior to returning results.
* Allow DFS paths in `HADOOP_GREMLIN_LIBS`.
* Added a safer serializer infrastructure for use with `SparkGraphComputer` that uses `KryoSerializer` and the new `GryoRegistrator`.
* Added `HaltedTraverserStrategy` to allow users to get back different element detachments in OLAP.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/408755de/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
index f46fe90..590398e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/RemoteGraph.java
@@ -46,6 +46,10 @@ import java.util.Iterator;
@Graph.OptIn(Graph.OptIn.SUITE_PROCESS_STANDARD)
@Graph.OptIn(Graph.OptIn.SUITE_PROCESS_COMPUTER)
@Graph.OptOut(
+ test = "org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTest$Traversals",
+ method = "g_withSideEffectXa_g_VX2XX_VX1X_out_whereXneqXaXX",
+ reason = "RemoteGraph can not handle a sideEffect that is spawned by a traversal")
+@Graph.OptOut(
test = "org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest",
method = "shouldNeverPropagateANoBulkTraverser",
reason = "RemoteGraph can't serialize a lambda so the test fails before it has a chance for the Traversal to be evaluated")
@@ -54,6 +58,10 @@ import java.util.Iterator;
method = "shouldNeverPropagateANullValuedTraverser",
reason = "RemoteGraph can't serialize a lambda so the test fails before it has a chance for the Traversal to be evaluated")
@Graph.OptOut(
+ test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest",
+ method = "*",
+ reason = "RemoteGraph retrieves detached vertices that can't be attached to a remote OLAP graph")
+@Graph.OptOut(
test = "org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategyProcessTest",
method = "*",
reason = "RemoteGraph does not support ElementIdStrategy at this time - it requires a lambda in construction which is not serializable")
@@ -66,18 +74,6 @@ import java.util.Iterator;
method = "*",
reason = "RemoteGraph does not support PartitionStrategy at this time")
@Graph.OptOut(
- test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.PeerPressureTest",
- method = "g_V_peerPressure",
- reason = "RemoteGraph retrieves detached vertices that can't be attached to a remote OLAP graph")
-@Graph.OptOut(
- test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.PageRankTest",
- method = "g_V_pageRank",
- reason = "RemoteGraph retrieves detached vertices that can't be attached to a remote OLAP graph")
-@Graph.OptOut(
- test = "org.apache.tinkerpop.gremlin.process.traversal.step.map.ProgramTest",
- method = "g_V_programXpageRankX",
- reason = "RemoteGraph retrieves detached vertices that can't be attached to a remote OLAP graph")
-@Graph.OptOut(
test = "org.apache.tinkerpop.gremlin.process.computer.ranking.pagerank.PageRankVertexProgramTest",
method = "*",
reason = "RemoteGraph does not support direct Graph.compute() access")
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/408755de/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
index 45966f0..1a2c207 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/HaltedTraverserStrategy.java
@@ -32,11 +32,13 @@ import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
public final class HaltedTraverserStrategy extends AbstractTraversalStrategy<TraversalStrategy.DecorationStrategy> implements TraversalStrategy.DecorationStrategy {
private final Class haltedTraverserFactory;
+ private final boolean useReference;
private HaltedTraverserStrategy(final Class haltedTraverserFactory) {
- if (haltedTraverserFactory.equals(DetachedFactory.class) || haltedTraverserFactory.equals(ReferenceFactory.class))
+ if (haltedTraverserFactory.equals(DetachedFactory.class) || haltedTraverserFactory.equals(ReferenceFactory.class)) {
this.haltedTraverserFactory = haltedTraverserFactory;
- else
+ this.useReference = ReferenceFactory.class.equals(this.haltedTraverserFactory);
+ } else
throw new IllegalArgumentException("The provided traverser detachment factory is unknown: " + haltedTraverserFactory);
}
@@ -49,7 +51,7 @@ public final class HaltedTraverserStrategy extends AbstractTraversalStrategy<Tra
}
public <R> Traverser.Admin<R> halt(final Traverser.Admin<R> traverser) {
- if (ReferenceFactory.class.equals(this.haltedTraverserFactory))
+ if (this.useReference)
traverser.set(ReferenceFactory.detach(traverser.get()));
else
traverser.set(DetachedFactory.detach(traverser.get(), true));
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/408755de/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
index a6303a6..2bea54b 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnection.java
@@ -22,6 +22,7 @@ import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.driver.Client;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.Result;
+import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.decoration.VertexProgramStrategy;
import org.apache.tinkerpop.gremlin.process.remote.RemoteConnection;
import org.apache.tinkerpop.gremlin.process.remote.RemoteConnectionException;
import org.apache.tinkerpop.gremlin.process.remote.RemoteGraph;
@@ -160,7 +161,7 @@ public class DriverRemoteConnection implements RemoteConnection {
@Override
public <E> Iterator<Traverser.Admin<E>> submit(final Traversal<?, E> t) throws RemoteConnectionException {
try {
- if (attachElements) {
+ if (attachElements && !t.asAdmin().getStrategies().toList().stream().filter(s -> s instanceof VertexProgramStrategy).findAny().isPresent()) {
if (!conf.isPresent()) throw new IllegalStateException("Traverser can't be reattached for testing");
final Graph graph = ((Supplier<Graph>) conf.get().getProperty("hidden.for.testing.only")).get();
return new AttachingTraverserIterator<>(client.submit(t).iterator(), graph);
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/408755de/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
index bdb692d..8bff220 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java
@@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.HaltedTraverserStrategy;
import org.apache.tinkerpop.gremlin.server.Context;
import org.apache.tinkerpop.gremlin.server.GraphManager;
import org.apache.tinkerpop.gremlin.server.GremlinServer;
@@ -45,7 +46,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import static com.codahale.metrics.MetricRegistry.name;
@@ -127,7 +127,7 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
// earlier validation in selection of this op method should free us to cast this without worry
final Map<String, String> aliases = (Map<String, String>) msg.optionalArgs(Tokens.ARGS_ALIASES).get();
- final Traversal.Admin<?,?> traversal;
+ final Traversal.Admin<?, ?> traversal;
try {
traversal = (Traversal.Admin) Serializer.deserializeObject(serializedTraversal);
} catch (Exception ex) {
@@ -158,7 +158,7 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
try {
// compile the traversal - without it getEndStep() has nothing in it
traversal.applyStrategies();
- handleIterator(context, new DetachingIterator<>(traversal.getEndStep()));
+ handleIterator(context, new DetachingIterator<>(traversal));
} catch (TimeoutException ex) {
final String errorMessage = String.format("Response iteration exceeded the configured threshold for request [%s] - %s", msg.getRequestId(), ex.getMessage());
logger.warn(errorMessage);
@@ -200,19 +200,24 @@ public class TraversalOpProcessor extends AbstractOpProcessor {
static class DetachingIterator<E> implements Iterator<Traverser.Admin<E>> {
private Iterator<Traverser.Admin<E>> inner;
-
- public DetachingIterator(final Iterator<Traverser.Admin<E>> toDetach) {
- inner = toDetach;
+ private HaltedTraverserStrategy haltedTraverserStrategy;
+
+ public DetachingIterator(final Traversal.Admin<?, E> traversal) {
+ this.inner = traversal.getEndStep();
+ this.haltedTraverserStrategy = (HaltedTraverserStrategy) traversal.getStrategies().toList().stream().filter(s -> s instanceof HaltedTraverserStrategy).findAny().orElse(
+ Boolean.valueOf(System.getProperty("is.testing", "false")) ?
+ HaltedTraverserStrategy.detached() :
+ HaltedTraverserStrategy.reference());
}
@Override
public boolean hasNext() {
- return inner.hasNext();
+ return this.inner.hasNext();
}
@Override
public Traverser.Admin<E> next() {
- return inner.next().detach();
+ return this.haltedTraverserStrategy.halt(this.inner.next());
}
}
}
[36/50] [abbrv] tinkerpop git commit: Added more invalid binding keys
to Gremlin Server OpProcessor validation.
Posted by tw...@apache.org.
Added more invalid binding keys to Gremlin Server OpProcessor validation.
These "invalid" keys are reserved terms for Gremlin Server as they are statically imported enums and shouldn't be used as binding keys. You get some less than easy to understand error messages if those keys are used.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/c37c3016
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/c37c3016
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/c37c3016
Branch: refs/heads/TINKERPOP-1254
Commit: c37c3016bd05b3caeb09084f5469c606c439bfe5
Parents: 1c9bd08
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 30 13:07:44 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 30 13:07:44 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../upgrade/release-3.1.x-incubating.asciidoc | 12 +++++
.../gremlin/process/traversal/Scope.java | 2 -
.../server/op/AbstractEvalOpProcessor.java | 54 +++++++++++++++++---
.../server/GremlinServerIntegrateTest.java | 21 +++++++-
5 files changed, 79 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c37c3016/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 2ae2e77..3fd646a 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,6 +33,7 @@ TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
* Improved `TinkerGraph` performance when iterating vertices and edges.
* Fixed a bug where timeout functions provided to the `GremlinExecutor` were not executing in the same thread as the script evaluation.
* Optimized a few special cases in `RangeByIsCountStrategy`.
+* Added more "invalid" variable bindings to the list used by Gremlin Server to validate incoming bindings on requests.
* Named the thread pool used by Gremlin Server sessions: "gremlin-server-session-$n".
* Fixed a bug in `BulkSet.equals()` which made itself apparent when using `store()` and `aggregate()` with labeled `cap()`.
* Fixed a bug where `Result.one()` could potentially block indefinitely under certain circumstances.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c37c3016/docs/src/upgrade/release-3.1.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.1.x-incubating.asciidoc b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
index b1b99f8..504baaa 100644
--- a/docs/src/upgrade/release-3.1.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
@@ -32,6 +32,16 @@ Please see the link:https://github.com/apache/incubator-tinkerpop/blob/3.1.3/CHA
Upgrading for Users
~~~~~~~~~~~~~~~~~~~
+Reserved Gremlin Server Keys
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Gremlin Server has always considered certain binding keys (request parameters) as reserved, but that list has now
+expanded to be more inclusive all the static enums that are imported to the script engine. It is possible that those
+using Gremlin Server may have to rename their keys if they somehow successfully were using some of the now reserved
+terms in previous versions.
+
+See: https://issues.apache.org/jira/browse/TINKERPOP-1354[TINKERPOP-1354]
+
Remote Timeout
^^^^^^^^^^^^^^
@@ -54,6 +64,8 @@ set to `none`.
See: https://issues.apache.org/jira/browse/TINKERPOP-1267[TINKERPOP-1267]
+
+
Upgrading for Providers
~~~~~~~~~~~~~~~~~~~~~~~
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c37c3016/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Scope.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Scope.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Scope.java
index 1cce1e0..11979de 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Scope.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Scope.java
@@ -18,8 +18,6 @@
*/
package org.apache.tinkerpop.gremlin.process.traversal;
-import java.util.Map;
-
/**
* Many {@link Step} instance can have a variable scope.
* {@link Scope#global}: the step operates on the entire traversal.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c37c3016/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index a5dd0a0..f712b44 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -28,10 +28,15 @@ import org.apache.tinkerpop.gremlin.driver.message.ResponseStatusCode;
import org.apache.tinkerpop.gremlin.driver.ser.MessageTextSerializer;
import org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor;
import org.apache.tinkerpop.gremlin.groovy.jsr223.customizer.TimedInterruptTimeoutException;
+import org.apache.tinkerpop.gremlin.process.traversal.Operator;
+import org.apache.tinkerpop.gremlin.process.traversal.Order;
+import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.process.traversal.Scope;
import org.apache.tinkerpop.gremlin.server.GraphManager;
import org.apache.tinkerpop.gremlin.server.handler.Frame;
import org.apache.tinkerpop.gremlin.server.handler.GremlinResponseFrameEncoder;
import org.apache.tinkerpop.gremlin.server.handler.StateKey;
+import org.apache.tinkerpop.gremlin.structure.Column;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.server.Context;
import org.apache.tinkerpop.gremlin.server.GremlinServer;
@@ -54,11 +59,13 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import java.util.regex.Pattern;
+import java.util.stream.Stream;
import static com.codahale.metrics.MetricRegistry.name;
@@ -84,7 +91,12 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
/**
* Regex for validating that binding variables.
+ *
+ * @deprecated As of release 3.1.2-incubating, not replaced. This {@code Pattern} is not used internally.
+ * Deprecated rather than just removing as it's possible that someone else might be using it when developing
+ * custom {@link OpProcessor} implementations.
*/
+ @Deprecated
protected static final Pattern validBindingName = Pattern.compile("[a-zA-Z$_][a-zA-Z0-9$_]*");
/**
@@ -95,12 +107,37 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
* Use of {@code toUpperCase()} on the accessor values of {@link T} solves an issue where the {@code ScriptEngine}
* ignores private scope on {@link T} and imports static fields.
*/
- private static final List<String> invalidBindingsKeys = Arrays.asList(
- T.id.getAccessor(), T.key.getAccessor(),
- T.label.getAccessor(), T.value.getAccessor(),
- T.id.getAccessor().toUpperCase(), T.key.getAccessor().toUpperCase(),
- T.label.getAccessor().toUpperCase(), T.value.getAccessor().toUpperCase());
- private static final String invalidBindingKeysJoined = String.join(",", invalidBindingsKeys);
+ protected static final Set<String> INVALID_BINDINGS_KEYS = new HashSet<>();
+
+ static {
+ INVALID_BINDINGS_KEYS.addAll(Arrays.asList(
+ T.id.name(), T.key.name(),
+ T.label.name(), T.value.name(),
+ T.id.getAccessor(), T.key.getAccessor(),
+ T.label.getAccessor(), T.value.getAccessor(),
+ T.id.getAccessor().toUpperCase(), T.key.getAccessor().toUpperCase(),
+ T.label.getAccessor().toUpperCase(), T.value.getAccessor().toUpperCase()));
+
+ for (Column enumItem : Column.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Order enumItem : Order.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Operator enumItem : Operator.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Scope enumItem : Scope.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+
+ for (Pop enumItem : Pop.values()) {
+ INVALID_BINDINGS_KEYS.add(enumItem.name());
+ }
+ }
protected final boolean manageTransactions;
@@ -155,8 +192,9 @@ public abstract class AbstractEvalOpProcessor implements OpProcessor {
throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create());
}
- if (bindings.keySet().stream().anyMatch(invalidBindingsKeys::contains)) {
- final String msg = String.format("The [%s] message is using at least one of the invalid binding key of [%s]. It conflicts with standard static imports to Gremlin Server.", Tokens.OPS_EVAL, invalidBindingKeysJoined);
+ final Set<String> badBindings = IteratorUtils.set(IteratorUtils.<String>filter(bindings.keySet().iterator(), INVALID_BINDINGS_KEYS::contains));
+ if (!badBindings.isEmpty()) {
+ final String msg = String.format("The [%s] message supplies one or more invalid parameters key of [%s] - these are reserved names.", Tokens.OPS_EVAL, badBindings);
throw new OpProcessorException(msg, ResponseMessage.build(message).code(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS).statusMessage(msg).create());
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c37c3016/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 99bb745..2f091d9 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -55,7 +55,6 @@ import org.junit.Before;
import org.junit.Test;
import java.nio.channels.ClosedChannelException;
-import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -412,6 +411,26 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
fail("Request should have returned error, but instead timed out");
assertTrue(pass.get());
}
+
+ try (SimpleClient client = new WebSocketClient()) {
+ final Map<String, Object> bindings = new HashMap<>();
+ bindings.put("id", "123");
+ final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+ .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+ .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AtomicBoolean pass = new AtomicBoolean(false);
+ client.submit(request, result -> {
+ if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+ pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+ latch.countDown();
+ }
+ });
+
+ if (!latch.await(3000, TimeUnit.MILLISECONDS))
+ fail("Request should have returned error, but instead timed out");
+ assertTrue(pass.get());
+ }
}
@Test
[27/50] [abbrv] tinkerpop git commit: Refactored traversal strategy
performance tests.
Posted by tw...@apache.org.
Refactored traversal strategy performance tests.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f87ef124
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f87ef124
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f87ef124
Branch: refs/heads/TINKERPOP-1254
Commit: f87ef1240bb8376862e960c848129837f049bdb5
Parents: e6071c0
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Wed Jun 29 17:07:54 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Wed Jun 29 17:07:54 2016 +0200
----------------------------------------------------------------------
.../TraversalStrategyPerformanceTest.java | 102 +++++++++++++++++++
.../IdentityRemovalStrategyTest.java | 72 ++++++-------
.../optimization/RepeatUnrollStrategyTest.java | 86 ++++++++--------
3 files changed, 174 insertions(+), 86 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f87ef124/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
new file mode 100644
index 0000000..5e496f1
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/TraversalStrategyPerformanceTest.java
@@ -0,0 +1,102 @@
+package org.apache.tinkerpop.gremlin.process.traversal.strategy;
+
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.apache.tinkerpop.gremlin.util.TimeUtil;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ */
+public abstract class TraversalStrategyPerformanceTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TraversalStrategyPerformanceTest.class);
+ private static final Random RANDOM = new Random();
+
+ protected int getClockRuns() {
+ return 1000;
+ }
+
+ /**
+ * Specifies for how many percent of all comparisons the optimized traversal must be faster than the
+ * original traversal. Default is 100.
+ */
+ protected double getAssertionPercentile() {
+ return 100.0;
+ }
+
+ protected abstract Class<? extends TraversalStrategy> getStrategyUnderTest();
+
+ protected TraversalStrategy<?> getStrategyUnderTestInstance() throws Exception {
+ return (TraversalStrategy) getStrategyUnderTest().getMethod("instance").invoke(null);
+ }
+
+ protected abstract Iterator<GraphTraversal> getTraversalIterator();
+
+ @Test
+ public void shouldBeFaster() throws Exception {
+
+ final TraversalStrategies withStrategyUnderTest = new DefaultTraversalStrategies();
+ withStrategyUnderTest.addStrategies(getStrategyUnderTestInstance());
+
+ final TraversalStrategies withoutStrategyUnderTest = new DefaultTraversalStrategies();
+ withoutStrategyUnderTest.removeStrategies(getStrategyUnderTest());
+
+ final int clockRuns = getClockRuns();
+ final Iterator<GraphTraversal> iterator = getTraversalIterator();
+ int faster = 0, numTraversals = 0;
+ while (iterator.hasNext()) {
+
+ final GraphTraversal traversal = iterator.next();
+ final GraphTraversal.Admin original = traversal.asAdmin();
+ final GraphTraversal.Admin optimized = original.clone();
+
+ original.setStrategies(withoutStrategyUnderTest);
+ optimized.setStrategies(withStrategyUnderTest);
+
+ final double originalTime, optimizedTime;
+
+ if (RANDOM.nextBoolean()) {
+ originalTime = TimeUtil.clock(clockRuns, () -> original.clone().iterate());
+ optimizedTime = TimeUtil.clock(clockRuns, () -> optimized.clone().iterate());
+ } else {
+ optimizedTime = TimeUtil.clock(clockRuns, () -> optimized.clone().iterate());
+ originalTime = TimeUtil.clock(clockRuns, () -> original.clone().iterate());
+ }
+
+ final List originalResult = original.toList();
+ final List optimizedResult = optimized.toList();
+
+ if (originalTime > optimizedTime) {
+ LOGGER.debug("Original traversal ({} ms): {}", originalTime, original);
+ LOGGER.debug("Optimized traversal ({} ms): {}", optimizedTime, optimized);
+ } else {
+ LOGGER.warn("Original traversal ({} ms): {}", originalTime, original);
+ LOGGER.warn("Optimized traversal ({} ms): {}", optimizedTime, optimized);
+ }
+
+ if (getAssertionPercentile() >= 100) assertTrue(originalTime > optimizedTime);
+ else {
+ if (originalTime > optimizedTime)
+ faster++;
+ numTraversals++;
+ }
+
+ assertEquals(originalResult, optimizedResult);
+ }
+
+ if (getAssertionPercentile() < 100)
+ assertTrue(((faster * 100.0) / numTraversals) >= getAssertionPercentile());
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f87ef124/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
index c5099f9..065dc53 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
@@ -20,20 +20,21 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyPerformanceTest;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
-import org.apache.tinkerpop.gremlin.util.TimeUtil;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
-import java.util.Random;
+import java.util.Iterator;
+import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
/**
@@ -82,52 +83,39 @@ public class IdentityRemovalStrategyTest {
}
- public static class NonParameterizedTests {
+ public static class PerformanceTest extends TraversalStrategyPerformanceTest {
- private static final Random RANDOM = new Random();
+ @Override
+ protected Class<? extends TraversalStrategy> getStrategyUnderTest() {
+ return IdentityRemovalStrategy.class;
+ }
- @Test
- public void shouldBeFaster() {
-
- final int startSize = 1000;
- final int clockRuns = 2000;
- final int maxIdentities = 10;
- final int minIdentities = 3;
- final Integer[] starts = new Integer[startSize];
- for (int i = 0; i < startSize; i++) {
- starts[i] = i;
- }
-
- for (int i = minIdentities; i < maxIdentities; i++) {
- final int numberOfIdentities = i;
- final Runnable original = () -> {
- final GraphTraversal<Integer, Integer> traversal = __.inject(starts);
- for (int j = 0; j < numberOfIdentities; j++) {
- traversal.identity();
- }
- traversal.iterate();
- };
+ @Override
+ protected Iterator<GraphTraversal> getTraversalIterator() {
+
+ return new Iterator<GraphTraversal>() {
+
+ final int minIdentities = 3;
+ final int maxIdentities = 10;
+ final Integer[] starts = IntStream.range(0, 1000).boxed().toArray(Integer[]::new);
+
+ private int numberOfIdentities = minIdentities;
+
+ @Override
+ public boolean hasNext() {
+ return numberOfIdentities <= maxIdentities;
+ }
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(IdentityRemovalStrategy.instance());
- final Runnable optimized = () -> {
- final GraphTraversal<Integer, Integer> traversal = __.inject(starts);
+ @Override
+ public GraphTraversal next() {
+ final GraphTraversal traversal = __.inject(starts);
for (int j = 0; j < numberOfIdentities; j++) {
traversal.identity();
}
- traversal.asAdmin().setStrategies(strategies);
- traversal.iterate();
- };
-
- //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns, optimized));
- if (RANDOM.nextBoolean()) {
- assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
- assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
- } else {
- assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
- assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
+ numberOfIdentities++;
+ return traversal;
}
- }
+ };
}
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f87ef124/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
index 91ab2ae..d409cc2 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
@@ -21,25 +21,24 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyPerformanceTest;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.util.TimeUtil;
-import org.javatuples.Pair;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Random;
+import java.util.Iterator;
import java.util.function.Predicate;
-import java.util.function.Supplier;
+import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -48,8 +47,6 @@ import static org.junit.Assert.assertTrue;
@RunWith(Enclosed.class)
public class RepeatUnrollStrategyTest {
- private static final Random RANDOM = new Random();
-
@RunWith(Parameterized.class)
public static class ParameterizedTests {
@@ -98,46 +95,47 @@ public class RepeatUnrollStrategyTest {
}
}
- public static class NonParameterizedTests {
+ public static class PerformanceTest extends TraversalStrategyPerformanceTest {
- @Test
- public void shouldBeFaster() {
- final int startSize = 1000;
- final int clockRuns = 1000;
- for (int i = 100; i <= startSize; i = i + 200) {
- final Integer[] starts = new Integer[startSize];
- for (int j = 0; j < startSize; j++) {
- starts[j] = j % i;
+ @Override
+ protected double getAssertionPercentile() {
+ return 95.0;
+ }
+
+ @Override
+ protected Class<? extends TraversalStrategy> getStrategyUnderTest() {
+ return RepeatUnrollStrategy.class;
+ }
+
+ @Override
+ protected Iterator<GraphTraversal> getTraversalIterator() {
+
+ return new Iterator<GraphTraversal>() {
+
+ final int minLoops = 2;
+ final int maxLoops = 5;
+ final int minModulo = 100;
+ final int maxModulo = 1000;
+
+ private int numberOfLoops = minLoops;
+ private int modulo = minModulo;
+
+ @Override
+ public boolean hasNext() {
+ return modulo <= maxModulo;
}
- assertEquals(i, new HashSet<>(Arrays.asList(starts)).size());
- ///
- for (int j = 2; j < 6; j++) {
- final int times = j;
- final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next();
-
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(RepeatUnrollStrategy.instance());
- final Supplier<Long> optimized = () -> {
- final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum();
- traversal.asAdmin().setStrategies(strategies);
- return traversal.next();
- };
-
- final Pair<Double, Long> originalResult;
- final Pair<Double, Long> optimizedResult;
- if (RANDOM.nextBoolean()) {
- originalResult = TimeUtil.clockWithResult(clockRuns, original);
- optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
- } else {
- optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
- originalResult = TimeUtil.clockWithResult(clockRuns, original);
- }
- // System.out.println(originalResult + "---" + optimizedResult);
- assertEquals(originalResult.getValue1(), optimizedResult.getValue1());
- assertTrue(originalResult.getValue0() > optimizedResult.getValue0());
+ @Override
+ public GraphTraversal next() {
+ final Integer[] starts = IntStream.range(0, 1000).map(i -> i % modulo).boxed().toArray(Integer[]::new);
+ final GraphTraversal traversal = __.inject(starts).repeat(__.identity()).times(numberOfLoops).sum();
+ if (++numberOfLoops > maxLoops) {
+ numberOfLoops = minLoops;
+ modulo += 200;
+ }
+ return traversal;
}
- }
+ };
}
}
}
[07/50] [abbrv] tinkerpop git commit: removed NOTE: Neo4jGraph
currently does not support HA and added an image for the HA section. CTR.
Posted by tw...@apache.org.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/da26cf18/docs/static/images/tinkerpop3.graffle
----------------------------------------------------------------------
diff --git a/docs/static/images/tinkerpop3.graffle b/docs/static/images/tinkerpop3.graffle
index de98d34..11a1a94 100644
--- a/docs/static/images/tinkerpop3.graffle
+++ b/docs/static/images/tinkerpop3.graffle
@@ -4,8 +4,8 @@
<dict>
<key>ApplicationVersion</key>
<array>
- <string>com.omnigroup.OmniGrafflePro</string>
- <string>139.18.0.187838</string>
+ <string>com.omnigroup.OmniGraffle6</string>
+ <string>169.14.0.260934</string>
</array>
<key>CreationDate</key>
<string>2014-05-12 16:00:33 +0000</string>
@@ -14,19 +14,557 @@
<key>FileType</key>
<string>flat</string>
<key>GraphDocumentVersion</key>
- <integer>8</integer>
+ <integer>12</integer>
<key>GuidesLocked</key>
<string>NO</string>
<key>GuidesVisible</key>
<string>YES</string>
<key>ImageCounter</key>
- <integer>120</integer>
+ <integer>121</integer>
<key>Images</key>
<array>
<dict>
<key>Extension</key>
<string>tiff</string>
<key>ID</key>
+ <integer>120</integer>
+ <key>RawData</key>
+ <data>
+ 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
+ AAAAJgAAAah0aFRIAAAAJgAAAahlc1hMAAAAJgAAAahkZURFAAAA
+ JgAAAahlblVTAAAAJgAAAahwdEJSAAAAJgAAAahwbFBMAAAAJgAA
+ AahlbEdSAAAAJgAAAahzdlNFAAAAJgAAAah0clRSAAAAJgAAAahq
+ YUpQAAAAJgAAAahwdFBUAAAAJgAAAagAVABoAHUAbgBkAGUAcgBi
+ AG8AbAB0ACAARABpAHMAcABsAGEAeQAAdGV4dAAAAABDb3B5cmln
+ aHQgQXBwbGUgSW5jLiwgMjAxNgAAWFlaIAAAAAAAAPMWAAEAAAAB
+ FspYWVogAAAAAAAAccAAADmKAAABZ1hZWiAAAAAAAABhIwAAueYA
+ ABP2WFlaIAAAAAAAACPyAAAMkAAAvdBjdXJ2AAAAAAAABAAAAAAF
+ AAoADwAUABkAHgAjACgALQAyADYAOwBAAEUASgBPAFQAWQBeAGMA
+ aABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8AowCoAK0AsgC3ALwAwQDG
+ AMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIB
+ OAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHB
+ AckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcC
+ cQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4
+ A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAE
+ LQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6
+ BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoG
+ ewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfS
+ B+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8J
+ ZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsL
+ CyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM
+ 8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7u
+ DwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMR
+ MRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxOD
+ E6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMW
+ JhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjV
+ GPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib
+ 2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7p
+ HxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7Iici
+ VSKCIq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXH
+ JfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4KWsp
+ nSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12
+ Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIx
+ ujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9
+ Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6
+ sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9h
+ P6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdE
+ ikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mp
+ SfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBP
+ SU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1Tb
+ VShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa
+ 9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8
+ YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1n
+ k2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4S
+ bmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1
+ KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwh
+ fIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eD
+ uoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyosw
+ i5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOT
+ TZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtC
+ m6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj
+ 5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axc
+ rNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1
+ irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6E
+ vv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/I
+ Pci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+
+ 0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724Dc
+ BdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN
+ 5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw
+ 5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3
+ /Af8mP0p/br+S/7c/23//3BhcmEAAAAAAAMAAAACZmYAAPKnAAAN
+ WQAAE9AAAAoOdmNndAAAAAAAAAABAAEAAAAAAAAAAQAAAAEAAAAA
+ AAAAAQAAAAEAAAAAAAAAAQAAbmRpbgAAAAAAAAA2AACnQAAAVYAA
+ AEzAAACewAAAJYAAAAzAAABQAAAAVEAAAjMzAAIzMwACMzMAAAAA
+ AAAAAHNmMzIAAAAAAAEMcgAABfj///MdAAAHugAA/XL///ud///9
+ pAAAA9kAAMBxbW1vZAAAAAAAAAYQAACSJxgxFZ/QpAMAAAAAAAAA
+ AAAAAAAAAAAAAA==
+ </data>
+ </dict>
+ <dict>
+ <key>Extension</key>
+ <string>tiff</string>
+ <key>ID</key>
<integer>119</integer>
<key>RawData</key>
<data>
@@ -189173,7 +189711,7 @@
<key>MasterSheets</key>
<array/>
<key>ModificationDate</key>
- <string>2016-04-21 13:16:16 +0000</string>
+ <string>2016-06-17 13:23:32 +0000</string>
<key>Modifier</key>
<string>Marko Rodriguez</string>
<key>NotesVisible</key>
@@ -189202,12 +189740,12 @@
<key>NSPaperSize</key>
<array>
<string>size</string>
- <string>{612.00001430511475, 792}</string>
+ <string>{611.99999046325684, 792}</string>
</array>
<key>NSPrintReverseOrientation</key>
<array>
- <string>int</string>
- <string>0</string>
+ <string>coded</string>
+ <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
</array>
<key>NSRightMargin</key>
<array>
@@ -189232,7 +189770,7 @@
<key>BackgroundGraphic</key>
<dict>
<key>Bounds</key>
- <string>{{0, 0}, {576.00001430511475, 733}}</string>
+ <string>{{0, 0}, {575.99999046325684, 733}}</string>
<key>Class</key>
<string>SolidGraphic</string>
<key>FontInfo</key>
@@ -189246,11 +189784,6 @@
<integer>2</integer>
<key>Style</key>
<dict>
- <key>shadow</key>
- <dict>
- <key>Draws</key>
- <string>NO</string>
- </dict>
<key>stroke</key>
<dict>
<key>Draws</key>
@@ -189267,7 +189800,7 @@
<key>ColumnSpacing</key>
<real>36</real>
<key>DisplayScale</key>
- <string>1 0/72 in = 1.0000 in</string>
+ <string>1 in = 1.00000 in</string>
<key>GraphicsList</key>
<array>
<dict>
@@ -189288,8 +189821,6 @@
</dict>
<key>ID</key>
<integer>58</integer>
- <key>Shape</key>
- <string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
@@ -189311,14 +189842,14 @@
<key>Text</key>
<dict>
<key>Text</key>
- <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400
-\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 AmericanTypewriter;}
+ <string>{\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf470
+{\fonttbl\f0\fnil\fcharset0 AmericanTypewriter;}
{\colortbl;\red255\green255\blue255;}
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc\partightenfactor0
\f0\b\fs96 \cf0 TinkerPop}</string>
<key>VerticalPad</key>
- <integer>0</integer>
+ <real>0.0</real>
</dict>
<key>Wrap</key>
<string>NO</string>
@@ -189349,11 +189880,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -189376,13 +189907,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189432,11 +189963,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -189459,13 +189990,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189515,11 +190046,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -189542,13 +190073,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189595,11 +190126,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>0</string>
+ <real>0.0</real>
</dict>
</dict>
<key>shadow</key>
@@ -189661,13 +190192,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189679,11 +190210,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -189710,11 +190241,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>0</string>
+ <real>0.0</real>
</dict>
</dict>
<key>shadow</key>
@@ -189776,13 +190307,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189794,11 +190325,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -189840,11 +190371,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0208795</string>
+ <real>0.020879499999999999</real>
<key>r</key>
- <string>0.86621</string>
+ <real>0.86621000000000004</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -189867,13 +190398,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189885,11 +190416,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -189931,11 +190462,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -189958,13 +190489,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -189976,11 +190507,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190022,11 +190553,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190049,13 +190580,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190067,11 +190598,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190113,11 +190644,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0208795</string>
+ <real>0.020879499999999999</real>
<key>r</key>
- <string>0.86621</string>
+ <real>0.86621000000000004</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190140,13 +190671,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190158,11 +190689,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190204,11 +190735,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190231,13 +190762,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190249,11 +190780,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190295,11 +190826,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190322,13 +190853,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190340,11 +190871,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190386,11 +190917,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0208795</string>
+ <real>0.020879499999999999</real>
<key>r</key>
- <string>0.86621</string>
+ <real>0.86621000000000004</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190413,13 +190944,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190431,11 +190962,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190477,11 +191008,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190504,13 +191035,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190522,11 +191053,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190568,11 +191099,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190595,13 +191126,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190613,11 +191144,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190659,11 +191190,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0208795</string>
+ <real>0.020879499999999999</real>
<key>r</key>
- <string>0.86621</string>
+ <real>0.86621000000000004</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190686,13 +191217,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190704,11 +191235,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190750,11 +191281,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190777,13 +191308,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190795,11 +191326,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190841,11 +191372,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190868,13 +191399,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190886,11 +191417,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -190932,11 +191463,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0208795</string>
+ <real>0.020879499999999999</real>
<key>r</key>
- <string>0.86621</string>
+ <real>0.86621000000000004</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -190959,13 +191490,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -190977,11 +191508,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191023,11 +191554,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -191050,13 +191581,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191068,11 +191599,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191114,11 +191645,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -191141,13 +191672,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191159,11 +191690,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191205,11 +191736,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -191232,13 +191763,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191250,11 +191781,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191296,11 +191827,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -191323,13 +191854,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191341,11 +191872,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191387,11 +191918,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00868958</string>
+ <real>0.0086895800000000006</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0.0411741</string>
+ <real>0.041174099999999998</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -191414,13 +191945,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191432,11 +191963,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191478,11 +192009,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.0111024</string>
+ <real>0.0111024</real>
<key>g</key>
- <string>0.0328073</string>
+ <real>0.032807299999999998</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>3</integer>
@@ -191505,13 +192036,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191523,11 +192054,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.023095</string>
+ <real>0.023095000000000001</real>
<key>g</key>
- <string>0.0396825</string>
+ <real>0.039682500000000002</real>
<key>r</key>
- <string>0.005354</string>
+ <real>0.0053540000000000003</real>
</dict>
<key>Join</key>
<integer>0</integer>
@@ -191559,11 +192090,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.000904381</string>
+ <real>0.000904381</real>
<key>g</key>
- <string>0.935545</string>
+ <real>0.93554499999999996</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -191586,13 +192117,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191642,11 +192173,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.000904381</string>
+ <real>0.000904381</real>
<key>g</key>
- <string>0.935545</string>
+ <real>0.93554499999999996</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -191669,13 +192200,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191725,11 +192256,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.000904381</string>
+ <real>0.000904381</real>
<key>g</key>
- <string>0.935545</string>
+ <real>0.93554499999999996</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -191752,13 +192283,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191810,11 +192341,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0950316</string>
+ <real>0.095031599999999994</real>
<key>r</key>
- <string>0.0196927</string>
+ <real>0.0196927</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -191837,13 +192368,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191893,11 +192424,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0950316</string>
+ <real>0.095031599999999994</real>
<key>r</key>
- <string>0.0196927</string>
+ <real>0.0196927</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -191920,13 +192451,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -191976,11 +192507,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>1</string>
+ <real>1</real>
<key>g</key>
- <string>0.0950316</string>
+ <real>0.095031599999999994</real>
<key>r</key>
- <string>0.0196927</string>
+ <real>0.0196927</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192003,13 +192534,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192061,11 +192592,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00381666</string>
+ <real>0.0038166599999999999</real>
<key>g</key>
- <string>0.34765</string>
+ <real>0.34765000000000001</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192088,13 +192619,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192144,11 +192675,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00381666</string>
+ <real>0.0038166599999999999</real>
<key>g</key>
- <string>0.34765</string>
+ <real>0.34765000000000001</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192171,13 +192702,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192227,11 +192758,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00381666</string>
+ <real>0.0038166599999999999</real>
<key>g</key>
- <string>0.34765</string>
+ <real>0.34765000000000001</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192254,13 +192785,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192312,11 +192843,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192339,13 +192870,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192395,11 +192926,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192422,13 +192953,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192478,11 +193009,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192505,13 +193036,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192563,11 +193094,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192590,13 +193121,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192646,11 +193177,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192673,13 +193204,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192729,11 +193260,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0</string>
+ <real>0.0</real>
<key>g</key>
- <string>0</string>
+ <real>0.0</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192756,13 +193287,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192814,11 +193345,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00381666</string>
+ <real>0.0038166599999999999</real>
<key>g</key>
- <string>0.34765</string>
+ <real>0.34765000000000001</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192841,13 +193372,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192897,11 +193428,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00381666</string>
+ <real>0.0038166599999999999</real>
<key>g</key>
- <string>0.34765</string>
+ <real>0.34765000000000001</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -192924,13 +193455,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -192980,11 +193511,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.00381666</string>
+ <real>0.0038166599999999999</real>
<key>g</key>
- <string>0.34765</string>
+ <real>0.34765000000000001</real>
<key>r</key>
- <string>1</string>
+ <real>1</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -193007,13 +193538,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -193065,11 +193596,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.12746</string>
+ <real>0.12745999999999999</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0</string>
+ <real>0.0</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -193092,13 +193623,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -193148,11 +193679,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.12746</string>
+ <real>0.12745999999999999</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0</string>
+ <real>0.0</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -193175,13 +193706,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -193231,11 +193762,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.12746</string>
+ <real>0.12745999999999999</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0</string>
+ <real>0.0</real>
</dict>
<key>FillType</key>
<integer>2</integer>
@@ -193258,13 +193789,13 @@
<key>Color</key>
<dict>
<key>a</key>
- <string>0.5</string>
+ <real>0.5</real>
<key>b</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>g</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
<key>r</key>
- <string>0.333333</string>
+ <real>0.33333299999999999</real>
</dict>
<key>Draws</key>
<string>NO</string>
@@ -193316,11 +193847,11 @@
<key>Color</key>
<dict>
<key>b</key>
- <string>0.12746</string>
+ <real>0.12745999999999999</real>
<key>g</key>
- <string>1</string>
+ <real>1</real>
<key>r</key>
- <string>0</string>
+ <real>0.0</real>
</dict>
<key>FillType</key>
<TRUNCATED>
[32/50] [abbrv] tinkerpop git commit: Merge branch 'TINKERPOP-1349'
Posted by tw...@apache.org.
Merge branch 'TINKERPOP-1349'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/7f22595c
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/7f22595c
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/7f22595c
Branch: refs/heads/TINKERPOP-1254
Commit: 7f22595c46bb66caa7535f7881e3aaeac241690c
Parents: 5395aae 857e2e2
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Jun 30 07:14:14 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Jun 30 07:14:14 2016 -0600
----------------------------------------------------------------------
.../process/traversal/TraversalStrategies.java | 2 +
.../traversal/step/branch/BranchStep.java | 12 +-
.../traversal/step/util/AbstractStep.java | 5 +-
.../optimization/RepeatUnrollStrategy.java | 78 ++++++++++
.../TraversalStrategyPerformanceTest.java | 120 ++++++++++++++++
.../IdentityRemovalStrategyTest.java | 104 ++++++++++----
.../optimization/RepeatUnrollStrategyTest.java | 141 +++++++++++++++++++
.../process/traversal/step/map/ProfileTest.java | 36 ++---
8 files changed, 447 insertions(+), 51 deletions(-)
----------------------------------------------------------------------
[38/50] [abbrv] tinkerpop git commit: TINKERPOP-1355 Design
HasContainer for extension
Posted by tw...@apache.org.
TINKERPOP-1355 Design HasContainer for extension
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/ca8a4f9f
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/ca8a4f9f
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/ca8a4f9f
Branch: refs/heads/TINKERPOP-1254
Commit: ca8a4f9fb8a9bc1d69aa10870d75076b8fa906b5
Parents: c0b0eed
Author: Bryn Cooke <br...@gmail.com>
Authored: Mon Jul 4 09:29:40 2016 +0100
Committer: Bryn Cooke <br...@gmail.com>
Committed: Mon Jul 4 10:40:43 2016 +0100
----------------------------------------------------------------------
.../traversal/step/util/HasContainer.java | 56 ++++++++++++++------
1 file changed, 41 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ca8a4f9f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
index b634e37..d08f408 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -33,12 +33,12 @@ import java.util.function.Predicate;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public final class HasContainer implements Serializable, Cloneable, Predicate<Element> {
+public class HasContainer implements Serializable, Cloneable, Predicate<Element> {
private String key;
private P predicate;
- private boolean testingIdString;
+ private final boolean testingIdString;
public HasContainer(final String key, final P<?> predicate) {
this.key = key;
@@ -66,34 +66,60 @@ public final class HasContainer implements Serializable, Cloneable, Predicate<El
}
}
- public boolean test(final Element element) {
+ public final boolean test(final Element element) {
// it is OK to evaluate equality of ids via toString(), given that the test suite enforces the value of
// id().toString() to be a first class representation of the identifier. a string test is only executed
// if the predicate value is a String. this allows stuff like: g.V().has(id,lt(10)) to work properly
if (this.key.equals(T.id.getAccessor()))
- return testingIdString ? this.predicate.test(element.id().toString()) : this.predicate.test(element.id());
+ return testingIdString ? testIdAsString(element) : testId(element);
else if (this.key.equals(T.label.getAccessor()))
- return this.predicate.test(element.label());
+ return testLabel(element);
else if (element instanceof VertexProperty && this.key.equals(T.value.getAccessor()))
- return this.predicate.test(((VertexProperty) element).value());
+ return testValue((VertexProperty) element);
else if (element instanceof VertexProperty && this.key.equals(T.key.getAccessor()))
- return this.predicate.test(((VertexProperty) element).key());
+ return testKey((VertexProperty) element);
else {
if (element instanceof Vertex) {
final Iterator<? extends Property> itty = element.properties(this.key);
while (itty.hasNext()) {
- if (this.predicate.test(itty.next().value()))
+ if (testValue(itty.next()))
return true;
}
return false;
} else {
final Property property = element.property(this.key);
- return property.isPresent() && this.predicate.test(property.value());
+ return property.isPresent() && testValue(property);
}
}
}
- public String toString() {
+ protected boolean testId(Element element)
+ {
+ return this.predicate.test(element.id());
+ }
+
+ protected boolean testIdAsString(Element element)
+ {
+ return this.predicate.test(element.id().toString());
+ }
+
+ protected boolean testLabel(Element element)
+ {
+ return this.predicate.test(element.label());
+ }
+
+ protected boolean testValue(Property property)
+ {
+ return this.predicate.test(property.value());
+ }
+
+ protected boolean testKey(Property property)
+ {
+ return this.predicate.test(property.key());
+ }
+
+
+ public final String toString() {
return this.key + '.' + this.predicate;
}
@@ -112,23 +138,23 @@ public final class HasContainer implements Serializable, Cloneable, Predicate<El
return (this.key != null ? this.key.hashCode() : 0) ^ (this.predicate != null ? this.predicate.hashCode() : 0);
}
- public String getKey() {
+ public final String getKey() {
return this.key;
}
- public void setKey(final String key) {
+ public final void setKey(final String key) {
this.key = key;
}
- public P<?> getPredicate() {
+ public final P<?> getPredicate() {
return this.predicate;
}
- public BiPredicate<?, ?> getBiPredicate() {
+ public final BiPredicate<?, ?> getBiPredicate() {
return this.predicate.getBiPredicate();
}
- public Object getValue() {
+ public final Object getValue() {
return this.predicate.getValue();
}
[04/50] [abbrv] tinkerpop git commit: Merge branch 'tp31'
Posted by tw...@apache.org.
Merge branch 'tp31'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/668bee37
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/668bee37
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/668bee37
Branch: refs/heads/TINKERPOP-1254
Commit: 668bee3718fd5de462abf2d7f0ee59ffe4e11e64
Parents: 74127ca ce0dc48
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Thu Jun 16 21:47:32 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Thu Jun 16 21:47:32 2016 +0200
----------------------------------------------------------------------
bin/validate-distribution.sh | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
[19/50] [abbrv] tinkerpop git commit: Merge branch 'TINKERPOP-1071'
Posted by tw...@apache.org.
Merge branch 'TINKERPOP-1071'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/5395aaeb
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/5395aaeb
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/5395aaeb
Branch: refs/heads/TINKERPOP-1254
Commit: 5395aaeb057e4c163233aa8ace2a2975ea827fe5
Parents: 0787e46 2d69b9e
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Tue Jun 28 18:25:10 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Tue Jun 28 18:25:10 2016 +0200
----------------------------------------------------------------------
docs/preprocessor/preprocess-file.sh | 7 +++++++
1 file changed, 7 insertions(+)
----------------------------------------------------------------------
[37/50] [abbrv] tinkerpop git commit: Merge branch 'TINKERPOP-1341'
of https://github.com/dalaro/incubator-tinkerpop
Posted by tw...@apache.org.
Merge branch 'TINKERPOP-1341' of https://github.com/dalaro/incubator-tinkerpop
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/c0b0eedc
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/c0b0eedc
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/c0b0eedc
Branch: refs/heads/TINKERPOP-1254
Commit: c0b0eedced6c176d85b4c976957c3021a124abf8
Parents: 78f7f3e f19121b
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Sat Jul 2 07:31:15 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Sat Jul 2 07:31:15 2016 -0600
----------------------------------------------------------------------
.../gremlin/spark/structure/io/gryo/GryoRegistrator.java | 5 +++++
1 file changed, 5 insertions(+)
----------------------------------------------------------------------
[49/50] [abbrv] tinkerpop git commit: Fixed merge issues from
previous commit.
Posted by tw...@apache.org.
Fixed merge issues from previous commit.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/a138d554
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/a138d554
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/a138d554
Branch: refs/heads/TINKERPOP-1254
Commit: a138d5549348f2202669af86841be49f99c838ad
Parents: e5cbe53
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 11:46:04 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 11:46:04 2016 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java | 6 ++----
.../tinkerpop/gremlin/server/GremlinServerIntegrateTest.java | 1 +
2 files changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a138d554/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
index 813174c..114fa28 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/AbstractEvalOpProcessor.java
@@ -30,10 +30,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Operator;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.Scope;
-import org.apache.tinkerpop.gremlin.server.GraphManager;
-import org.apache.tinkerpop.gremlin.server.handler.Frame;
+import org.apache.tinkerpop.gremlin.server.OpProcessor;
import org.apache.tinkerpop.gremlin.server.handler.GremlinResponseFrameEncoder;
-import org.apache.tinkerpop.gremlin.server.handler.StateKey;
import org.apache.tinkerpop.gremlin.structure.Column;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.server.Context;
@@ -49,6 +47,7 @@ import org.slf4j.LoggerFactory;
import javax.script.Bindings;
import javax.script.SimpleBindings;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -58,7 +57,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import java.util.regex.Pattern;
-import java.util.stream.Stream;
import static com.codahale.metrics.MetricRegistry.name;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/a138d554/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index 37c310f..50ed066 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -78,6 +78,7 @@ import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.StringEndsWith.endsWith;
import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;
import static org.junit.Assert.assertEquals;
[15/50] [abbrv] tinkerpop git commit: updated CHANGELOG.
Posted by tw...@apache.org.
updated CHANGELOG.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/82afed3a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/82afed3a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/82afed3a
Branch: refs/heads/TINKERPOP-1254
Commit: 82afed3a482a287241ae5a016bc2e14f01785b21
Parents: 7dfd0dd
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 21 16:45:57 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 21 16:45:57 2016 -0600
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/82afed3a/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 1ba08d4..94bb67e 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.2.1 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* `TraversalExplanation.prettyPrint()` exists which provides word wrapping and GremlinConsole is smart to use console width to control `toString()`.
* `TraversalOpProcessor` (`RemoteConnection`) uses `HaltedTraverserStrategy` metadata to determine detachment procedure prior to returning results.
* Allow DFS paths in `HADOOP_GREMLIN_LIBS`.
* Added a safer serializer infrastructure for use with `SparkGraphComputer` that uses `KryoSerializer` and the new `GryoRegistrator`.
[23/50] [abbrv] tinkerpop git commit: Fixed a problem with how
timeouts were scheduled in GremlinExecutor
Posted by tw...@apache.org.
Fixed a problem with how timeouts were scheduled in GremlinExecutor
Made timeouts schedule closer to when execution of a script actually occurred. All together, this change helps prevent sessions from locking when submitting multiple parallel requests that have the potential to block.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/cd0e58bb
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/cd0e58bb
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/cd0e58bb
Branch: refs/heads/TINKERPOP-1254
Commit: cd0e58bb769faf06ddfee9473649c7b53ba1b50c
Parents: d699cb6
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Tue Jun 28 16:19:54 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Jun 28 16:19:54 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 4 +-
.../src/reference/gremlin-applications.asciidoc | 6 ++-
.../upgrade/release-3.1.x-incubating.asciidoc | 14 ++++-
.../gremlin/groovy/engine/GremlinExecutor.java | 51 +++++++++++-------
.../server/GremlinDriverIntegrateTest.java | 54 ++++++++++++++++++++
5 files changed, 106 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cd0e58bb/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a359eca..6fcd00a 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,7 +26,9 @@ image::https://raw.githubusercontent.com/apache/incubator-tinkerpop/master/docs/
TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* Avoid hamcrest conflict by using mockito-core instead of mockito-all dependency in `gremlin-test`.
+* Avoided hamcrest conflict by using mockito-core instead of mockito-all dependency in `gremlin-test`.
+* Fixed bug in `GremlinExecutor` causing Gremlin Server to lock up when parallel requests were submitted on the same session if those parallel requests included a script that blocked indefinitely.
+* Changed `GremlinExecutor` timeout scheduling so that the timer would not start until a time closer to the actual start of script evaluation.
* Fixed bug in `SubgraphStrategy` where step labels were not being propogated properly to new steps injected by the strategy.
* Defaulted to `Edge.DEFAULT` if no edge label was supplied in GraphML.
* Fixed bug in `IoGraphTest` causing IllegalArgumentException: URI is not hierarchical error for external graph implementations.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cd0e58bb/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 0cb875e..488663f 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1261,7 +1261,7 @@ Tuning
image:gremlin-handdrawn.png[width=120,float=right] Tuning Gremlin Server for a particular environment may require some simple trial-and-error, but the following represent some basic guidelines that might be useful:
* Gremlin Server defaults to a very modest maximum heap size. Consider increasing this value for non-trivial uses. Maximum heap size (`-Xmx`) is defined with the `JAVA_OPTIONS` setting in `gremlin-server.sh`.
-* When configuring the size of `threadPoolWorker` start with the default of `1` and increment by one as needed to a maximum of `2*number of cores`.
+* When configuring the size of `threadPoolWorker` start with the default of `1` and increment by one as needed to a maximum of `2*number of cores`. Note that if using sessions that will accept parallel requests on the same session, then this value should be no less than `2`.
* The "right" size of the `gremlinPool` setting is somewhat dependent on the type of scripts that will be processed
by Gremlin Server. As requests arrive to Gremlin Server they are decoded and queued to be processed by threads in
this pool. When this pool is exhausted of threads, Gremlin Server will continue to accept incoming requests, but
@@ -1407,6 +1407,10 @@ request.
A session is a "heavier" approach to the simple "request/response" approach of sessionless requests, but is sometimes
necessary for a given use case.
+IMPORTANT: If submitting requests in parallel to a single session in Gremlin Server, then the `threadPoolWorker`
+setting can be no less than `2` or else the session may be prone to becoming locked if scripts sent on that session
+tend to block for extended periods of time.
+
[[considering-transactions]]
Considering Transactions
^^^^^^^^^^^^^^^^^^^^^^^^
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cd0e58bb/docs/src/upgrade/release-3.1.x-incubating.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.1.x-incubating.asciidoc b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
index b1b99f8..d8c5de2 100644
--- a/docs/src/upgrade/release-3.1.x-incubating.asciidoc
+++ b/docs/src/upgrade/release-3.1.x-incubating.asciidoc
@@ -52,7 +52,17 @@ still possible to get a timeout on a request if the server timeout limits are re
refers to how long the console will wait for a response from the server before giving up. By default, the timeout is
set to `none`.
-See: https://issues.apache.org/jira/browse/TINKERPOP-1267[TINKERPOP-1267]
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1267[TINKERPOP-1267]
+
+Gremlin Server Workers
+^^^^^^^^^^^^^^^^^^^^^^
+
+Past configuration recommendations for the `threadPoolWorker` setting on Gremlin Server stated this value could be
+safely set to `1` at the low end. A size of `1` is still valid for most cases, however, if Gremlin Server is being used
+with sessions that accept parallel requests, then this value should be no less than `2` or else certain scripts (i.e.
+those that block for an extended period of time) may cause Gremlin Server to lock up the session.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1350[TINKERPOP-1350]
Upgrading for Providers
~~~~~~~~~~~~~~~~~~~~~~~
@@ -93,7 +103,7 @@ is an optional argument and does not represent a breaking change, but it does ma
complete. While the default authentication implementations packaged with Gremlin Server don't utilize this argument
other implementations might, so the drivers should be able to pass it as per the SASL specification.
-See: https://issues.apache.org/jira/browse/[TINKERPOP-1263]
+See: link:https://issues.apache.org/jira/browse/[TINKERPOP-1263]
TinkerPop 3.1.2
---------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cd0e58bb/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
index 63721eb..d70ff3d 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutor.java
@@ -51,6 +51,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -231,6 +232,8 @@ public class GremlinExecutor implements AutoCloseable {
return eval(script, language, boundVars, lifeCycle);
}
+ private static final AtomicInteger ugh = new AtomicInteger(0);
+
/**
* Evaluate a script and allow for the submission of alteration to the entire evaluation execution lifecycle.
*
@@ -249,10 +252,35 @@ public class GremlinExecutor implements AutoCloseable {
bindings.putAll(boundVars);
// override the timeout if the lifecycle has a value assigned
- final long seto = lifeCycle.getScriptEvaluationTimeoutOverride().orElse(scriptEvaluationTimeout);
+ final long scriptEvalTimeOut = lifeCycle.getScriptEvaluationTimeoutOverride().orElse(scriptEvaluationTimeout);
final CompletableFuture<Object> evaluationFuture = new CompletableFuture<>();
- final FutureTask<Void> f = new FutureTask<>(() -> {
+ final FutureTask<Void> evalFuture = new FutureTask<>(() -> {
+
+ if (scriptEvalTimeOut > 0) {
+ final Thread scriptEvalThread = Thread.currentThread();
+
+ logger.debug("Schedule timeout for script - {} - in thread [{}]", script, scriptEvalThread.getName());
+
+ // Schedule a timeout in the thread pool for future execution
+ final ScheduledFuture<?> sf = scheduledExecutorService.schedule(() -> {
+ logger.warn("Timing out script - {} - in thread [{}]", script, Thread.currentThread().getName());
+ if (!evaluationFuture.isDone()) scriptEvalThread.interrupt();
+ }, scriptEvalTimeOut, TimeUnit.MILLISECONDS);
+
+ // Cancel the scheduled timeout if the eval future is complete or the script evaluation failed
+ // with exception
+ evaluationFuture.handleAsync((v, t) -> {
+ if (!sf.isDone()) {
+ logger.debug("Killing scheduled timeout on script evaluation - {} - as the eval completed (possibly with exception).", script);
+ sf.cancel(true);
+ }
+
+ // no return is necessary - nothing downstream is concerned with what happens in here
+ return null;
+ }, scheduledExecutorService);
+ }
+
try {
lifeCycle.getBeforeEval().orElse(beforeEval).accept(bindings);
@@ -286,7 +314,7 @@ public class GremlinExecutor implements AutoCloseable {
if (root instanceof InterruptedException) {
lifeCycle.getAfterTimeout().orElse(afterTimeout).accept(bindings);
evaluationFuture.completeExceptionally(new TimeoutException(
- String.format("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of %s ms for request [%s]: %s", seto, script, root.getMessage())));
+ String.format("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of %s ms for request [%s]: %s", scriptEvalTimeOut, script, root.getMessage())));
} else {
lifeCycle.getAfterFailure().orElse(afterFailure).accept(bindings, root);
evaluationFuture.completeExceptionally(root);
@@ -296,22 +324,7 @@ public class GremlinExecutor implements AutoCloseable {
return null;
});
- executorService.execute(f);
-
- if (seto > 0) {
- // Schedule a timeout in the thread pool for future execution
- final ScheduledFuture<?> sf = scheduledExecutorService.schedule(() -> {
- logger.warn("Timing out script - {} - in thread [{}]", script, Thread.currentThread().getName());
- if (!f.isDone()) f.cancel(true);
- }, seto, TimeUnit.MILLISECONDS);
-
- // Cancel the scheduled timeout if the eval future is complete or the script evaluation failed
- // with exception
- evaluationFuture.handleAsync((v, t) -> {
- logger.debug("Killing scheduled timeout on script evaluation as the eval completed (possibly with exception).");
- return sf.cancel(true);
- }, scheduledExecutorService);
- }
+ executorService.execute(evalFuture);
return evaluationFuture;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cd0e58bb/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
index 8515e8a..846ed7a 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java
@@ -124,6 +124,10 @@ public class GremlinDriverIntegrateTest extends AbstractGremlinServerIntegration
deleteDirectory(new File("/tmp/neo4j"));
settings.graphs.put("graph", "conf/neo4j-empty.properties");
break;
+ case "shouldProcessSessionRequestsInOrderAfterTimeout":
+ settings.scriptEvaluationTimeout = 1000;
+ settings.threadPoolWorker = 2;
+ break;
}
return settings;
@@ -1193,4 +1197,54 @@ public class GremlinDriverIntegrateTest extends AbstractGremlinServerIntegration
cluster.close();
}
+
+ @Test
+ public void shouldProcessSessionRequestsInOrderAfterTimeout() throws Exception {
+ final Cluster cluster = Cluster.open();
+ final Client client = cluster.connect(name.getMethodName());
+
+ final ResultSet first = client.submit(
+ "Object mon1 = 'mon1';\n" +
+ "synchronized (mon1) {\n" +
+ " mon1.wait();\n" +
+ "} ");
+
+ final ResultSet second = client.submit(
+ "Object mon2 = 'mon2';\n" +
+ "synchronized (mon2) {\n" +
+ " mon2.wait();\n" +
+ "}");
+
+ final CompletableFuture<List<Result>> futureFirst = first.all();
+ final CompletableFuture<List<Result>> futureSecond = second.all();
+
+ final AtomicBoolean hit = new AtomicBoolean(false);
+ while (!futureFirst.isDone()) {
+ // futureSecond can't finish before futureFirst - racy business here?
+ assertThat(futureSecond.isDone(), is(false));
+ hit.set(true);
+ }
+
+ // should have entered the loop at least once and thus proven that futureSecond didn't return ahead of
+ // futureFirst
+ assertThat(hit.get(), is(true));
+
+ try {
+ futureFirst.get();
+ fail("Should have timed out");
+ } catch (Exception ex) {
+ final Throwable root = ExceptionUtils.getRootCause(ex);
+ assertThat(root, instanceOf(ResponseException.class));
+ assertThat(root.getMessage(), startsWith("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 1000 ms for request"));
+ }
+
+ try {
+ futureSecond.get();
+ fail("Should have timed out");
+ } catch (Exception ex) {
+ final Throwable root = ExceptionUtils.getRootCause(ex);
+ assertThat(root, instanceOf(ResponseException.class));
+ assertThat(root.getMessage(), startsWith("Script evaluation exceeded the configured 'scriptEvaluationTimeout' threshold of 1000 ms for request"));
+ }
+ }
}
[20/50] [abbrv] tinkerpop git commit: added RepeatUnrollStrategy for
when the loop amount is known at compile time. Fixed a bug in BranchStep
around child integration.
Posted by tw...@apache.org.
added RepeatUnrollStrategy for when the loop amount is known at compile time. Fixed a bug in BranchStep around child integration.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/8753366a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/8753366a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/8753366a
Branch: refs/heads/TINKERPOP-1254
Commit: 8753366a975101ba4edaa1888163abda3238f7ff
Parents: 0787e46
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 28 10:44:32 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 28 10:44:32 2016 -0600
----------------------------------------------------------------------
.../process/traversal/TraversalStrategies.java | 2 +
.../traversal/step/branch/BranchStep.java | 12 +-
.../optimization/RepeatUnrollStrategy.java | 75 +++++++++
.../IdentityRemovalStrategyTest.java | 35 ++++-
.../optimization/RepeatUnrollStrategyTest.java | 154 +++++++++++++++++++
.../process/traversal/step/map/ProfileTest.java | 36 +++--
6 files changed, 291 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/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 137abb9..b093676 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
@@ -30,6 +30,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.Matc
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.OrderLimitStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathProcessorStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ComputerVerificationStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.StandardVerificationStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
@@ -193,6 +194,7 @@ public interface TraversalStrategies extends Serializable, Cloneable {
FilterRankingStrategy.instance(),
IdentityRemovalStrategy.instance(),
MatchPredicateStrategy.instance(),
+ RepeatUnrollStrategy.instance(),
RangeByIsCountStrategy.instance(),
ProfileStrategy.instance(),
StandardVerificationStrategy.instance());
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
index 2cd954d..19df2a6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java
@@ -165,18 +165,22 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav
final List<Traversal.Admin<S, E>> clonedTraversals = clone.traversalOptions.compute(entry.getKey(), (k, v) ->
(v == null) ? new ArrayList<>(traversals.size()) : v);
for (final Traversal.Admin<S, E> traversal : traversals) {
- final Traversal.Admin<S, E> clonedTraversal = traversal.clone();
- clonedTraversals.add(clonedTraversal);
- clone.integrateChild(clonedTraversal);
+ clonedTraversals.add(traversal.clone());
}
}
}
clone.branchTraversal = this.branchTraversal.clone();
- clone.integrateChild(clone.branchTraversal);
return clone;
}
@Override
+ public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) {
+ super.setTraversal(parentTraversal);
+ this.integrateChild(this.branchTraversal);
+ this.traversalOptions.values().stream().flatMap(List::stream).forEach(this::integrateChild);
+ }
+
+ @Override
public int hashCode() {
int result = super.hashCode();
if (this.traversalOptions != null)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java
new file mode 100644
index 0000000..9047478
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.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.optimization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.LoopTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class RepeatUnrollStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements TraversalStrategy.OptimizationStrategy {
+
+ private static final RepeatUnrollStrategy INSTANCE = new RepeatUnrollStrategy();
+
+ private RepeatUnrollStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ if (!TraversalHelper.hasStepOfAssignableClass(RepeatStep.class, traversal) ||
+ TraversalHelper.onGraphComputer(traversal))
+ return;
+
+ for (int i = 0; i < traversal.getSteps().size(); i++) {
+ if (traversal.getSteps().get(i) instanceof RepeatStep) {
+ final RepeatStep<?> repeatStep = (RepeatStep) traversal.getSteps().get(i);
+ if (null == repeatStep.getEmitTraversal() && repeatStep.getUntilTraversal() instanceof LoopTraversal) {
+ final Traversal.Admin<?, ?> repeatTraversal = repeatStep.getGlobalChildren().get(0);
+ final int repeatLength = repeatTraversal.getSteps().size() - 1;
+ repeatTraversal.removeStep(repeatLength);
+ int insertIndex = i;
+ final int loops = (int) ((LoopTraversal) repeatStep.getUntilTraversal()).getMaxLoops();
+ for (int j = 0; j < loops; j++) {
+ TraversalHelper.insertTraversal(insertIndex, repeatTraversal.clone(), traversal); // removes the RepeatEndStep
+ insertIndex = insertIndex + repeatLength + 1;
+ traversal.addStep(insertIndex, new NoOpBarrierStep<>(traversal));
+ }
+ if (!repeatStep.getLabels().isEmpty()) {
+ final Step<?, ?> lastStep = (Step) traversal.getSteps().get(insertIndex);
+ repeatStep.getLabels().forEach(lastStep::addLabel);
+ }
+ traversal.removeStep(i); // remove the RepeatStep
+ }
+ }
+ }
+ }
+
+
+ public static RepeatUnrollStrategy instance() {
+ return INSTANCE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
index fd1ec2b..c71ad99 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
@@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.apache.tinkerpop.gremlin.util.TimeUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -29,6 +30,8 @@ import org.junit.runners.Parameterized;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -36,6 +39,8 @@ import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class IdentityRemovalStrategyTest {
+ private static boolean executedshouldBeFaster = false;
+
@Parameterized.Parameter(value = 0)
public Traversal original;
@@ -43,7 +48,7 @@ public class IdentityRemovalStrategyTest {
public Traversal optimized;
- void applyIdentityRemovalStrategy(final Traversal traversal) {
+ private void applyIdentityRemovalStrategy(final Traversal traversal) {
final TraversalStrategies strategies = new DefaultTraversalStrategies();
strategies.addStrategies(IdentityRemovalStrategy.instance());
traversal.asAdmin().setStrategies(strategies);
@@ -70,4 +75,30 @@ public class IdentityRemovalStrategyTest {
{__.out().identity().as("a").out().in().identity().identity().as("b").identity().out(), __.out().as("a").out().in().as("b").out()},
});
}
-}
\ No newline at end of file
+
+ @Test
+ public void shouldBeFaster() {
+ if (executedshouldBeFaster)
+ return;
+ else
+ executedshouldBeFaster = true;
+ final int startSize = 1000;
+ final int clockRuns = 1000;
+ final Integer[] starts = new Integer[startSize];
+ for (int i = 0; i < startSize; i++) {
+ starts[i] = i;
+ }
+
+ final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate();
+
+ final Runnable optimized = () -> {
+ final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity();
+ traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance()));
+ traversal.iterate();
+ };
+
+ //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized));
+ assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
+ assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
new file mode 100644
index 0000000..1c4c4b7
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.optimization;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.util.TimeUtil;
+import org.javatuples.Pair;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@RunWith(Parameterized.class)
+public class RepeatUnrollStrategyTest {
+
+ private static final Random RANDOM = new Random();
+ private static boolean shouldBeFasterWithUniqueStreamExecuted = false;
+ private static boolean shouldBeFasterWithDuplicateStreamExecuted = false;
+
+ @Parameterized.Parameter(value = 0)
+ public Traversal original;
+
+ @Parameterized.Parameter(value = 1)
+ public Traversal optimized;
+
+
+ private void applyRepeatUnrollStrategy(final Traversal traversal) {
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(RepeatUnrollStrategy.instance());
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.asAdmin().applyStrategies();
+
+ }
+
+ @Test
+ public void doTest() {
+ applyRepeatUnrollStrategy(original);
+ assertEquals(optimized, original);
+ }
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Iterable<Object[]> generateTestParameters() {
+
+ final Predicate<Traverser<Vertex>> predicate = t -> t.loops() > 5;
+ return Arrays.asList(new Traversal[][]{
+ {__.identity(), __.identity()},
+ {__.out().as("a").in().repeat(__.outE("created").bothV()).times(2).in(), __.out().as("a").in().outE("created").bothV().barrier().outE("created").bothV().barrier().in()},
+ {__.out().repeat(__.outE("created").bothV()).times(1).in(), __.out().outE("created").bothV().barrier().in()},
+ {__.repeat(__.outE("created").bothV()).times(1).in(), __.outE("created").bothV().barrier().in()},
+ {__.repeat(__.out()).times(2).as("x").repeat(__.in().as("b")).times(3), __.out().barrier().out().barrier().as("x").in().as("b").barrier().in().as("b").barrier().in().as("b").barrier()},
+ {__.repeat(__.outE("created").inV()).times(2), __.outE("created").inV().barrier().outE("created").inV().barrier()},
+ {__.repeat(__.out()).times(3), __.out().barrier().out().barrier().out().barrier()},
+ {__.repeat(__.local(__.select("a").out("knows"))).times(2), __.local(__.select("a").out("knows")).barrier().local(__.select("a").out("knows")).barrier()},
+ {__.<Vertex>times(2).repeat(__.out()), __.out().barrier().out().barrier()},
+ {__.<Vertex>out().times(2).repeat(__.out().as("a")).as("x"), __.out().out().as("a").barrier().out().as("a").barrier().as("x")},
+ {__.repeat(__.out()).emit().times(2), __.repeat(__.out()).emit().times(2)},
+ {__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)},
+ {__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()},
+ {__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()},
+ });
+ }
+
+ @Test
+ public void shouldBeFasterWithUniqueStream() {
+ if (shouldBeFasterWithUniqueStreamExecuted)
+ return;
+ shouldBeFasterWithUniqueStreamExecuted = true;
+ final int startSize = 1000;
+ final int clockRuns = 1000;
+ final Integer[] starts = new Integer[startSize];
+ for (int i = 0; i < startSize; i++) {
+ starts[i] = i; // 1000 unique objects
+ }
+ assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size());
+ clockTraversals(starts, clockRuns);
+ }
+
+ @Test
+ public void shouldBeFasterWithDuplicateStream() {
+ if (shouldBeFasterWithDuplicateStreamExecuted)
+ return;
+ shouldBeFasterWithDuplicateStreamExecuted = true;
+ final int startSize = 1000;
+ final int clockRuns = 1000;
+ final int uniques = 100;
+ final Integer[] starts = new Integer[startSize];
+ for (int i = 0; i < startSize; i++) {
+ starts[i] = i % uniques; // 100 unique objects
+ }
+ assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size());
+ clockTraversals(starts, clockRuns);
+ }
+
+ private void clockTraversals(final Integer[] starts, final int clockRuns) {
+ final int times = RANDOM.nextInt(4) + 2;
+ assertTrue(times > 1 && times < 6);
+ final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next();
+
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(RepeatUnrollStrategy.instance());
+ final Supplier<Long> optimized = () -> {
+ final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum();
+ traversal.asAdmin().setStrategies(strategies);
+ return traversal.next();
+ };
+
+ final Pair<Double, Long> originalResult;
+ final Pair<Double, Long> optimizedResult;
+ if (RANDOM.nextBoolean()) {
+ originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
+ } else {
+ optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
+ originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ }
+
+ // System.out.println(originalResult + "---" + optimizedResult);
+ assertEquals(originalResult.getValue1(), optimizedResult.getValue1());
+ assertTrue(originalResult.getValue0() > optimizedResult.getValue0());
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java
index 4d0ce49..548e7ab 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java
@@ -33,6 +33,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.Profiling;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.ProfileStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ComputerVerificationStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics;
import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics;
@@ -231,7 +233,9 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest {
printTraversalForm(traversal);
final TraversalMetrics traversalMetrics = traversal.next();
- validate_g_V_repeat_both_modern_profile(traversalMetrics);
+ validate_g_V_repeat_both_modern_profile(traversalMetrics,
+ traversal.asAdmin().getStrategies().toList().contains(RepeatUnrollStrategy.instance()) &&
+ !traversal.asAdmin().getStrategies().toList().contains(ComputerVerificationStrategy.instance()));
}
@Test
@@ -241,10 +245,12 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest {
printTraversalForm(traversal);
traversal.iterate();
final TraversalMetrics traversalMetrics = traversal.asAdmin().getSideEffects().<TraversalMetrics>get(METRICS_KEY);
- validate_g_V_repeat_both_modern_profile(traversalMetrics);
+ validate_g_V_repeat_both_modern_profile(traversalMetrics,
+ traversal.asAdmin().getStrategies().toList().contains(RepeatUnrollStrategy.instance()) &&
+ !traversal.asAdmin().getStrategies().toList().contains(ComputerVerificationStrategy.instance()));
}
- private void validate_g_V_repeat_both_modern_profile(TraversalMetrics traversalMetrics) {
+ private void validate_g_V_repeat_both_modern_profile(TraversalMetrics traversalMetrics, boolean withRepeatUnrollStrategy) {
traversalMetrics.toString(); // ensure no exceptions are thrown
Metrics metrics = traversalMetrics.getMetrics(0);
@@ -252,25 +258,21 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest {
assertEquals(6, metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue());
metrics = traversalMetrics.getMetrics(1);
- assertEquals(72, metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue());
+ assertEquals(withRepeatUnrollStrategy ? 12 : 72, metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue());
assertNotEquals(0, metrics.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
- assertTrue("Count should be greater than traversers.", metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > metrics.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
+ if (!withRepeatUnrollStrategy)
+ assertTrue("Count should be greater than traversers.", metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > metrics.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
assertTrue("Percent duration should be positive.", (Double) metrics.getAnnotation(TraversalMetrics.PERCENT_DURATION_KEY) >= 0);
assertTrue("Times should be positive.", metrics.getDuration(TimeUnit.MICROSECONDS) >= 0);
// Test the nested global metrics of the repeat step
- final Metrics vertexStepNestedInRepeat = (Metrics) metrics.getNested().toArray()[0];
- assertEquals(114, vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue());
- assertNotEquals(0, vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
- assertTrue("Count should be greater than traversers.", vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
- assertTrue("Times should be positive.", vertexStepNestedInRepeat.getDuration(TimeUnit.MICROSECONDS) >= 0);
-
- /*final Metrics repeatEndStepNestedInRepeat = (Metrics) metrics.getNested().toArray()[1];
- assertEquals(72, repeatEndStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue());
- assertNotEquals(0, repeatEndStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
- assertTrue("Count should be greater than traversers.", repeatEndStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > repeatEndStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
- assertTrue("Times should be positive.", repeatEndStepNestedInRepeat.getDuration(TimeUnit.MICROSECONDS) >= 0);*/
-
+ if (!withRepeatUnrollStrategy) {
+ final Metrics vertexStepNestedInRepeat = (Metrics) metrics.getNested().toArray()[0];
+ assertEquals(114, vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue());
+ assertNotEquals(0, vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
+ assertTrue("Count should be greater than traversers.", vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue());
+ assertTrue("Times should be positive.", vertexStepNestedInRepeat.getDuration(TimeUnit.MICROSECONDS) >= 0);
+ }
double totalPercentDuration = 0;
for (Metrics m : traversalMetrics.getMetrics()) {
[34/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/TINKERPOP-1063' into tp31
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/TINKERPOP-1063' into tp31
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/1c9bd087
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/1c9bd087
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/1c9bd087
Branch: refs/heads/TINKERPOP-1254
Commit: 1c9bd087d54a1f7a6506edacd34e07d713d15a04
Parents: d699cb6 1e0c581
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 30 11:22:46 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 30 11:22:46 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../step/sideEffect/TinkerGraphStep.java | 15 ++++---
.../tinkergraph/structure/TinkerGraph.java | 47 +++++++++++---------
3 files changed, 35 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
[44/50] [abbrv] tinkerpop git commit: This closes #346
Posted by tw...@apache.org.
This closes #346
Merged this PR to tp31 and master branches - ignored the merge commit from master on the PR.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/96cf3f26
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/96cf3f26
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/96cf3f26
Branch: refs/heads/TINKERPOP-1254
Commit: 96cf3f262145541a89650c2a5f4bf8a38f99e5c6
Parents: 4e0b5b1
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 10:33:25 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:33:25 2016 -0400
----------------------------------------------------------------------
----------------------------------------------------------------------
[18/50] [abbrv] tinkerpop git commit: minor correction;
code was using a test file instead of the actual output file
Posted by tw...@apache.org.
minor correction; code was using a test file instead of the actual output file
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/2d69b9e7
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/2d69b9e7
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/2d69b9e7
Branch: refs/heads/TINKERPOP-1254
Commit: 2d69b9e71b11bcdbd3220809304fc8017d5ab9de
Parents: 98f09ba
Author: Daniel Kuppitz <da...@hotmail.com>
Authored: Tue Jun 28 17:22:31 2016 +0200
Committer: Daniel Kuppitz <da...@hotmail.com>
Committed: Tue Jun 28 17:22:31 2016 +0200
----------------------------------------------------------------------
docs/preprocessor/preprocess-file.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2d69b9e7/docs/preprocessor/preprocess-file.sh
----------------------------------------------------------------------
diff --git a/docs/preprocessor/preprocess-file.sh b/docs/preprocessor/preprocess-file.sh
index 57a8b98..242cfe5 100755
--- a/docs/preprocessor/preprocess-file.sh
+++ b/docs/preprocessor/preprocess-file.sh
@@ -72,7 +72,7 @@ trap cleanup INT
function cleanup {
if [ -f "${output}" ]; then
- if [ `wc -l /tmp/foo | awk '{print $1}'` -gt 0 ]; then
+ if [ `wc -l "${output}" | awk '{print $1}'` -gt 0 ]; then
echo -e "\n\e[1mLast 10 lines of ${output}:\e[0m\n"
tail -n10 ${output}
echo
[08/50] [abbrv] tinkerpop git commit: removed NOTE: Neo4jGraph
currently does not support HA and added an image for the HA section. CTR.
Posted by tw...@apache.org.
removed NOTE: Neo4jGraph currently does not support HA and added an image for the HA section. CTR.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/da26cf18
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/da26cf18
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/da26cf18
Branch: refs/heads/TINKERPOP-1254
Commit: da26cf1862b7827223205c5410731c96d3cca70a
Parents: b2cf6d8
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Jun 17 07:33:37 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri Jun 17 07:33:37 2016 -0600
----------------------------------------------------------------------
.../reference/implementations-neo4j.asciidoc | 5 +-
docs/static/images/neo4j-ha.png | Bin 0 -> 108249 bytes
docs/static/images/tinkerpop3.graffle | 23433 ++++++++---------
3 files changed, 11624 insertions(+), 11814 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/da26cf18/docs/src/reference/implementations-neo4j.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/implementations-neo4j.asciidoc b/docs/src/reference/implementations-neo4j.asciidoc
index 998eb74..d1fc30b 100644
--- a/docs/src/reference/implementations-neo4j.asciidoc
+++ b/docs/src/reference/implementations-neo4j.asciidoc
@@ -54,9 +54,6 @@ gremlin> graph = Neo4jGraph.open('/tmp/neo4j')
==>neo4jgraph[EmbeddedGraphDatabase [/tmp/neo4j]]
----
-NOTE: Neo4j link:http://docs.neo4j.org/chunked/stable/ha.html[High Availability] is currently not supported by
-Neo4j-Gremlin.
-
TIP: To host Neo4j in <<gremlin-server,Gremlin Server>>, the dependencies must first be "installed" or otherwise
copied to the Gremlin Server path. The automated method for doing this would be to execute
`bin/gremlin-server.sh -i org.apache.tinkerpop neo4j-gremlin x.y.z`.
@@ -263,7 +260,7 @@ gremlin.neo4j.conf.relationship_auto_indexing=true
High Availability Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-TinkerPop supports running Neo4j with its fault tolerant master-slave replication configuration, referred to as its
+image:neo4j-ha.png[width=400,float=right] TinkerPop supports running Neo4j with its fault tolerant master-slave replication configuration, referred to as its
link:http://neo4j.com/docs/operations-manual/current/#_neo4j_cluster_install[High Availability (HA) cluster]. From the
TinkerPop perspective, configuring for HA is not that different than configuring for embedded mode as shown above. The
main difference is the usage of HA configuration options that enable the cluster. Once connected to a cluster, usage
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/da26cf18/docs/static/images/neo4j-ha.png
----------------------------------------------------------------------
diff --git a/docs/static/images/neo4j-ha.png b/docs/static/images/neo4j-ha.png
new file mode 100644
index 0000000..b21393c
Binary files /dev/null and b/docs/static/images/neo4j-ha.png differ
[26/50] [abbrv] tinkerpop git commit: shouldBeFaster() in both
RepeatUnrollStrategyTest and IdentityRemovalStrategyTest now do parameter
sweeps and test a broader range of behaviors.
Posted by tw...@apache.org.
shouldBeFaster() in both RepeatUnrollStrategyTest and IdentityRemovalStrategyTest now do parameter sweeps and test a broader range of behaviors.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e6071c0e
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e6071c0e
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e6071c0e
Branch: refs/heads/TINKERPOP-1254
Commit: e6071c0e445061c003cd8a68803a635ff2610fad
Parents: 857deab
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 28 15:23:53 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 28 15:23:53 2016 -0600
----------------------------------------------------------------------
.../IdentityRemovalStrategyTest.java | 50 +++++++++---
.../optimization/RepeatUnrollStrategyTest.java | 81 ++++++++------------
2 files changed, 72 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e6071c0e/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
index 3a84813..c5099f9 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java
@@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies;
import org.apache.tinkerpop.gremlin.util.TimeUtil;
@@ -29,6 +30,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
+import java.util.Random;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -81,27 +83,51 @@ public class IdentityRemovalStrategyTest {
}
public static class NonParameterizedTests {
+
+ private static final Random RANDOM = new Random();
+
@Test
public void shouldBeFaster() {
final int startSize = 1000;
- final int clockRuns = 1000;
+ final int clockRuns = 2000;
+ final int maxIdentities = 10;
+ final int minIdentities = 3;
final Integer[] starts = new Integer[startSize];
for (int i = 0; i < startSize; i++) {
starts[i] = i;
}
- final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate();
-
- final Runnable optimized = () -> {
- final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity();
- traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance()));
- traversal.iterate();
- };
-
- //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized));
- assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
- assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
+ for (int i = minIdentities; i < maxIdentities; i++) {
+ final int numberOfIdentities = i;
+ final Runnable original = () -> {
+ final GraphTraversal<Integer, Integer> traversal = __.inject(starts);
+ for (int j = 0; j < numberOfIdentities; j++) {
+ traversal.identity();
+ }
+ traversal.iterate();
+ };
+
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(IdentityRemovalStrategy.instance());
+ final Runnable optimized = () -> {
+ final GraphTraversal<Integer, Integer> traversal = __.inject(starts);
+ for (int j = 0; j < numberOfIdentities; j++) {
+ traversal.identity();
+ }
+ traversal.asAdmin().setStrategies(strategies);
+ traversal.iterate();
+ };
+
+ //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns, optimized));
+ if (RANDOM.nextBoolean()) {
+ assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
+ assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
+ } else {
+ assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original));
+ assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized));
+ }
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e6071c0e/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
index 3d47a10..91ab2ae 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java
@@ -101,56 +101,43 @@ public class RepeatUnrollStrategyTest {
public static class NonParameterizedTests {
@Test
- public void shouldBeFasterWithUniqueStream() {
+ public void shouldBeFaster() {
final int startSize = 1000;
final int clockRuns = 1000;
- final Integer[] starts = new Integer[startSize];
- for (int i = 0; i < startSize; i++) {
- starts[i] = i; // 1000 unique objects
+ for (int i = 100; i <= startSize; i = i + 200) {
+ final Integer[] starts = new Integer[startSize];
+ for (int j = 0; j < startSize; j++) {
+ starts[j] = j % i;
+ }
+ assertEquals(i, new HashSet<>(Arrays.asList(starts)).size());
+ ///
+ for (int j = 2; j < 6; j++) {
+ final int times = j;
+ final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next();
+
+ final TraversalStrategies strategies = new DefaultTraversalStrategies();
+ strategies.addStrategies(RepeatUnrollStrategy.instance());
+ final Supplier<Long> optimized = () -> {
+ final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum();
+ traversal.asAdmin().setStrategies(strategies);
+ return traversal.next();
+ };
+
+ final Pair<Double, Long> originalResult;
+ final Pair<Double, Long> optimizedResult;
+ if (RANDOM.nextBoolean()) {
+ originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
+ } else {
+ optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
+ originalResult = TimeUtil.clockWithResult(clockRuns, original);
+ }
+
+ // System.out.println(originalResult + "---" + optimizedResult);
+ assertEquals(originalResult.getValue1(), optimizedResult.getValue1());
+ assertTrue(originalResult.getValue0() > optimizedResult.getValue0());
+ }
}
- assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size());
- clockTraversals(starts, clockRuns);
- }
-
- @Test
- public void shouldBeFasterWithDuplicateStream() {
- final int startSize = 1000;
- final int clockRuns = 1000;
- final int uniques = 100;
- final Integer[] starts = new Integer[startSize];
- for (int i = 0; i < startSize; i++) {
- starts[i] = i % uniques; // 100 unique objects
- }
- assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size());
- clockTraversals(starts, clockRuns);
- }
-
- private void clockTraversals(final Integer[] starts, final int clockRuns) {
- final int times = RANDOM.nextInt(4) + 2;
- assertTrue(times > 1 && times < 6);
- final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next();
-
- final TraversalStrategies strategies = new DefaultTraversalStrategies();
- strategies.addStrategies(RepeatUnrollStrategy.instance());
- final Supplier<Long> optimized = () -> {
- final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum();
- traversal.asAdmin().setStrategies(strategies);
- return traversal.next();
- };
-
- final Pair<Double, Long> originalResult;
- final Pair<Double, Long> optimizedResult;
- if (RANDOM.nextBoolean()) {
- originalResult = TimeUtil.clockWithResult(clockRuns, original);
- optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
- } else {
- optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized);
- originalResult = TimeUtil.clockWithResult(clockRuns, original);
- }
-
- // System.out.println(originalResult + "---" + optimizedResult);
- assertEquals(originalResult.getValue1(), optimizedResult.getValue1());
- assertTrue(originalResult.getValue0() > optimizedResult.getValue0());
}
}
}
[02/50] [abbrv] tinkerpop git commit: Updated changelog.
Posted by tw...@apache.org.
Updated changelog.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/099e6bc6
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/099e6bc6
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/099e6bc6
Branch: refs/heads/TINKERPOP-1254
Commit: 099e6bc62468516974a3e76531d00444dbe89edc
Parents: e59b93c
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 16 15:32:58 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 16 15:32:58 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/099e6bc6/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a359eca..2ae2e77 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -30,6 +30,7 @@ TinkerPop 3.1.3 (NOT OFFICIALLY RELEASED YET)
* Fixed bug in `SubgraphStrategy` where step labels were not being propogated properly to new steps injected by the strategy.
* Defaulted to `Edge.DEFAULT` if no edge label was supplied in GraphML.
* Fixed bug in `IoGraphTest` causing IllegalArgumentException: URI is not hierarchical error for external graph implementations.
+* Improved `TinkerGraph` performance when iterating vertices and edges.
* Fixed a bug where timeout functions provided to the `GremlinExecutor` were not executing in the same thread as the script evaluation.
* Optimized a few special cases in `RangeByIsCountStrategy`.
* Named the thread pool used by Gremlin Server sessions: "gremlin-server-session-$n".
[46/50] [abbrv] tinkerpop git commit: Merge remote-tracking branch
'origin/tp31'
Posted by tw...@apache.org.
Merge remote-tracking branch 'origin/tp31'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/88f3da55
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/88f3da55
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/88f3da55
Branch: refs/heads/TINKERPOP-1254
Commit: 88f3da553681a2cecceba055f0d6bf21ba17e13e
Parents: 96cf3f2 17aab3e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jul 6 10:38:58 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:38:58 2016 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 2 +
.../src/reference/gremlin-applications.asciidoc | 6 ++-
.../upgrade/release-3.1.x-incubating.asciidoc | 14 ++++-
.../gremlin/groovy/engine/GremlinExecutor.java | 51 +++++++++++-------
.../server/GremlinDriverIntegrateTest.java | 54 ++++++++++++++++++++
5 files changed, 105 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88f3da55/CHANGELOG.asciidoc
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/88f3da55/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
[13/50] [abbrv] tinkerpop git commit: made things safer -- not longer
wraps by step name, but by character. much cleaner.
Posted by tw...@apache.org.
made things safer -- not longer wraps by step name, but by character. much cleaner.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/090efe3b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/090efe3b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/090efe3b
Branch: refs/heads/TINKERPOP-1254
Commit: 090efe3be4b40e90dba4731d8233b5dd62c08204
Parents: 21a533d
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Tue Jun 21 16:44:19 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Tue Jun 21 16:44:19 2016 -0600
----------------------------------------------------------------------
.../tinkerpop/gremlin/console/Console.groovy | 6 ++---
.../traversal/util/TraversalExplanation.java | 23 +++++++++-----------
.../util/TraversalExplanationTest.java | 16 +++++++++-----
3 files changed, 23 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/090efe3b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
----------------------------------------------------------------------
diff --git a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
index 3d748eb..8dcb272 100644
--- a/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
+++ b/gremlin-console/src/main/groovy/org/apache/tinkerpop/gremlin/console/Console.groovy
@@ -19,6 +19,7 @@
package org.apache.tinkerpop.gremlin.console
import jline.TerminalFactory
+import jline.console.history.FileHistory
import org.apache.commons.cli.Option
import org.apache.tinkerpop.gremlin.console.commands.GremlinSetCommand
import org.apache.tinkerpop.gremlin.console.commands.InstallCommand
@@ -29,7 +30,6 @@ import org.apache.tinkerpop.gremlin.console.commands.UninstallCommand
import org.apache.tinkerpop.gremlin.console.plugin.PluggedIn
import org.apache.tinkerpop.gremlin.groovy.loaders.GremlinLoader
import org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
-import jline.console.history.FileHistory
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation
import org.apache.tinkerpop.gremlin.util.Gremlin
import org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator
@@ -252,8 +252,8 @@ class Console {
return null
}
} else if (result instanceof TraversalExplanation) {
- final int width = TerminalFactory.get().getWidth() - 25
- io.out.println(buildResultPrompt() + result.prettyPrint(width < 10 ? 100 : width))
+ final int width = TerminalFactory.get().getWidth();
+ io.out.println(buildResultPrompt() + result.prettyPrint(width < 20 ? 80 : width))
return null
} else {
io.out.println(buildResultPrompt() + ((null == result) ? NULL : result.toString()))
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/090efe3b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
index 2baccdb..6e3692a 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanation.java
@@ -156,26 +156,23 @@ public class TraversalExplanation implements Serializable {
StringBuilder builder = new StringBuilder();
int counter = 0;
- for (final String shortString : longString.split(", ")) {
- if (0 == counter)
- builder.append(shortString).append(", ");
- else if (counter < maxLengthPerLine)
- builder.append(shortString).append(", ");
- else {
- builder.deleteCharAt(builder.length() - 1); // remove the " "
+ for (int i = 0; i < longString.length(); i++) {
+ if (0 == counter) {
+ builder.append(longString.charAt(i));
+ } else if (counter < maxLengthPerLine) {
+ builder.append(longString.charAt(i));
+ } else {
builder.append("\n");
- for (int i = 0; i < newLineIndent; i++) {
+ for (int j = 0; j < newLineIndent; j++) {
builder.append(" ");
}
- builder.append(shortString).append(", ");
+ builder.append(longString.charAt(i));
counter = 0;
}
- counter = counter + shortString.length();
+ counter++;
}
- return builder
- .delete(builder.length() - 2, builder.length()) // remove the final ", "
- .toString();
+ return builder.toString();
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/090efe3b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanationTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanationTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanationTest.java
index 3350a87..3040fe8 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanationTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalExplanationTest.java
@@ -55,7 +55,7 @@ public class TraversalExplanationTest {
///
traversal = __.V().out().out().out().out();
toString = traversal.explain().prettyPrint();
- assertTrue(toString.contains("VertexStep(OUT,vertex),\n"));
+ assertTrue(toString.contains("VertexStep(OUT,vertex),"));
//System.out.println(toString);
///
for (int i = 0; i < 30; i++) {
@@ -68,15 +68,20 @@ public class TraversalExplanationTest {
if (i < 3)
assertFalse(toString.contains("VertexStep(OUT,vertex),\n"));
else {
- assertFalse(Stream.of(toString.split("\n"))
+ assertTrue(Stream.of(toString.split("\n"))
.filter(s -> s.startsWith(" "))
.map(String::trim)
.filter(s -> Character.isLowerCase(s.charAt(0)))
.findAny()
.isPresent()); // all indented word wraps should start with steps
- assertTrue(toString.contains("VertexStep(OUT,vertex),\n"));
+ assertTrue(toString.contains("vertex"));
}
- //System.out.println(toString);
+ for (int j = 80; j < 200; j++) {
+ for (final String line : traversal.explain().prettyPrint(j).split("\n")) {
+ assertTrue(line.length() <= j);
+ }
+ }
+ // System.out.println(toString);
}
}
@@ -118,8 +123,7 @@ public class TraversalExplanationTest {
assertEquals(4, found);
//
found = 0;
- for (final String line : traversal.explain().prettyPrint().split("]\n")) { // need to split cause of word wrap
- //System.out.println(line + "\n\n");
+ for (final String line : traversal.explain().prettyPrint(158).split("]\n")) { // need to split cause of word wrap
if (line.contains("IncidentToAdjacentStrategy") && line.contains("[VertexStep(IN,vertex)"))
found++;
if (line.contains("IncidentToAdjacentStrategy") && line.contains("[VertexStep(OUT,vertex)"))
[39/50] [abbrv] tinkerpop git commit: ResultSet.hasNext should be
idempotent
Posted by tw...@apache.org.
ResultSet.hasNext should be idempotent
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/e25c1d5a
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/e25c1d5a
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/e25c1d5a
Branch: refs/heads/TINKERPOP-1254
Commit: e25c1d5a07a3adfe139e54e406ec75acd8e249ca
Parents: 1c9bd08
Author: Robert Dale <Ro...@sensus.com>
Authored: Fri Jun 24 16:13:33 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jul 6 10:03:42 2016 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/driver/ResultSet.java | 4 +++-
.../tinkerpop/gremlin/driver/ResultSetTest.java | 19 +++++++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e25c1d5a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
index d4e233b..78a4892 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ResultSet.java
@@ -127,7 +127,9 @@ public final class ResultSet implements Iterable<Result> {
@Override
public boolean hasNext() {
- nextOne = one();
+ if (null == nextOne) {
+ nextOne = one();
+ }
return nextOne != null;
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/e25c1d5a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
----------------------------------------------------------------------
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
index 392566a..ea3729f 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ResultSetTest.java
@@ -174,4 +174,23 @@ public class ResultSetTest extends AbstractResultQueueTest {
assertEquals(100, counter.get());
}
+
+ @Test
+ public void shouldCallHasNextWithoutSideEffect() throws Exception {
+ final Iterator itty = resultSet.iterator();
+ final AtomicInteger counter = new AtomicInteger(0);
+
+ addToQueue(100, 1, true, true);
+
+ for (int i = 0; i < 101; i++) {
+ assertThat(itty.hasNext(), is(true));
+ }
+
+ while (itty.hasNext()) {
+ itty.next();
+ counter.incrementAndGet();
+ }
+
+ assertEquals(100, counter.get());
+ }
}
[16/50] [abbrv] tinkerpop git commit: Force startedIterating before
sleep
Posted by tw...@apache.org.
Force startedIterating before sleep
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/0787e460
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/0787e460
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/0787e460
Branch: refs/heads/TINKERPOP-1254
Commit: 0787e46097cc09bb278ac1c787c4a50ece81cdb0
Parents: 82afed3
Author: Bryn Cooke <br...@gmail.com>
Authored: Mon Jun 27 22:14:37 2016 +0100
Committer: Bryn Cooke <br...@gmail.com>
Committed: Mon Jun 27 23:18:17 2016 +0100
----------------------------------------------------------------------
.../gremlin/process/traversal/TraversalInterruptionTest.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/0787e460/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
index c508df2..b0da10e 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
@@ -76,10 +76,9 @@ public class TraversalInterruptionTest extends AbstractGremlinProcessTest {
final CountDownLatch startedIterating = new CountDownLatch(1);
final Thread t = new Thread(() -> {
try {
- final AtomicBoolean first = new AtomicBoolean(true);
final Traversal traversal = traversalAfterPause.apply(traversalBeforePause.apply(g).sideEffect(traverser -> {
// let the first iteration flow through
- if (!first.compareAndSet(true, false)) {
+ if (startedIterating.getCount() == 0) {
// ensure that the whole traversal doesn't iterate out before we get a chance to interrupt
// the next iteration should stop so we can force the interrupt to be handled by VertexStep
try {