Improved performance of TinkerGraph around element lookup. Primary change was to drop use of Stream and use IteratorUtils.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/70dd3245 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/70dd3245 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/70dd3245 Branch: refs/heads/TINKERPOP-1063 Commit: 70dd3245eadcf2dd69720c50fbffd3b0c9e92922 Parents: 84f2d63 Author: Stephen Mallette <[email protected]> Authored: Tue Dec 22 16:43:45 2015 -0500 Committer: Stephen Mallette <[email protected]> Committed: Thu Jun 16 14:19:23 2016 -0400 ---------------------------------------------------------------------- .../step/sideEffect/TinkerGraphStep.java | 15 +++++----- .../tinkergraph/structure/TinkerGraph.java | 31 ++++++++++++-------- 2 files changed, 27 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70dd3245/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java ---------------------------------------------------------------------- diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java index b0a5714..3ec73c3 100644 --- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java +++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/process/traversal/step/sideEffect/TinkerGraphStep.java @@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerHelper; +import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; import java.util.ArrayList; import java.util.Arrays; @@ -79,17 +80,17 @@ public final class TinkerGraphStep<S, E extends Element> extends GraphStep<S, E> else return null == indexedContainer ? this.iteratorList(graph.vertices()) : - TinkerHelper.queryVertexIndex(graph, indexedContainer.getKey(), indexedContainer.getPredicate().getValue()).stream() - .filter(vertex -> HasContainer.testAll(vertex, this.hasContainers)) - .collect(Collectors.<Vertex>toList()).iterator(); + IteratorUtils.filter(TinkerHelper.queryVertexIndex(graph, indexedContainer.getKey(), indexedContainer.getPredicate().getValue()).iterator(), + vertex -> HasContainer.testAll(vertex, this.hasContainers)); } private HasContainer getIndexKey(final Class<? extends Element> indexedClass) { final Set<String> indexedKeys = ((TinkerGraph) this.getTraversal().getGraph().get()).getIndexedKeys(indexedClass); - return this.hasContainers.stream() - .filter(c -> indexedKeys.contains(c.getKey()) && c.getPredicate().getBiPredicate() == Compare.eq) - .findAny() - .orElseGet(() -> null); + + final Iterator<HasContainer> itty = IteratorUtils.filter(hasContainers.iterator(), + c -> c.getPredicate().getBiPredicate() == Compare.eq && indexedKeys.contains(c.getKey())); + return itty.hasNext() ? itty.next() : null; + } @Override http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/70dd3245/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 35e268e..168dd7f 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 @@ -36,11 +36,13 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputer; import org.apache.tinkerpop.gremlin.tinkergraph.process.computer.TinkerGraphComputerView; import org.apache.tinkerpop.gremlin.tinkergraph.process.traversal.strategy.optimization.TinkerGraphStepStrategy; +import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; import java.io.File; -import java.io.IOException; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -317,31 +319,36 @@ public final class TinkerGraph implements Graph { } } - - private <T extends Element> Iterator<T> createElementIterator(final Class<T> clazz, final Map<Object, T> elements, final IdManager idManager, final Object... ids) { if (0 == ids.length) { 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())) { - // 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 + // 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 Stream.of(ids).map(id -> elements.get(((T) id).id())).filter(Objects::nonNull).iterator(); + 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(); - if (!Stream.of(ids).map(Object::getClass).allMatch(firstClass::equals)) - throw Graph.Exceptions.idArgsMustBeEitherIdOrElement(); - return Stream.of(ids).map(id -> idManager.convert(id)).map(elements::get).filter(Objects::nonNull).iterator(); + 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); } } }
