// Copyright 2017 JanusGraph Authors // // Licensed 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.janusgraph.graphdb.tinkerpop.optimize; import org.janusgraph.graphdb.tinkerpop.ElementUtils; 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.map.GraphStep; import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; import org.apache.tinkerpop.gremlin.structure.Element; import org.apache.tinkerpop.gremlin.structure.Graph; import java.util.Iterator; /** * @author Matthias Broecheler (me@matthiasb.com) */ public class JanusGraphStepStrategy extends AbstractTraversalStrategy<TraversalStrategy.ProviderOptimizationStrategy> implements TraversalStrategy.ProviderOptimizationStrategy { private static final JanusGraphStepStrategy INSTANCE = new JanusGraphStepStrategy(); private JanusGraphStepStrategy() { } @Override public void apply(final Traversal.Admin<?, ?> traversal) { if (TraversalHelper.onGraphComputer(traversal)) return; TraversalHelper.getStepsOfClass(GraphStep.class, traversal).forEach(originalGraphStep -> { if (originalGraphStep.getIds() == null || originalGraphStep.getIds().length == 0) { //Try to optimize for index calls final JanusGraphStep<?, ?> janusGraphStep = new JanusGraphStep<>(originalGraphStep); TraversalHelper.replaceStep(originalGraphStep, (Step) janusGraphStep, traversal); HasStepFolder.foldInIds(janusGraphStep, traversal); HasStepFolder.foldInHasContainer(janusGraphStep, traversal); HasStepFolder.foldInOrder(janusGraphStep, traversal, traversal, janusGraphStep.returnsVertex()); HasStepFolder.foldInRange(janusGraphStep, traversal); } else { //Make sure that any provided "start" elements are instantiated in the current transaction Object[] ids = originalGraphStep.getIds(); ElementUtils.verifyArgsMustBeEitherIdorElement(ids); if (ids[0] instanceof Element) { //GraphStep constructor ensures that the entire array is elements final Object[] elementIds = new Object[ids.length]; for (int i = 0; i < ids.length; i++) { elementIds[i] = ((Element) ids[i]).id(); } originalGraphStep.setIteratorSupplier(() -> (Iterator) (originalGraphStep.returnsVertex() ? ((Graph) originalGraphStep.getTraversal().getGraph().get()).vertices(elementIds) : ((Graph) originalGraphStep.getTraversal().getGraph().get()).edges(elementIds))); } } }); } public static JanusGraphStepStrategy instance() { return INSTANCE; } }