You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/08/25 15:06:11 UTC
[14/17] incubator-tinkerpop git commit: Revert "Revert "Merge
remote-tracking branch 'origin' into tp30""
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
index 773a48b..26e7264 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/RangeLocalStep.java
@@ -68,13 +68,15 @@ public final class RangeLocalStep<S> extends MapStep<S, S> {
static <S> S applyRange(final S start, final long low, final long high) {
if (start instanceof Map) {
return (S) applyRangeMap((Map) start, low, high);
- } else if (start instanceof Collection) {
- return (S) applyRangeCollection((Collection) start, low, high);
+ } else if (start instanceof Iterable) {
+ return (S) applyRangeIterable((Iterable) start, low, high);
}
return start;
}
- /** Extracts specified range of elements from a Map. */
+ /**
+ * Extracts specified range of elements from a Map.
+ */
private static Map applyRangeMap(final Map map, final long low, final long high) {
final long capacity = (high != -1 ? high : map.size()) - low;
final Map result = new LinkedHashMap((int) Math.min(capacity, map.size()));
@@ -91,8 +93,10 @@ public final class RangeLocalStep<S> extends MapStep<S, S> {
return result;
}
- /** Extracts specified range of elements from a Collection. */
- private static Object applyRangeCollection(final Collection collection, final long low, final long high) {
+ /**
+ * Extracts specified range of elements from a Collection.
+ */
+ private static Object applyRangeIterable(final Iterable<Object> iterable, final long low, final long high) {
// See if we only want a single item. It is also possible that we will allow more than one item, but that the
// incoming container is only capable of producing a single item. In that case, we will still emit a
// container. This allows the result type to be predictable based on the step arguments. It also allows us to
@@ -100,10 +104,10 @@ public final class RangeLocalStep<S> extends MapStep<S, S> {
boolean single = high != -1 ? (high - low == 1) : false;
final Collection resultCollection =
- single ? null : (collection instanceof Set) ? new LinkedHashSet() : new LinkedList();
+ single ? null : (iterable instanceof Set) ? new LinkedHashSet() : new LinkedList();
Object result = single ? null : resultCollection;
long c = 0L;
- for (final Object item : collection) {
+ for (final Object item : iterable) {
if (c >= low) {
if (c < high || high == -1) {
if (single) {
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
index 43f6d9d..ea678a5 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/TailLocalStep.java
@@ -19,10 +19,12 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
import java.util.Collection;
import java.util.Collections;
@@ -50,7 +52,9 @@ public final class TailLocalStep<S> extends MapStep<S, S> {
final long high =
start instanceof Map ? ((Map) start).size() :
start instanceof Collection ? ((Collection) start).size() :
- this.limit;
+ start instanceof Path ? ((Path) start).size() :
+ start instanceof Iterable ? IteratorUtils.count((Iterable) start) :
+ this.limit;
final long low = high - this.limit;
final S result = RangeLocalStep.applyRange(start, low, high);
return result;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GraphStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GraphStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GraphStep.java
index 1cfdbee..b0472b2 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GraphStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GraphStep.java
@@ -29,6 +29,7 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.iterator.EmptyIterator;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.function.Supplier;
@@ -46,11 +47,10 @@ public class GraphStep<S extends Element> extends StartStep<S> implements Engine
public GraphStep(final Traversal.Admin traversal, final Class<S> returnClass, final Object... ids) {
super(traversal);
this.returnClass = returnClass;
- this.ids = ids;
-
+ this.ids = (ids.length == 1 && ids[0] instanceof Collection) ? ((Collection) ids[0]).toArray(new Object[((Collection) ids[0]).size()]) : ids;
this.iteratorSupplier = () -> (Iterator<S>) (Vertex.class.isAssignableFrom(this.returnClass) ?
- this.getTraversal().getGraph().get().vertices(this.ids) :
- this.getTraversal().getGraph().get().edges(this.ids));
+ this.getTraversal().getGraph().get().vertices(this.ids) :
+ this.getTraversal().getGraph().get().edges(this.ids));
}
public String toString() {
@@ -85,6 +85,10 @@ public class GraphStep<S extends Element> extends StartStep<S> implements Engine
public void onEngine(final TraversalEngine traversalEngine) {
if (traversalEngine.isComputer()) {
this.iteratorSupplier = Collections::emptyIterator;
+ for(int i=0; i<this.ids.length; i++) { // if this is going to OLAP, convert to ids so you don't serialize elements
+ if(this.ids[i] instanceof Element)
+ this.ids[i] = ((Element)this.ids[i]).id();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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 e141e61..4d9b7d2 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
@@ -40,8 +40,8 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
protected String id = Traverser.Admin.HALT;
protected Traversal.Admin traversal;
protected ExpandableStepIterator<S> starts;
- protected Traverser<E> nextEnd = null;
- protected boolean traverserStepIdSetByChild = false;
+ protected Traverser.Admin<E> nextEnd = null;
+ protected boolean traverserStepIdAndLabelsSetByChild = false;
protected Step<?, S> previousStep = EmptyStep.instance();
protected Step<E, ?> nextStep = EmptyStep.instance();
@@ -123,7 +123,7 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
}
} else {
while (true) {
- final Traverser<E> traverser = this.processNextStart();
+ final Traverser.Admin<E> traverser = (Traverser.Admin<E>) this.processNextStart();
if (null != traverser.get() && 0 != traverser.bulk())
return this.prepareTraversalForNextStep(traverser);
}
@@ -137,7 +137,7 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
else {
try {
while (true) {
- this.nextEnd = this.processNextStart();
+ this.nextEnd = (Traverser.Admin<E>) this.processNextStart();
if (null != this.nextEnd.get() && 0 != this.nextEnd.bulk())
return true;
else
@@ -197,9 +197,11 @@ public abstract class AbstractStep<S, E> implements Step<S, E> {
return result;
}
- private final Traverser<E> prepareTraversalForNextStep(final Traverser<E> traverser) {
- if (!this.traverserStepIdSetByChild) ((Traverser.Admin<E>) traverser).setStepId(this.nextStep.getId());
- if (!this.labels.isEmpty()) this.labels.forEach(label -> traverser.path().addLabel(label));
+ private final Traverser.Admin<E> prepareTraversalForNextStep(final Traverser.Admin<E> traverser) {
+ if (!this.traverserStepIdAndLabelsSetByChild) {
+ traverser.setStepId(this.nextStep.getId());
+ traverser.addLabels(this.labels);
+ }
return traverser;
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ComputerAwareStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ComputerAwareStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ComputerAwareStep.java
index a8cc2d3..2c7ecc5 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ComputerAwareStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ComputerAwareStep.java
@@ -44,13 +44,13 @@ public abstract class ComputerAwareStep<S, E> extends AbstractStep<S, E> impleme
while (true) {
if (this.previousIterator.hasNext())
return this.previousIterator.next();
- this.previousIterator = this.traverserStepIdSetByChild ? this.computerAlgorithm() : this.standardAlgorithm();
+ this.previousIterator = this.traverserStepIdAndLabelsSetByChild ? this.computerAlgorithm() : this.standardAlgorithm();
}
}
@Override
public void onEngine(final TraversalEngine engine) {
- this.traverserStepIdSetByChild = engine.isComputer();
+ this.traverserStepIdAndLabelsSetByChild = engine.isComputer();
}
@Override
@@ -75,8 +75,10 @@ public abstract class ComputerAwareStep<S, E> extends AbstractStep<S, E> impleme
@Override
protected Traverser<S> processNextStart() throws NoSuchElementException {
final Traverser.Admin<S> start = this.starts.next();
- if (this.traverserStepIdSetByChild)
- start.setStepId(((ComputerAwareStep)this.getTraversal().getParent()).getNextStep().getId());
+ if (this.traverserStepIdAndLabelsSetByChild) {
+ start.setStepId(((ComputerAwareStep<?, ?>) this.getTraversal().getParent()).getNextStep().getId());
+ start.addLabels(((ComputerAwareStep<?, ?>) this.getTraversal().getParent()).getLabels());
+ }
return start;
}
@@ -87,7 +89,7 @@ public abstract class ComputerAwareStep<S, E> extends AbstractStep<S, E> impleme
@Override
public void onEngine(final TraversalEngine engine) {
- this.traverserStepIdSetByChild = engine.isComputer();
+ this.traverserStepIdAndLabelsSetByChild = engine.isComputer();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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 72d8c01..c40f228 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
@@ -47,6 +47,11 @@ public final class EmptyPath implements Path, Serializable {
}
@Override
+ public Path extend(final Set<String> labels) {
+ return this;
+ }
+
+ @Override
public <A> A get(final String label) {
throw Path.Exceptions.stepWithProvidedLabelDoesNotExist(label);
}
@@ -62,11 +67,6 @@ public final class EmptyPath implements Path, Serializable {
}
@Override
- public void addLabel(final String label) {
-
- }
-
- @Override
public List<Object> objects() {
return Collections.emptyList();
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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 93f7623..1a916ca 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
@@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.step.util;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
+import org.apache.tinkerpop.gremlin.structure.Element;
import java.io.Serializable;
import java.util.ArrayList;
@@ -51,10 +52,6 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
return this;
}
- private ImmutablePath(final Object currentObject, final Set<String> currentLabels) {
- this(TailPath.instance(), currentObject, currentLabels);
- }
-
private ImmutablePath(final ImmutablePathImpl previousPath, final Object currentObject, final Set<String> currentLabels) {
this.previousPath = previousPath;
this.currentObject = currentObject;
@@ -72,6 +69,14 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
}
@Override
+ public Path extend(final Set<String> labels) {
+ final Set<String> temp = new LinkedHashSet<>();
+ temp.addAll(this.currentLabels);
+ temp.addAll(labels);
+ return new ImmutablePath(this.previousPath, this.currentObject, temp);
+ }
+
+ @Override
public <A> A get(final int index) {
return (this.size() - 1) == index ? (A) this.currentObject : this.previousPath.get(index);
}
@@ -130,13 +135,8 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
}
@Override
- public void addLabel(final String label) {
- this.currentLabels.add(label);
- }
-
- @Override
public List<Object> objects() {
- final List<Object> objectPath = new ArrayList<>();
+ final List<Object> objectPath = new ArrayList<>(); // TODO: optimize
objectPath.addAll(this.previousPath.objects());
objectPath.add(this.currentObject);
return Collections.unmodifiableList(objectPath);
@@ -144,7 +144,7 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
@Override
public List<Set<String>> labels() {
- final List<Set<String>> labelPath = new ArrayList<>();
+ final List<Set<String>> labelPath = new ArrayList<>(); // TODO: optimize
labelPath.addAll(this.previousPath.labels());
labelPath.add(this.currentLabels);
return Collections.unmodifiableList(labelPath);
@@ -155,6 +155,28 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
return this.objects().toString();
}
+ @Override
+ public int hashCode() {
+ return this.objects().hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (!(other instanceof Path))
+ return false;
+ final Path otherPath = (Path) other;
+ if (otherPath.size() != this.size())
+ return false;
+ for (int i = this.size() - 1; i >= 0; i--) {
+ if (!this.get(i).equals(otherPath.get(i)))
+ return false;
+ if (!this.labels().get(i).equals(otherPath.labels().get(i)))
+ return false;
+ }
+ return true;
+ }
+
+
private static class TailPath implements Path, ImmutablePathImpl {
private static final TailPath INSTANCE = new TailPath();
@@ -169,7 +191,12 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
@Override
public Path extend(final Object object, final Set<String> labels) {
- return new ImmutablePath(object, labels);
+ return new ImmutablePath(TailPath.instance(), object, labels);
+ }
+
+ @Override
+ public Path extend(final Set<String> labels) {
+ throw new UnsupportedOperationException("A head path can not have labels added to it");
}
@Override
@@ -206,11 +233,6 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
}
@Override
- public void addLabel(final String label) {
- throw new UnsupportedOperationException("A head path can not have labels added to it");
- }
-
- @Override
public List<Object> objects() {
return Collections.emptyList();
}
@@ -225,6 +247,7 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
return true;
}
+ @SuppressWarnings("CloneDoesntCallSuperClone,CloneDoesntDeclareCloneNotSupportedException")
@Override
public TailPath clone() {
return this;
@@ -235,13 +258,18 @@ public class ImmutablePath implements Path, ImmutablePathImpl, Serializable, Clo
}
@Override
- public boolean equals(final Object object) {
- return object instanceof TailPath;
+ public String toString() {
+ return Collections.emptyList().toString();
}
@Override
- public String toString() {
- return Collections.emptyList().toString();
+ public int hashCode() {
+ return Collections.emptyList().hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ return other instanceof Path && ((Path) other).size() == 0;
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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 67f9d57..0a35f90 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
@@ -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.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -58,7 +59,9 @@ public class MutablePath implements Path, Serializable {
clone.objects = new ArrayList<>();
clone.labels = new ArrayList<>();*/
clone.objects.addAll(this.objects);
- clone.labels.addAll(this.labels);
+ for (final Set<String> labels : this.labels) {
+ clone.labels.add(new LinkedHashSet<>(labels));
+ }
return clone;
}
@@ -76,13 +79,19 @@ public class MutablePath implements Path, Serializable {
}
@Override
+ public Path extend(final Set<String> labels) {
+ this.labels.get(this.labels.size() - 1).addAll(labels);
+ return this;
+ }
+
+ @Override
public <A> A get(int index) {
return (A) this.objects.get(index);
}
@Override
public <A> A get(final Pop pop, final String label) {
- if(Pop.all == pop) {
+ if (Pop.all == pop) {
if (this.hasLabel(label)) {
final Object object = this.get(label);
if (object instanceof List)
@@ -92,7 +101,7 @@ public class MutablePath implements Path, Serializable {
} else {
return (A) Collections.emptyList();
}
- } else {
+ } else {
// Override default to avoid building temporary list, and to stop looking when we find the label.
if (Pop.last == pop) {
for (int i = this.labels.size() - 1; i >= 0; i--) {
@@ -115,11 +124,6 @@ public class MutablePath implements Path, Serializable {
}
@Override
- public void addLabel(final String label) {
- this.labels.get(this.labels.size() - 1).add(label);
- }
-
- @Override
public List<Object> objects() {
return Collections.unmodifiableList(this.objects);
}
@@ -130,7 +134,33 @@ public class MutablePath implements Path, Serializable {
}
@Override
+ public Iterator<Object> iterator() {
+ return this.objects.iterator();
+ }
+
+ @Override
public String toString() {
return this.objects.toString();
}
+
+ @Override
+ public int hashCode() {
+ return this.objects.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (!(other instanceof Path))
+ return false;
+ final Path otherPath = (Path) other;
+ if (otherPath.size() != this.size())
+ return false;
+ for (int i = this.size() - 1; i >= 0; i--) {
+ if (!this.objects.get(i).equals(otherPath.get(i)))
+ return false;
+ if (!this.labels.get(i).equals(otherPath.labels().get(i)))
+ return false;
+ }
+ return true;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/DedupBijectionStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/DedupBijectionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/DedupBijectionStrategy.java
deleted file mode 100644
index 712184d..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/DedupBijectionStrategy.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.filter.DedupGlobalStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@code DedupBijectionStrategy} does deduplication prior to a non-mutating bijective step if there is no
- * {@code by()}-modulation on {@code dedup()}. Given that {@link DedupGlobalStep} reduces the number of
- * objects in the stream, it is cheaper to dedup prior.
- * <p/>
- *
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- * @author Daniel Kuppitz (http://gremlin.guru)
- * @example <pre>
- * __.order().dedup() // is replaced by __.dedup().order()
- * </pre>
- */
-public final class DedupBijectionStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements TraversalStrategy.OptimizationStrategy {
-
- private static final DedupBijectionStrategy INSTANCE = new DedupBijectionStrategy();
- private static final Set<Class<? extends OptimizationStrategy>> PRIORS = new HashSet<>();
-
- static {
- PRIORS.add(IdentityRemovalStrategy.class);
- }
-
-
- private DedupBijectionStrategy() {
- }
-
-
- @Override
- public void apply(final Traversal.Admin<?, ?> traversal) {
- if (!TraversalHelper.hasStepOfClass(DedupGlobalStep.class, traversal))
- return;
-
- final List<Step> steps = traversal.getSteps();
- boolean exchangeable = false;
- for (int i = steps.size() - 1; i >= 0; i--) {
- final Step curr = steps.get(i);
- if (exchangeable) {
- if (curr instanceof OrderGlobalStep) {
- final Step next = curr.getNextStep();
- traversal.removeStep(next);
- traversal.addStep(i, next);
- }
- exchangeable = curr instanceof IdentityStep;
- } else {
- exchangeable = curr instanceof DedupGlobalStep && ((DedupGlobalStep) curr).getLocalChildren().isEmpty();
- }
- }
- }
-
- @Override
- public Set<Class<? extends OptimizationStrategy>> applyPrior() {
- return PRIORS;
- }
-
- public static DedupBijectionStrategy instance() {
- return INSTANCE;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategy.java
new file mode 100644
index 0000000..eaa69bc
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/FilterRankingStrategy.java
@@ -0,0 +1,176 @@
+/*
+ * 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.LambdaHolder;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.filter.*;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * FilterRankingStrategy reorders filter- and order-steps according to their rank. Labeled steps or lambda holders or
+ * steps that contain child traversals, that have labeled steps or lambda holders, will not be reordered.
+ * <p/>
+ * <table>
+ * <thead>
+ * <tr><th>Step</th><th>Rank</th></tr>
+ * </thead>
+ * <tbody>
+ * <tr><td>is(predicate)</td><td>1</td></tr>
+ * <tr><td>has(predicate)</td><td>2</td></tr>
+ * <tr><td>where(predicate)</td><td>3</td></tr>
+ * <tr><td>simplePath()</td><td>4</td></tr>
+ * <tr><td>cyclicPath()</td><td>4</td></tr>
+ * <tr><td>filter(traversal)</td><td>5</td></tr>
+ * <tr><td>where(traversal)</td><td>6</td></tr>
+ * <tr><td>or(...)</td><td>7</td></tr>
+ * <tr><td>and(...)</td><td>8</td></tr>
+ * <tr><td>dedup()</td><td>9</td></tr>
+ * <tr><td>order()</td><td>10</td></tr>
+ * </tbody>
+ * </table>
+ *
+ * @author Daniel Kuppitz (http://gremlin.guru)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ * @example <pre>
+ * __.order().dedup() // is replaced by __.dedup().order()
+ * __.dedup().filter(out()).has("value", 0) // is replaced by __.has("value", 0).filter(out()).dedup()
+ * </pre>
+ */
+public final class FilterRankingStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements TraversalStrategy.OptimizationStrategy {
+
+ private static final FilterRankingStrategy INSTANCE = new FilterRankingStrategy();
+ private static final Set<Class<? extends OptimizationStrategy>> PRIORS = new HashSet<>();
+
+ static {
+ PRIORS.add(IdentityRemovalStrategy.class);
+ }
+
+ private FilterRankingStrategy() {
+ }
+
+ @Override
+ public void apply(final Traversal.Admin<?, ?> traversal) {
+ boolean modified;
+ do {
+ modified = false;
+ final List<Step> steps = traversal.getSteps();
+ int prevRank = 0;
+ for (int i = steps.size() - 1; i >= 0; i--) {
+ final Step curr = steps.get(i);
+ final int rank = rank(curr);
+ if (prevRank > 0 && rank > prevRank) {
+ final Step next = curr.getNextStep();
+ traversal.removeStep(next);
+ traversal.addStep(i, next);
+ modified = true;
+ }
+ prevRank = rank;
+ }
+ } while (modified);
+ }
+
+ @Override
+ public Set<Class<? extends OptimizationStrategy>> applyPrior() {
+ return PRIORS;
+ }
+
+ public static FilterRankingStrategy instance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Ranks the given step. Steps with lower ranks can be moved in front of steps with higher ranks. 0 means that
+ * the step has no rank and thus is not exchangeable with its neighbors.
+ *
+ * @param step
+ * @return The rank of the given step.
+ */
+ private static int getStepRank(final Step step) {
+ if (step instanceof IsStep) {
+ return 1;
+ } else if (step instanceof HasStep) {
+ return 2;
+ } else if (step instanceof WherePredicateStep) {
+ return 3;
+ } else if (step instanceof SimplePathStep || step instanceof CyclicPathStep) {
+ return 4;
+ } else if (step instanceof TraversalFilterStep) {
+ return 5;
+ } else if (step instanceof WhereTraversalStep) {
+ return 6;
+ } else if (step instanceof OrStep) {
+ return 7;
+ } else if (step instanceof AndStep) {
+ return 8;
+ } else if (step instanceof DedupGlobalStep) {
+ return 9;
+ } else if (step instanceof OrderGlobalStep) {
+ return 10;
+ }
+ return 0;
+ }
+
+ /**
+ * If the given step has no child traversal that holds a lambda, then the actual rank determined by
+ * {@link #getStepRank(Step)} is returned, otherwise 0.
+ *
+ * @param step
+ * @return The rank of the given step.
+ */
+ private static int rank(final Step step) {
+ if (isNotOptimizableStep(step)) {
+ return 0;
+ }
+ final int rank = getStepRank(step);
+ if (rank > 0 && step instanceof TraversalParent) {
+ final TraversalParent tp = (TraversalParent) step;
+ final Iterator<Traversal.Admin<Object, Object>> childTraversalIterator = IteratorUtils.concat(
+ tp.getLocalChildren().iterator(), tp.getGlobalChildren().iterator());
+ while (childTraversalIterator.hasNext()) {
+ if (TraversalHelper.anyStepRecursively(FilterRankingStrategy::isNotOptimizableStep, childTraversalIterator.next())) {
+ return 0;
+ }
+ }
+ }
+ return rank;
+ }
+
+ /**
+ * Returns true if the step is not optimizable, otherwise false. A step is not optimizable if it (or any of its
+ * child traversals) is a lambda holder or has a label.
+ *
+ * @param step
+ * @return true if the given step is optimizable, otherwise false.
+ */
+ private static boolean isNotOptimizableStep(final Step step) {
+ return step instanceof LambdaHolder || !step.getLabels().isEmpty();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_Traverser.java
new file mode 100644
index 0000000..c282d30
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_Traverser.java
@@ -0,0 +1,99 @@
+/*
+ * 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.traverser;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+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.structure.util.Attachable;
+import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class B_LP_O_P_S_SE_SL_Traverser<T> extends B_O_S_SE_SL_Traverser<T> {
+
+ protected Path path;
+
+ protected B_LP_O_P_S_SE_SL_Traverser() {
+ }
+
+ public B_LP_O_P_S_SE_SL_Traverser(final T t, final Step<T, ?> step, final long initialBulk) {
+ super(t, step, initialBulk);
+ this.path = ImmutablePath.make().extend(t, step.getLabels());
+ }
+
+ /////////////////
+
+ @Override
+ public Path path() {
+ return this.path;
+ }
+
+ /////////////////
+
+ @Override
+ public Traverser.Admin<T> detach() {
+ super.detach();
+ this.path = ReferenceFactory.detach(this.path);
+ return this;
+ }
+
+ /////////////////
+
+ @Override
+ public <R> Traverser.Admin<R> split(final R r, final Step<T, R> step) {
+ final B_LP_O_P_S_SE_SL_Traverser<R> clone = (B_LP_O_P_S_SE_SL_Traverser<R>) super.split(r, step);
+ clone.path = clone.path.clone().extend(r, step.getLabels());
+ return clone;
+ }
+
+ @Override
+ public Traverser.Admin<T> split() {
+ final B_LP_O_P_S_SE_SL_Traverser<T> clone = (B_LP_O_P_S_SE_SL_Traverser<T>) super.split();
+ clone.path = clone.path.clone();
+ return clone;
+ }
+
+ @Override
+ public void addLabels(final Set<String> labels) {
+ if (!labels.isEmpty())
+ this.path = this.path.extend(labels);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() + this.path.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ return (object instanceof B_LP_O_P_S_SE_SL_Traverser)
+ && ((B_LP_O_P_S_SE_SL_Traverser) object).get().equals(this.t)
+ && ((B_LP_O_P_S_SE_SL_Traverser) object).getStepId().equals(this.getStepId())
+ && ((B_LP_O_P_S_SE_SL_Traverser) object).loops() == this.loops()
+ && (null == this.sack)
+ && ((B_LP_O_P_S_SE_SL_Traverser) object).path().equals(this.path);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_TraverserGenerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_TraverserGenerator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_TraverserGenerator.java
new file mode 100644
index 0000000..0ba86f5
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_P_S_SE_SL_TraverserGenerator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.traverser;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.TraverserGenerator;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class B_LP_O_P_S_SE_SL_TraverserGenerator implements TraverserGenerator {
+
+ private static final B_LP_O_P_S_SE_SL_TraverserGenerator INSTANCE = new B_LP_O_P_S_SE_SL_TraverserGenerator();
+ private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(
+ TraverserRequirement.OBJECT,
+ TraverserRequirement.BULK,
+ TraverserRequirement.SINGLE_LOOP,
+ TraverserRequirement.LABELED_PATH,
+ TraverserRequirement.PATH,
+ TraverserRequirement.SACK,
+ TraverserRequirement.SIDE_EFFECTS);
+
+ private B_LP_O_P_S_SE_SL_TraverserGenerator() {
+ }
+
+ @Override
+ public <S> Traverser.Admin<S> generate(final S start, final Step<S, ?> startStep, final long initialBulk) {
+ return new B_LP_O_P_S_SE_SL_Traverser<>(start, startStep, initialBulk);
+ }
+
+ @Override
+ public Set<TraverserRequirement> getProvidedRequirements() {
+ return REQUIREMENTS;
+ }
+
+ public static B_LP_O_P_S_SE_SL_TraverserGenerator instance() {
+ return INSTANCE;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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
new file mode 100644
index 0000000..61683c9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_Traverser.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * * 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.traverser;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+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.structure.util.Attachable;
+import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class B_LP_O_S_SE_SL_Traverser<T> extends B_O_S_SE_SL_Traverser<T> {
+
+ protected Path path;
+
+ protected B_LP_O_S_SE_SL_Traverser() {
+ }
+
+ public B_LP_O_S_SE_SL_Traverser(final T t, final Step<T, ?> step, final long initialBulk) {
+ super(t, step, initialBulk);
+ this.path = ImmutablePath.make();
+ if (!step.getLabels().isEmpty()) this.path = this.path.extend(t, step.getLabels());
+ }
+
+ /////////////////
+
+ @Override
+ public Path path() {
+ return this.path;
+ }
+
+ /////////////////
+
+ @Override
+ public Traverser.Admin<T> detach() {
+ super.detach();
+ this.path = ReferenceFactory.detach(this.path);
+ return this;
+ }
+
+ /////////////////
+
+ @Override
+ public <R> Traverser.Admin<R> split(final R r, final Step<T, R> step) {
+ final B_LP_O_S_SE_SL_Traverser<R> clone = (B_LP_O_S_SE_SL_Traverser<R>) super.split(r, step);
+ clone.path = clone.path.clone();
+ if (!step.getLabels().isEmpty()) clone.path = clone.path.extend(r, step.getLabels());
+ return clone;
+ }
+
+ @Override
+ public Traverser.Admin<T> split() {
+ final B_LP_O_S_SE_SL_Traverser<T> clone = (B_LP_O_S_SE_SL_Traverser<T>) super.split();
+ clone.path = clone.path.clone();
+ return clone;
+ }
+
+ @Override
+ public void addLabels(final Set<String> labels) {
+ if (!labels.isEmpty())
+ this.path = this.path.size() == 0 || !this.path.get(this.path.size() - 1).equals(this.t) ?
+ this.path.extend(this.t, labels) :
+ this.path.extend(labels);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() + this.path.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ return (object instanceof B_LP_O_S_SE_SL_Traverser)
+ && ((B_LP_O_S_SE_SL_Traverser) object).get().equals(this.t)
+ && ((B_LP_O_S_SE_SL_Traverser) object).getStepId().equals(this.getStepId())
+ && ((B_LP_O_S_SE_SL_Traverser) object).loops() == this.loops()
+ && (null == this.sack)
+ && ((B_LP_O_S_SE_SL_Traverser) object).path().equals(this.path);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_TraverserGenerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_TraverserGenerator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_TraverserGenerator.java
new file mode 100644
index 0000000..4789056
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_LP_O_S_SE_SL_TraverserGenerator.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * * 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.traverser;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.TraverserGenerator;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class B_LP_O_S_SE_SL_TraverserGenerator implements TraverserGenerator {
+
+ private static final B_LP_O_S_SE_SL_TraverserGenerator INSTANCE = new B_LP_O_S_SE_SL_TraverserGenerator();
+ private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(
+ TraverserRequirement.OBJECT,
+ TraverserRequirement.BULK,
+ TraverserRequirement.SINGLE_LOOP,
+ TraverserRequirement.LABELED_PATH,
+ TraverserRequirement.SACK,
+ TraverserRequirement.SIDE_EFFECTS);
+
+ private B_LP_O_S_SE_SL_TraverserGenerator() {
+ }
+
+ @Override
+ public <S> Traverser.Admin<S> generate(final S start, final Step<S, ?> startStep, final long initialBulk) {
+ return new B_LP_O_S_SE_SL_Traverser<>(start, startStep, initialBulk);
+ }
+
+ @Override
+ public Set<TraverserRequirement> getProvidedRequirements() {
+ return REQUIREMENTS;
+ }
+
+ public static B_LP_O_S_SE_SL_TraverserGenerator instance() {
+ return INSTANCE;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_Traverser.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_Traverser.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_Traverser.java
deleted file mode 100644
index 7b77843..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_Traverser.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.traverser;
-
-import org.apache.tinkerpop.gremlin.process.traversal.Path;
-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.structure.util.Attachable;
-import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory;
-import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
-
-import java.util.function.Function;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class B_O_P_S_SE_SL_Traverser<T> extends B_O_S_SE_SL_Traverser<T> {
-
- protected Path path;
-
- protected B_O_P_S_SE_SL_Traverser() {
- }
-
- public B_O_P_S_SE_SL_Traverser(final T t, final Step<T, ?> step, final long initialBulk) {
- super(t, step, initialBulk);
- this.path = ImmutablePath.make().extend(t, step.getLabels());
- }
-
- /////////////////
-
- @Override
- public Path path() {
- return this.path;
- }
-
- /////////////////
-
- @Override
- public Traverser.Admin<T> detach() {
- super.detach();
- this.path = ReferenceFactory.detach(this.path);
- return this;
- }
-
- @Override
- public T attach(final Function<Attachable<T>, T> method) {
- // you do not want to attach a path because it will reference graph objects not at the current vertex
- if (this.t instanceof Attachable && !(((Attachable) this.t).get() instanceof Path))
- this.t = ((Attachable<T>) this.t).attach(method);
- return this.t;
- }
-
- /////////////////
-
- @Override
- public void merge(final Traverser.Admin<?> other) {
- this.bulk = this.bulk + other.bulk();
- }
-
- @Override
- public <R> Traverser.Admin<R> split(final R r, final Step<T, R> step) {
- final B_O_P_S_SE_SL_Traverser<R> clone = (B_O_P_S_SE_SL_Traverser<R>) super.split(r, step);
- clone.path = clone.path.clone().extend(r, step.getLabels());
- return clone;
-
- }
-
- @Override
- public int hashCode() {
- return super.hashCode() + this.path.hashCode();
- }
-
- @Override
- public boolean equals(final Object object) {
- return (object instanceof B_O_P_S_SE_SL_Traverser)
- && ((B_O_P_S_SE_SL_Traverser) object).path().equals(this.path)
- && ((B_O_P_S_SE_SL_Traverser) object).get().equals(this.t)
- && ((B_O_P_S_SE_SL_Traverser) object).getStepId().equals(this.getStepId())
- && ((B_O_P_S_SE_SL_Traverser) object).loops() == this.loops()
- && (null == this.sack);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_TraverserGenerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_TraverserGenerator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_TraverserGenerator.java
deleted file mode 100644
index 9915740..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/B_O_P_S_SE_SL_TraverserGenerator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.traverser;
-
-import org.apache.tinkerpop.gremlin.process.traversal.Step;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.TraverserGenerator;
-
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class B_O_P_S_SE_SL_TraverserGenerator implements TraverserGenerator {
-
- private static final B_O_P_S_SE_SL_TraverserGenerator INSTANCE = new B_O_P_S_SE_SL_TraverserGenerator();
- private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(
- TraverserRequirement.OBJECT,
- TraverserRequirement.BULK,
- TraverserRequirement.SINGLE_LOOP,
- TraverserRequirement.PATH,
- TraverserRequirement.SACK,
- TraverserRequirement.SIDE_EFFECTS);
-
- private B_O_P_S_SE_SL_TraverserGenerator() {
- }
-
- @Override
- public <S> Traverser.Admin<S> generate(final S start, final Step<S, ?> startStep, final long initialBulk) {
- return new B_O_P_S_SE_SL_Traverser<>(start, startStep, initialBulk);
- }
-
- @Override
- public Set<TraverserRequirement> getProvidedRequirements() {
- return REQUIREMENTS;
- }
-
- public static B_O_P_S_SE_SL_TraverserGenerator instance() {
- return INSTANCE;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/TraverserRequirement.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/TraverserRequirement.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/TraverserRequirement.java
index 8d6c7c8..b81469b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/TraverserRequirement.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/TraverserRequirement.java
@@ -35,6 +35,7 @@ public enum TraverserRequirement {
BULK,
SINGLE_LOOP,
NESTED_LOOP,
+ LABELED_PATH,
PATH,
SACK,
SIDE_EFFECTS,
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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 3284394..1ced9ef 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
@@ -27,6 +27,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversalSideEff
import org.apache.tinkerpop.gremlin.structure.util.Attachable;
import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceFactory;
+import java.util.Set;
import java.util.function.Function;
/**
@@ -72,6 +73,11 @@ public abstract class AbstractTraverser<T> implements Traverser<T>, Traverser.Ad
}
@Override
+ public void addLabels(final Set<String> labels) {
+
+ }
+
+ @Override
public void set(final T t) {
this.t = t;
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/DefaultTraverserGeneratorFactory.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/DefaultTraverserGeneratorFactory.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/DefaultTraverserGeneratorFactory.java
index f473cbb..d94e531 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/DefaultTraverserGeneratorFactory.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/traverser/util/DefaultTraverserGeneratorFactory.java
@@ -20,8 +20,9 @@ package org.apache.tinkerpop.gremlin.process.traversal.traverser.util;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraverserGenerator;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_P_S_SE_SL_TraverserGenerator;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_S_SE_SL_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_O_S_SE_SL_TraverserGenerator;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_O_P_S_SE_SL_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_O_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.O_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserGeneratorFactory;
@@ -44,7 +45,7 @@ public class DefaultTraverserGeneratorFactory implements TraverserGeneratorFacto
}
@Override
- public TraverserGenerator getTraverserGenerator(final Traversal.Admin<?,?> traversal) {
+ public TraverserGenerator getTraverserGenerator(final Traversal.Admin<?, ?> traversal) {
final Set<TraverserRequirement> requirements = traversal.getTraverserRequirements();
if (O_TraverserGenerator.instance().getProvidedRequirements().containsAll(requirements))
@@ -56,8 +57,11 @@ public class DefaultTraverserGeneratorFactory implements TraverserGeneratorFacto
if (B_O_S_SE_SL_TraverserGenerator.instance().getProvidedRequirements().containsAll(requirements))
return B_O_S_SE_SL_TraverserGenerator.instance();
- if (B_O_P_S_SE_SL_TraverserGenerator.instance().getProvidedRequirements().containsAll(requirements))
- return B_O_P_S_SE_SL_TraverserGenerator.instance();
+ if (B_LP_O_S_SE_SL_TraverserGenerator.instance().getProvidedRequirements().containsAll(requirements))
+ return B_LP_O_S_SE_SL_TraverserGenerator.instance();
+
+ if (B_LP_O_P_S_SE_SL_TraverserGenerator.instance().getProvidedRequirements().containsAll(requirements))
+ return B_LP_O_P_S_SE_SL_TraverserGenerator.instance();
throw new IllegalStateException("The provided traverser generator factory does not support the requirements of the traversal: " + this.getClass().getCanonicalName() + requirements);
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/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 11d19bc..a099505 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
@@ -25,6 +25,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyPath;
import org.apache.tinkerpop.gremlin.structure.util.Attachable;
+import java.util.Set;
import java.util.function.Function;
/**
@@ -43,6 +44,11 @@ public final class EmptyTraverser<T> implements Traverser<T>, Traverser.Admin<T>
}
@Override
+ public void addLabels(final Set<String> labels) {
+
+ }
+
+ @Override
public void set(final T t) {
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
index eb2444c..5e025b1 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/TraversalHelper.java
@@ -38,13 +38,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -216,6 +211,22 @@ public final class TraversalHelper {
return false;
}
+ public static boolean anyStepRecursively(final Predicate<Step> predicate, final Traversal.Admin<?, ?> traversal) {
+ for (final Step<?, ?> step : traversal.getSteps()) {
+ if (predicate.test(step)) {
+ return true;
+ }
+ if (step instanceof TraversalParent) {
+ for (final Traversal.Admin<?, ?> globalChild : ((TraversalParent) step).getGlobalChildren()) {
+ if (anyStepRecursively(predicate, globalChild)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
/**
* @param stepClasses the step classes to look for
* @param traversal the traversal in which to look for the given step classes
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java
index 56b22e0..03bd8cc 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Transaction.java
@@ -20,7 +20,6 @@ package org.apache.tinkerpop.gremlin.structure;
import org.apache.tinkerpop.gremlin.structure.util.AbstractTransaction;
-import java.io.Closeable;
import java.util.Collections;
import java.util.Set;
import java.util.function.BiFunction;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
index d2fdb39..d45d411 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
@@ -61,12 +61,13 @@ public final class GraphMLReader implements GraphReader {
private final String edgeLabelKey;
private final String vertexLabelKey;
private final long batchSize;
+ private final boolean strict;
- private GraphMLReader(final String edgeLabelKey, final String vertexLabelKey,
- final long batchSize) {
- this.edgeLabelKey = edgeLabelKey;
- this.batchSize = batchSize;
- this.vertexLabelKey = vertexLabelKey;
+ private GraphMLReader(final Builder builder) {
+ this.edgeLabelKey = builder.edgeLabelKey;
+ this.batchSize = builder.batchSize;
+ this.vertexLabelKey = builder.vertexLabelKey;
+ this.strict = builder.strict;
}
@Override
@@ -143,13 +144,23 @@ public final class GraphMLReader implements GraphReader {
if (isInVertex) {
if (key.equals(vertexLabelKey))
vertexLabel = value;
- else
- vertexProps.put(dataAttributeName, typeCastValue(key, value, keyTypesMaps));
+ else {
+ try {
+ vertexProps.put(dataAttributeName, typeCastValue(key, value, keyTypesMaps));
+ } catch (NumberFormatException nfe) {
+ if (strict) throw nfe;
+ }
+ }
} else if (isInEdge) {
if (key.equals(edgeLabelKey))
edgeLabel = value;
- else
- edgeProps.put(dataAttributeName, typeCastValue(key, value, keyTypesMaps));
+ else {
+ try {
+ edgeProps.put(dataAttributeName, typeCastValue(key, value, keyTypesMaps));
+ } catch (NumberFormatException nfe) {
+ if (strict) throw nfe;
+ }
+ }
}
}
@@ -329,9 +340,19 @@ public final class GraphMLReader implements GraphReader {
public static final class Builder implements ReaderBuilder<GraphMLReader> {
private String edgeLabelKey = GraphMLTokens.LABEL_E;
private String vertexLabelKey = GraphMLTokens.LABEL_V;
+ private boolean strict = true;
private long batchSize = 10000;
- private Builder() {
+ private Builder() { }
+
+ /**
+ * When set to true, exceptions will be thrown if a property value cannot be coerced to the expected data
+ * type. If set to false, then the reader will continue with the import but ignore the failed property key.
+ * By default this value is "true".
+ */
+ public Builder strict(final boolean strict) {
+ this.strict = strict;
+ return this;
}
/**
@@ -359,7 +380,7 @@ public final class GraphMLReader implements GraphReader {
}
public GraphMLReader create() {
- return new GraphMLReader(edgeLabelKey, vertexLabelKey, batchSize);
+ return new GraphMLReader(this);
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
index 8b96052..b77f3ec 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
@@ -20,10 +20,12 @@ package org.apache.tinkerpop.gremlin.structure.io.gryo;
import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
import org.apache.tinkerpop.gremlin.process.computer.util.MapMemory;
+import org.apache.tinkerpop.gremlin.process.traversal.Contains;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_O_P_S_SE_SL_Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_P_S_SE_SL_Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_S_SE_SL_Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_O_S_SE_SL_Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_O_Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.O_Traverser;
@@ -31,7 +33,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSe
import org.apache.tinkerpop.gremlin.process.traversal.util.DependantMutableMetrics;
import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics;
import org.apache.tinkerpop.gremlin.process.traversal.util.StandardTraversalMetrics;
-import org.apache.tinkerpop.gremlin.process.traversal.Contains;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -96,12 +97,12 @@ import java.util.stream.Collectors;
* serializers in one of three ways:
* <p/>
* <ol>
- * <li>Register just the custom class with a {@code null} {@link Serializer} implementation</li>
- * <li>Register the custom class with a {@link Serializer} implementation</li>
- * <li>
- * Register the custom class with a {@code Function<Kryo, Serializer>} for those cases where the
- * {@link Serializer} requires the {@link Kryo} instance to get constructed.
- * </li>
+ * <li>Register just the custom class with a {@code null} {@link Serializer} implementation</li>
+ * <li>Register the custom class with a {@link Serializer} implementation</li>
+ * <li>
+ * Register the custom class with a {@code Function<Kryo, Serializer>} for those cases where the
+ * {@link Serializer} requires the {@link Kryo} instance to get constructed.
+ * </li>
* </ol>
* <p/>
* For example:
@@ -223,7 +224,7 @@ public final class GryoMapper implements Mapper<Kryo> {
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(ReferenceVertex.class, null, 84));
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(ReferencePath.class, null, 85));
- add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(StarGraph.class, kryo -> StarGraphGryoSerializer.with(Direction.BOTH), 86)); // ***LAST ID**
+ add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(StarGraph.class, kryo -> StarGraphGryoSerializer.with(Direction.BOTH), 86));
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Edge.class, kryo -> new GryoSerializers.EdgeSerializer(), 65));
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Vertex.class, kryo -> new GryoSerializers.VertexSerializer(), 66));
@@ -233,8 +234,9 @@ public final class GryoMapper implements Mapper<Kryo> {
// skip 55
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(B_O_Traverser.class, null, 75));
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(O_Traverser.class, null, 76));
- add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(B_O_P_S_SE_SL_Traverser.class, null, 77));
+ add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(B_LP_O_P_S_SE_SL_Traverser.class, null, 77));
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(B_O_S_SE_SL_Traverser.class, null, 78));
+ add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(B_LP_O_S_SE_SL_Traverser.class, null, 87)); // ***LAST ID**
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(TraverserSet.class, null, 58));
add(Triplet.<Class, Function<Kryo, Serializer>, Integer>with(Tree.class, null, 61));
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadLocalTransaction.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadLocalTransaction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadLocalTransaction.java
new file mode 100644
index 0000000..b47eb79
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadLocalTransaction.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.structure.util;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Transaction;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * A base implementation of {@link Transaction} that provides core functionality for transaction listeners using
+ * {@link ThreadLocal}. In this implementation, the listeners are bound to the current thread of execution (usually
+ * the same as the transaction for most graph database implementations). Therefore, when {@link #commit()} is
+ * called on a particular thread, the only listeners that get notified are those bound to that thread.
+ *
+ * @see AbstractThreadedTransaction
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractThreadLocalTransaction extends AbstractTransaction {
+
+ protected final ThreadLocal<List<Consumer<Transaction.Status>>> transactionListeners = new ThreadLocal<List<Consumer<Transaction.Status>>>() {
+ @Override
+ protected List<Consumer<Transaction.Status>> initialValue() {
+ return new ArrayList<>();
+ }
+ };
+
+ public AbstractThreadLocalTransaction(final Graph g) {
+ super(g);
+ }
+
+ @Override
+ protected void fireOnCommit() {
+ transactionListeners.get().forEach(c -> c.accept(Status.COMMIT));
+ }
+
+ @Override
+ protected void fireOnRollback() {
+ transactionListeners.get().forEach(c -> c.accept(Status.ROLLBACK));
+ }
+
+ @Override
+ public void addTransactionListener(final Consumer<Status> listener) {
+ transactionListeners.get().add(listener);
+ }
+
+ @Override
+ public void removeTransactionListener(final Consumer<Status> listener) {
+ transactionListeners.get().remove(listener);
+ }
+
+ @Override
+ public void clearTransactionListeners() {
+ transactionListeners.get().clear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/ae644951/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadedTransaction.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadedTransaction.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadedTransaction.java
new file mode 100644
index 0000000..57f8ec0
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/AbstractThreadedTransaction.java
@@ -0,0 +1,70 @@
+/*
+ * 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.structure.util;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Transaction;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+
+/**
+ * A base implementation of {@link Transaction} that provides core functionality for transaction listeners using a
+ * shared set of transaction listeners. Therefore, when {@link #commit()} is called from any thread, all listeners
+ * get notified. This implementation would be useful for graph implementations that support threaded transactions,
+ * specifically in the {@link Graph} instance returned from {@link Transaction#createThreadedTx()}.
+ *
+ * @see AbstractThreadLocalTransaction
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractThreadedTransaction extends AbstractTransaction {
+
+ protected final List<Consumer<Status>> transactionListeners = new CopyOnWriteArrayList<>();
+
+ public AbstractThreadedTransaction(final Graph g) {
+ super(g);
+ }
+
+ @Override
+ protected void fireOnCommit() {
+ transactionListeners.forEach(c -> c.accept(Status.COMMIT));
+ }
+
+ @Override
+ protected void fireOnRollback() {
+ transactionListeners.forEach(c -> c.accept(Status.ROLLBACK));
+ }
+
+ @Override
+ public void addTransactionListener(final Consumer<Status> listener) {
+ transactionListeners.add(listener);
+ }
+
+ @Override
+ public void removeTransactionListener(final Consumer<Status> listener) {
+ transactionListeners.remove(listener);
+ }
+
+ @Override
+ public void clearTransactionListeners() {
+ transactionListeners.clear();
+ }
+}