When a traversal is being constructed its construction history is maintained in a new ByteCode object. ByteCode is simply a list of instructions (stepName/arguments) that denote exactly how the traversal was constructed. This ByteCode can then be used by a Translator to translate a traversal into another language. In essence, what was previously fully done by Translator is now split between ByteCode and Translator. This removes the horrendous ThreadLocal __ model we had and it also makes Translators much simple. The API is basically Translator.translate(ByteCode). Very clean and there are probably other things that can be done with ByteCode -- e.g. Traversal serialization as any language can construct ByteCode representations with ease -- just a list of tuples (thus, a convenient JSON representation is possible).
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/c34fe9fc Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/c34fe9fc Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/c34fe9fc Branch: refs/heads/TINKERPOP-1278 Commit: c34fe9fc2cee8bf231c7d4a2d52e746053273129 Parents: 292f024 Author: Marko A. Rodriguez <[email protected]> Authored: Fri Jul 1 16:23:27 2016 -0600 Committer: Marko A. Rodriguez <[email protected]> Committed: Fri Jul 1 16:23:27 2016 -0600 ---------------------------------------------------------------------- .../strategy/decoration/RemoteStrategy.java | 2 +- .../gremlin/process/traversal/ByteCode.java | 88 ++ .../gremlin/process/traversal/Translator.java | 34 +- .../gremlin/process/traversal/Traversal.java | 7 + .../process/traversal/TraversalSource.java | 158 ++- .../process/traversal/TraversalStrategies.java | 4 - .../process/traversal/TraversalStrategy.java | 4 +- .../traversal/dsl/TraversalSourceSymbols.java | 6 +- .../dsl/graph/DefaultGraphTraversal.java | 6 +- .../traversal/dsl/graph/GraphTraversal.java | 847 +++++++----- .../dsl/graph/GraphTraversalSource.java | 90 +- .../traversal/dsl/graph/StepTranslator.java | 1273 ++++++++---------- .../process/traversal/dsl/graph/Symbols.java | 138 -- .../gremlin/process/traversal/dsl/graph/__.java | 17 +- .../lambda/AbstractLambdaTraversal.java | 5 + .../process/traversal/step/map/GroupStep.java | 7 +- .../strategy/creation/TranslationStrategy.java | 53 +- .../traversal/util/DefaultTraversal.java | 28 +- .../util/DefaultTraversalStrategies.java | 13 +- .../process/traversal/util/EmptyTranslator.java | 85 -- .../process/traversal/util/EmptyTraversal.java | 5 + .../util/EmptyTraversalStrategies.java | 10 - .../process/traversal/util/ScriptTraversal.java | 8 +- .../gremlin/structure/util/StringFactory.java | 6 +- .../gremlin/groovy/GroovyTranslatorTest.java | 2 +- .../java/translator/GroovyTranslator.java | 93 +- .../java/translator/PythonTranslator.java | 117 +- .../translator/PythonTranslatorProvider.java | 4 +- .../groovy/PythonGroovyTranslator.java | 14 +- .../groovy/PythonGroovyTranslatorTest.java | 4 +- .../jython/PythonJythonTranslator.java | 15 +- .../jython/PythonJythonTranslatorTest.java | 4 +- .../process/traversal/CoreTraversalTest.java | 2 + 33 files changed, 1584 insertions(+), 1565 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/strategy/decoration/RemoteStrategy.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/strategy/decoration/RemoteStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/strategy/decoration/RemoteStrategy.java index 613c8cc..4a0799f 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/strategy/decoration/RemoteStrategy.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/remote/traversal/strategy/decoration/RemoteStrategy.java @@ -89,7 +89,7 @@ public final class RemoteStrategy extends AbstractTraversalStrategy<TraversalStr final Traversal.Admin<?, ?> remoteTraversal; if (traversal.getStrategies().getStrategy(TranslationStrategy.class).isPresent()) { // if there is a translator, send the translation over the wire (TODO: don't use ScriptTraversal -- RemoteConnection.submit(alias, scriptEngine, script, bindings) - remoteTraversal = new ScriptTraversal<>(traversal.getStrategies().getStrategy(TranslationStrategy.class).get()); + remoteTraversal = new ScriptTraversal<>(traversal, traversal.getStrategies().getStrategy(TranslationStrategy.class).get()); TraversalHelper.removeAllSteps(traversal); } else { // if there is no translator, send the current traversal over the wire http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/ByteCode.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/ByteCode.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/ByteCode.java new file mode 100644 index 0000000..61a50e4 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/ByteCode.java @@ -0,0 +1,88 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * When a {@link TraversalSource} is manipulated, a {@link Traversal} is spawned and then mutated, a language + * agnostic representation of those mutations is recorded in a byte code instance. Byte code is simply a list + * of ordered instructions where an instruction is a string operator and an array of arguments. Byte code is used by + * {@link Translator} instances which translate a traversal to another language by analyzing the + * byte code as opposed to the Java traversal object representation on heap. + * + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class ByteCode implements Cloneable, Serializable { + + private List<Instruction> sourceInstructions = new ArrayList<>(); + private List<Instruction> stepInstructions = new ArrayList<>(); + + public void addSource(final String sourceName, final Object... arguments) { + this.sourceInstructions.add(new Instruction(sourceName, arguments)); + } + + public void addStep(final String stepName, final Object... arguments) { + this.stepInstructions.add(new Instruction(stepName, arguments)); + } + + public List<Instruction> getSourceInstructions() { + return Collections.unmodifiableList(this.sourceInstructions); + } + + public List<Instruction> getStepInstructions() { + return Collections.unmodifiableList(this.stepInstructions); + } + + @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException") + public ByteCode clone() { + try { + final ByteCode clone = (ByteCode) super.clone(); + clone.sourceInstructions = new ArrayList<>(this.sourceInstructions); + clone.stepInstructions = new ArrayList<>(this.stepInstructions); + return clone; + } catch (final CloneNotSupportedException e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + + public static class Instruction implements Serializable { + + private final String operator; + private final Object[] arguments; + + private Instruction(final String operator, final Object... arguments) { + this.operator = operator; + this.arguments = arguments; + } + + public String getOperator() { + return this.operator; + } + + public Object[] getArguments() { + return this.arguments; + } + + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java index 6437cce..e529db2 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java @@ -22,23 +22,33 @@ package org.apache.tinkerpop.gremlin.process.traversal; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public interface Translator<T extends Traversal.Admin<?, ?>, S extends TraversalSource> extends Cloneable { +public interface Translator<V> { + /** + * Get the {@link TraversalSource} alias rooting this translator. + * + * @return the string alias (typically "g"). + */ public String getAlias(); - public T addStep(final T traversal, final String stepName, final Object... arguments); - - public T addSpawnStep(final S traversalSource, final String stepName, final Object... arguments); - - public S addSource(final S traversalSource, final String sourceName, final Object... arguments); - - public Translator getAnonymousTraversalTranslator(); - - public String getTraversalScript(); - - public Translator clone(); + /** + * Translate {@link ByteCode} into a new representation. + * Typically, for language translations, the translation is to a string represenging the traversal in the respective scripting language. + * + * @param byteCode the byte code representing traversal source and traversal manipulations. + * @return the translated object + */ + public V translate(final ByteCode byteCode); public String getSourceLanguage(); + /** + * Get the language that the translator is converting the traversal byte code to. + * + * @return the language of the translation + */ public String getTargetLanguage(); + + // TODO: getTranslationClass() -- e.g. for GroovyTranslator, its String. + // TODO: Do we need getSourceLanguage()? The source language is always ByteCode now! } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java index 6993250..05a6c3e 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Traversal.java @@ -239,6 +239,13 @@ public interface Traversal<S, E> extends Iterator<E>, Serializable, Cloneable { public interface Admin<S, E> extends Traversal<S, E> { /** + * Get the {@link ByteCode} associated with the construction of this traversal. + * + * @return the byte code representation of the traversal + */ + public ByteCode getByteCode(); + + /** * Add an iterator of {@link Traverser.Admin} objects to the head/start of the traversal. * Users should typically not need to call this method. For dynamic inject of data, they should use {@link org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep}. * http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java index e314a28..265cec5 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java @@ -21,10 +21,11 @@ package org.apache.tinkerpop.gremlin.process.traversal; import org.apache.tinkerpop.gremlin.process.computer.Computer; import org.apache.tinkerpop.gremlin.process.computer.GraphComputer; import org.apache.tinkerpop.gremlin.process.computer.traversal.strategy.decoration.VertexProgramStrategy; -import org.apache.tinkerpop.gremlin.process.traversal.dsl.TraversalSourceSymbols; import org.apache.tinkerpop.gremlin.process.traversal.strategy.creation.TranslationStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SackStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SideEffectStrategy; import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier; import java.io.Serializable; import java.util.List; @@ -49,8 +50,6 @@ import java.util.function.UnaryOperator; */ public interface TraversalSource extends Cloneable { - public static final String SET_ANONYMOUS_TRAVERSAL_FUNCTION = "setAnonymousTraversalFunction"; - /** * Get the {@link TraversalStrategies} associated with this traversal source. * @@ -65,6 +64,29 @@ public interface TraversalSource extends Cloneable { */ public Graph getGraph(); + /** + * Get the {@link ByteCode} associated with the current state of this traversal source. + * + * @return the traversal source byte code + */ + public ByteCode getByteCode(); + + ///////////////////////////// + + public static class Symbols { + + private Symbols() { + // static fields only + } + + public static final String withSack = "withSack"; + public static final String withStrategies = "withStrategies"; + public static final String withoutStrategies = "withoutStrategies"; + public static final String withComputer = "withComputer"; + public static final String withSideEffect = "withSideEffect"; + public static final String withTranslator = "withTranslator"; + } + ///////////////////////////// /** @@ -76,6 +98,7 @@ public interface TraversalSource extends Cloneable { public default TraversalSource withStrategies(final TraversalStrategy... traversalStrategies) { final TraversalSource clone = this.clone(); clone.getStrategies().addStrategies(traversalStrategies); + clone.getByteCode().addSource(TraversalSource.Symbols.withStrategies, traversalStrategies); return clone; } @@ -89,31 +112,47 @@ public interface TraversalSource extends Cloneable { public default TraversalSource withoutStrategies(final Class<? extends TraversalStrategy>... traversalStrategyClasses) { final TraversalSource clone = this.clone(); clone.getStrategies().removeStrategies(traversalStrategyClasses); + clone.getByteCode().addSource(TraversalSource.Symbols.withoutStrategies, traversalStrategyClasses); return clone; } /** - * Add a {@link Function} that will generate a {@link GraphComputer} from the {@link Graph} that will be used to execute the traversal. - * This adds a {@link VertexProgramStrategy} to the strategies. + * Add a {@link Translator} to translate any traversal from this traversal source language into some target language. * - * @param computer a builder to generate a graph computer from the graph + * @param translator the translator that will do the source to targer language translation * @return a new traversal source with updated strategies */ - public default TraversalSource withComputer(final Computer computer) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withComputer, computer); - + public default TraversalSource withTranslator(final Translator translator) { + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(new TranslationStrategy(clone, translator)); + clone.getByteCode().addSource(Symbols.withTranslator, translator); + return clone; } /** - * Add a {@link Translator} to translate any traversal from this traversal source language into some target language. + * Add a {@link Function} that will generate a {@link GraphComputer} from the {@link Graph} that will be used to execute the traversal. + * This adds a {@link VertexProgramStrategy} to the strategies. * - * @param translator the translator that will do the source to targer language translation + * @param computer a builder to generate a graph computer from the graph * @return a new traversal source with updated strategies */ - public default TraversalSource withTranslator(final Translator translator) { + public default TraversalSource withComputer(final Computer computer) { + Class<? extends GraphComputer> graphComputerClass; + try { + graphComputerClass = computer.apply(this.getGraph()).getClass(); + } catch (final Exception e) { + graphComputerClass = computer.getGraphComputerClass(); + } + final List<TraversalStrategy<?>> graphComputerStrategies = TraversalStrategies.GlobalCache.getStrategies(graphComputerClass).toList(); + final TraversalStrategy[] traversalStrategies = new TraversalStrategy[graphComputerStrategies.size() + 1]; + traversalStrategies[0] = new VertexProgramStrategy(computer); + for (int i = 0; i < graphComputerStrategies.size(); i++) { + traversalStrategies[i + 1] = graphComputerStrategies.get(i); + } + /// final TraversalSource clone = this.clone(); - clone.getStrategies().addStrategies(new TranslationStrategy(clone, null)); - clone.getStrategies().setTranslator(translator); + clone.getStrategies().addStrategies(traversalStrategies); + clone.getByteCode().addSource(TraversalSource.Symbols.withComputer, computer); return clone; } @@ -125,7 +164,17 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default TraversalSource withComputer(final Class<? extends GraphComputer> graphComputerClass) { - return this.withComputer(Computer.compute(graphComputerClass)); + final List<TraversalStrategy<?>> graphComputerStrategies = TraversalStrategies.GlobalCache.getStrategies(graphComputerClass).toList(); + final TraversalStrategy[] traversalStrategies = new TraversalStrategy[graphComputerStrategies.size() + 1]; + traversalStrategies[0] = new VertexProgramStrategy(Computer.compute(graphComputerClass)); + for (int i = 0; i < graphComputerStrategies.size(); i++) { + traversalStrategies[i + 1] = graphComputerStrategies.get(i); + } + /// + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(traversalStrategies); + clone.getByteCode().addSource(TraversalSource.Symbols.withComputer, graphComputerClass); + return clone; } /** @@ -135,7 +184,24 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default TraversalSource withComputer() { - return this.withComputer(Computer.compute()); + final Computer computer = Computer.compute(); + Class<? extends GraphComputer> graphComputerClass; + try { + graphComputerClass = computer.apply(this.getGraph()).getClass(); + } catch (final Exception e) { + graphComputerClass = computer.getGraphComputerClass(); + } + final List<TraversalStrategy<?>> graphComputerStrategies = TraversalStrategies.GlobalCache.getStrategies(graphComputerClass).toList(); + final TraversalStrategy[] traversalStrategies = new TraversalStrategy[graphComputerStrategies.size() + 1]; + traversalStrategies[0] = new VertexProgramStrategy(computer); + for (int i = 0; i < graphComputerStrategies.size(); i++) { + traversalStrategies[i + 1] = graphComputerStrategies.get(i); + } + /// + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(traversalStrategies); + clone.getByteCode().addSource(TraversalSource.Symbols.withComputer); + return clone; } /** @@ -148,7 +214,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSideEffect(final String key, final Supplier<A> initialValue, final BinaryOperator<A> reducer) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSideEffect, key, initialValue, reducer); + final TraversalSource clone = this.clone(); + SideEffectStrategy.addSideEffect(clone.getStrategies(), key, (A) initialValue, reducer); + clone.getByteCode().addSource(TraversalSource.Symbols.withSideEffect, key, initialValue, reducer); + return clone; } /** @@ -161,7 +230,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSideEffect(final String key, final A initialValue, final BinaryOperator<A> reducer) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSideEffect, key, initialValue, reducer); + final TraversalSource clone = this.clone(); + SideEffectStrategy.addSideEffect(clone.getStrategies(), key, initialValue, reducer); + clone.getByteCode().addSource(TraversalSource.Symbols.withSideEffect, key, initialValue, reducer); + return clone; } /** @@ -173,7 +245,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSideEffect(final String key, final Supplier<A> initialValue) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSideEffect, key, initialValue); + final TraversalSource clone = this.clone(); + SideEffectStrategy.addSideEffect(clone.getStrategies(), key, (A) initialValue, null); + clone.getByteCode().addSource(TraversalSource.Symbols.withSideEffect, key, initialValue); + return clone; } /** @@ -185,7 +260,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSideEffect(final String key, final A initialValue) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSideEffect, key, initialValue); + final TraversalSource clone = this.clone(); + SideEffectStrategy.addSideEffect(clone.getStrategies(), key, initialValue, null); + clone.getByteCode().addSource(TraversalSource.Symbols.withSideEffect, key, initialValue); + return clone; } /** @@ -198,7 +276,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue, splitOperator, mergeOperator); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(initialValue).splitOperator(splitOperator).mergeOperator(mergeOperator).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue, splitOperator, mergeOperator); + return clone; } /** @@ -211,7 +292,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator, final BinaryOperator<A> mergeOperator) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue, splitOperator, mergeOperator); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(new ConstantSupplier<>(initialValue)).splitOperator(splitOperator).mergeOperator(mergeOperator).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue, splitOperator, mergeOperator); + return clone; } /** @@ -222,7 +306,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final A initialValue) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(new ConstantSupplier<>(initialValue)).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue); + return clone; } /** @@ -233,7 +320,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final Supplier<A> initialValue) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(initialValue).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue); + return clone; } /** @@ -245,7 +335,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final Supplier<A> initialValue, final UnaryOperator<A> splitOperator) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue, splitOperator); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(initialValue).splitOperator(splitOperator).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue, splitOperator); + return clone; } /** @@ -257,7 +350,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final A initialValue, final UnaryOperator<A> splitOperator) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue, splitOperator); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(new ConstantSupplier<>(initialValue)).splitOperator(splitOperator).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue, splitOperator); + return clone; } /** @@ -269,7 +365,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final Supplier<A> initialValue, final BinaryOperator<A> mergeOperator) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue, mergeOperator); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(initialValue).mergeOperator(mergeOperator).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue, mergeOperator); + return clone; } /** @@ -281,7 +380,10 @@ public interface TraversalSource extends Cloneable { * @return a new traversal source with updated strategies */ public default <A> TraversalSource withSack(final A initialValue, final BinaryOperator<A> mergeOperator) { - return this.getStrategies().getTranslator().addSource(this, TraversalSourceSymbols.withSack, initialValue, mergeOperator); + final TraversalSource clone = this.clone(); + clone.getStrategies().addStrategies(SackStrategy.<A>build().initialValue(new ConstantSupplier<>(initialValue)).mergeOperator(mergeOperator).create()); + clone.getByteCode().addSource(TraversalSource.Symbols.withSack, initialValue, mergeOperator); + return clone; } /** http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/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 934f3f0..14b831a 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 @@ -77,10 +77,6 @@ public interface TraversalStrategies extends Serializable, Cloneable { return (Optional) toList().stream().filter(s -> traversalStrategyClass.isAssignableFrom(s.getClass())).findAny(); } - public Translator getTranslator(); - - public void setTranslator(final Translator translator); - /** * Apply all the {@link TraversalStrategy} optimizers to the {@link Traversal} for the stated {@link TraversalEngine}. * This method must ensure that the strategies are sorted prior to application. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java index 2bd7978..e09b03c 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategy.java @@ -29,7 +29,7 @@ import java.util.Set; /** * A {@link TraversalStrategy} defines a particular atomic operation for mutating a {@link Traversal} prior to its evaluation. - * There are 5 pre-defined "traversal categories": {@link DecorationStrategy}, {@link OptimizationStrategy}, {@link ProviderOptimizationStrategy}, {@link FinalizationStrategy}, and {@link VerificationStrategy}. + * There are 6 pre-defined "traversal categories": {@link CreationStrategy}, {@link DecorationStrategy}, {@link OptimizationStrategy}, {@link ProviderOptimizationStrategy}, {@link FinalizationStrategy}, and {@link VerificationStrategy}. * Strategies within a category are sorted amongst themselves and then category sorts are applied in the ordered specified previous. * That is, decorations are applied, then optimizations, then provider optimizations, then finalizations, and finally, verifications. * If a strategy does not fit within the specified categories, then it can simply implement {@link TraversalStrategy} and can have priors/posts that span categories. @@ -67,7 +67,7 @@ public interface TraversalStrategy<S extends TraversalStrategy> extends Serializ } /** - * The type of traversal strategy -- i.e. {@link DecorationStrategy}, {@link OptimizationStrategy}, {@link FinalizationStrategy}, or {@link VerificationStrategy}. + * The type of traversal strategy -- i.e. {@link CreationStrategy}, {@link DecorationStrategy}, {@link OptimizationStrategy}, {@link FinalizationStrategy}, or {@link VerificationStrategy}. * * @return the traversal strategy category class */ http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/TraversalSourceSymbols.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/TraversalSourceSymbols.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/TraversalSourceSymbols.java index 1099e84..04ce342 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/TraversalSourceSymbols.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/TraversalSourceSymbols.java @@ -28,9 +28,5 @@ public final class TraversalSourceSymbols { // all static methods } - public static final String withSack = "withSack"; - public static final String withStrategies = "withStrategies"; - public static final String withoutStrategies = "withoutStrategies"; - public static final String withComputer = "withComputer"; - public static final String withSideEffect = "withSideEffect"; + } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c34fe9fc/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/DefaultGraphTraversal.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/DefaultGraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/DefaultGraphTraversal.java index f1b878d..f435241 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/DefaultGraphTraversal.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/DefaultGraphTraversal.java @@ -28,12 +28,14 @@ public class DefaultGraphTraversal<S, E> extends DefaultTraversal<S, E> implemen public DefaultGraphTraversal() { super(); - this.strategies.setTranslator(new StepTranslator()); + } + + public DefaultGraphTraversal(final GraphTraversalSource graphTraversalSource) { + super(graphTraversalSource); } public DefaultGraphTraversal(final Graph graph) { super(graph); - this.strategies.setTranslator(new StepTranslator()); } @Override
