This is an automated email from the ASF dual-hosted git repository. okram pushed a commit to branch tp4 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/tp4 by this push: new eb05677 really cleaned up the compilation process. We have a new super cool class called Compilation. It represents a strategized and function compiled Bytecode. It also enables Processor interaction. Sorta like TraversalHelper in TP3. This really cleaned up the function code and will allow us to now do nested traversal processing with ease. eb05677 is described below commit eb05677bd53d9be682399727d6169d9a6db06e7e Author: Marko A. Rodriguez <okramma...@gmail.com> AuthorDate: Tue Mar 12 06:57:59 2019 -0600 really cleaned up the compilation process. We have a new super cool class called Compilation. It represents a strategized and function compiled Bytecode. It also enables Processor interaction. Sorta like TraversalHelper in TP3. This really cleaned up the function code and will allow us to now do nested traversal processing with ease. --- .../org/apache/tinkerpop/language/Traversal.java | 28 ++--- .../apache/tinkerpop/language/TraversalSource.java | 9 +- .../tinkerpop/machine/bytecode/BytecodeUtil.java | 50 +++++---- .../tinkerpop/machine/bytecode/Compilation.java | 113 +++++++++++++++++++++ .../machine/coefficients/LongCoefficient.java | 2 +- .../machine/functions/BranchFunction.java | 1 + .../machine/functions/InternalFunction.java | 1 - .../machine/functions/NestedFunction.java | 3 - .../machine/functions/branch/UnionBranch.java | 41 +++----- .../machine/functions/filter/FilterFilter.java | 37 ++----- .../tinkerpop/machine/functions/map/MapMap.java | 37 ++----- .../machine/processor/EmptyProcessor.java | 2 +- .../machine/processor/EmptyProcessorFactory.java | 9 +- .../machine/processor/ProcessorFactory.java | 12 +++ .../CoefficientStrategy.java} | 13 +-- .../apache/tinkerpop/machine/traversers/Path.java | 12 +++ .../apache/tinkerpop/machine/TraversalTest.java | 4 +- .../org/apache/tinkerpop/machine/beam/Beam.java | 5 - .../tinkerpop/machine/beam/BeamProcessor.java | 11 +- .../BeamStrategy.java} | 20 ++-- .../org/apache/tinkerpop/machine/pipes/Pipes.java | 3 - .../tinkerpop/machine/pipes/PipesProcessor.java | 12 ++- .../machine/pipes/strategies/PipesStrategy.java} | 20 ++-- .../apache/tinkerpop/machine/pipes/PipesTest.java | 2 +- 24 files changed, 268 insertions(+), 179 deletions(-) diff --git a/java/core/src/main/java/org/apache/tinkerpop/language/Traversal.java b/java/core/src/main/java/org/apache/tinkerpop/language/Traversal.java index f072712..e620314 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/language/Traversal.java +++ b/java/core/src/main/java/org/apache/tinkerpop/language/Traversal.java @@ -20,11 +20,9 @@ package org.apache.tinkerpop.language; import org.apache.tinkerpop.machine.bytecode.Bytecode; import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; +import org.apache.tinkerpop.machine.bytecode.Compilation; import org.apache.tinkerpop.machine.coefficients.Coefficient; import org.apache.tinkerpop.machine.coefficients.LongCoefficient; -import org.apache.tinkerpop.machine.processor.EmptyProcessorFactory; -import org.apache.tinkerpop.machine.processor.Processor; -import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.traversers.Path; import org.apache.tinkerpop.machine.traversers.Traverser; @@ -39,8 +37,7 @@ public class Traversal<C, S, E> implements Iterator<E> { protected final Bytecode<C> bytecode; private Coefficient<C> currentCoefficient; - private final ProcessorFactory processorFactory; - private Processor<C, S, E> processor; + private Compilation<C, S, E> compilation; // private long lastCount = 0L; private E lastObject = null; @@ -48,7 +45,6 @@ public class Traversal<C, S, E> implements Iterator<E> { protected Traversal(final Bytecode<C> bytecode) { this.bytecode = bytecode; this.currentCoefficient = BytecodeUtil.getCoefficient(this.bytecode).orElse((Coefficient<C>) LongCoefficient.create()); - this.processorFactory = BytecodeUtil.getProcessorFactory(this.bytecode).orElse(EmptyProcessorFactory.instance()); } public Traversal<C, S, E> as(final String label) { @@ -122,26 +118,25 @@ public class Traversal<C, S, E> implements Iterator<E> { /////// - - private void setupProcessor() { - if (null == this.processor) - this.processor = this.processorFactory.mint(this.bytecode); + private final void prepareTraversal() { + if (null == this.compilation) + this.compilation = Compilation.compile(bytecode); } @Override public boolean hasNext() { - this.setupProcessor(); - return this.lastCount > 0 || this.processor.hasNext(); + this.prepareTraversal(); + return this.lastCount > 0 || this.compilation.getProcessor().hasNext(); } @Override public E next() { - this.setupProcessor(); + this.prepareTraversal(); if (this.lastCount > 0) { this.lastCount--; return this.lastObject; } else { - final Traverser<C, E> traverser = this.processor.next(); + final Traverser<C, E> traverser = this.compilation.getProcessor().next(); if (traverser.coefficient().count() > 1) { this.lastObject = traverser.object(); this.lastCount = traverser.coefficient().count() - 1L; @@ -151,7 +146,6 @@ public class Traversal<C, S, E> implements Iterator<E> { } public List<E> toList() { - this.setupProcessor(); final List<E> list = new ArrayList<>(); while (this.hasNext()) { list.add(this.next()); @@ -161,7 +155,7 @@ public class Traversal<C, S, E> implements Iterator<E> { @Override public String toString() { - this.setupProcessor(); - return this.processor.toString(); + this.prepareTraversal(); + return this.compilation.getProcessor().toString(); } } diff --git a/java/core/src/main/java/org/apache/tinkerpop/language/TraversalSource.java b/java/core/src/main/java/org/apache/tinkerpop/language/TraversalSource.java index 91f59f9..355ab61 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/language/TraversalSource.java +++ b/java/core/src/main/java/org/apache/tinkerpop/language/TraversalSource.java @@ -36,19 +36,22 @@ public class TraversalSource<C> { public TraversalSource<C> withCoefficient(final Class<? extends Coefficient<C>> coefficient) { this.bytecode = this.bytecode.clone(); - this.bytecode.addSourceInstruction(Symbols.WITH_COEFFICIENT, coefficient.getCanonicalName()); + this.bytecode.addSourceInstruction(Symbols.WITH_COEFFICIENT, coefficient); return this; } public TraversalSource<C> withProcessor(final Class<? extends ProcessorFactory> processor) { this.bytecode = this.bytecode.clone(); - this.bytecode.addSourceInstruction(Symbols.WITH_PROCESSOR, processor.getCanonicalName()); + this.bytecode.addSourceInstruction(Symbols.WITH_PROCESSOR, processor); + for (final Strategy strategy : ProcessorFactory.processorStrategies(processor)) { + this.bytecode.addSourceInstruction(Symbols.WITH_STRATEGY, strategy.getClass()); + } return this; } public TraversalSource<C> withStrategy(final Class<? extends Strategy> strategy) { this.bytecode = this.bytecode.clone(); - this.bytecode.addSourceInstruction(Symbols.WITH_STRATEGY, strategy.getCanonicalName()); + this.bytecode.addSourceInstruction(Symbols.WITH_STRATEGY, strategy); return this; } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java b/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java index 4746e97..635e787 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java @@ -21,10 +21,10 @@ package org.apache.tinkerpop.machine.bytecode; import org.apache.tinkerpop.language.Symbols; import org.apache.tinkerpop.machine.coefficients.Coefficient; import org.apache.tinkerpop.machine.functions.CFunction; +import org.apache.tinkerpop.machine.functions.branch.UnionBranch; import org.apache.tinkerpop.machine.functions.filter.FilterFilter; import org.apache.tinkerpop.machine.functions.filter.IdentityFilter; import org.apache.tinkerpop.machine.functions.filter.IsFilter; -import org.apache.tinkerpop.machine.functions.branch.UnionBranch; import org.apache.tinkerpop.machine.functions.initial.InjectInitial; import org.apache.tinkerpop.machine.functions.map.IncrMap; import org.apache.tinkerpop.machine.functions.map.MapMap; @@ -49,27 +49,31 @@ public final class BytecodeUtil { public static <C> Bytecode<C> strategize(final Bytecode<C> bytecode) { for (final Strategy strategy : BytecodeUtil.getStrategies(bytecode)) { - strategy.apply(bytecode); - for (final Instruction<C> instruction : bytecode.getInstructions()) { - for (Object arg : instruction.args()) { - if (arg instanceof Bytecode) - strategy.apply((Bytecode<C>) arg); - } - } + BytecodeUtil.strategize(bytecode, strategy); } return bytecode; } + private static <C> void strategize(final Bytecode<C> bytecode, Strategy strategy) { + strategy.apply(bytecode); + for (final Instruction<C> instruction : bytecode.getInstructions()) { + for (Object arg : instruction.args()) { + if (arg instanceof Bytecode) + BytecodeUtil.strategize((Bytecode<C>) arg, strategy); + } + } + } + public static <C> List<Strategy> getStrategies(final Bytecode<C> bytecode) { try { final List<Strategy> strategies = new ArrayList<>(); for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { if (sourceInstruction.op().equals(Symbols.WITH_STRATEGY)) - strategies.add((Strategy) Class.forName(sourceInstruction.args()[0].toString()).getConstructor().newInstance()); + strategies.add(((Class<? extends Strategy>) sourceInstruction.args()[0]).getConstructor().newInstance()); } // sort strategies return strategies; - } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { + } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { throw new RuntimeException(e.getMessage(), e); } } @@ -79,12 +83,12 @@ public final class BytecodeUtil { Coefficient<C> coefficient = null; for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { if (sourceInstruction.op().equals(Symbols.WITH_COEFFICIENT)) { - coefficient = (Coefficient<C>) Class.forName(sourceInstruction.args()[0].toString()).getConstructor().newInstance(); + coefficient = ((Class<? extends Coefficient<C>>) sourceInstruction.args()[0]).getConstructor().newInstance(); } } return Optional.ofNullable(coefficient); - } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { + } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { throw new RuntimeException(e.getMessage(), e); } } @@ -94,15 +98,23 @@ public final class BytecodeUtil { ProcessorFactory processor = null; for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { if (sourceInstruction.op().equals(Symbols.WITH_PROCESSOR)) { - processor = (ProcessorFactory) Class.forName(sourceInstruction.args()[0].toString()).getConstructor().newInstance(); + processor = (ProcessorFactory) ((Class<? extends Coefficient<C>>) sourceInstruction.args()[0]).getConstructor().newInstance(); } } return Optional.ofNullable(processor); - } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { + } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { throw new RuntimeException(e.getMessage(), e); } } + public static boolean hasSourceInstruction(final Bytecode<?> bytecode, final String op) { + for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { + if (sourceInstruction.op().equals(op)) + return true; + } + return false; + } + public static <C> Optional<TraverserFactory<C>> getTraverserFactory(final Bytecode<C> bytecode) { return Optional.of(new CompleteTraverserFactory<C>()); } @@ -123,7 +135,7 @@ public final class BytecodeUtil { case Symbols.COUNT: return new CountReduce<>(coefficient, labels); case Symbols.FILTER: - return new FilterFilter<>(coefficient, labels, compile((Bytecode<C>) instruction.args()[0])); + return new FilterFilter<>(coefficient, labels, Compilation.compileOne(instruction.args()[0])); case Symbols.IDENTITY: return new IdentityFilter<>(coefficient, labels); case Symbols.INJECT: @@ -133,17 +145,13 @@ public final class BytecodeUtil { case Symbols.INCR: return new IncrMap<>(coefficient, labels); case Symbols.MAP: - return new MapMap<>(coefficient, labels, compile((Bytecode<C>) instruction.args()[0])); + return new MapMap<>(coefficient, labels, Compilation.compileOne(instruction.args()[0])); case Symbols.PATH: return new PathMap<>(coefficient, labels); case Symbols.SUM: return new SumReduce<>(coefficient, labels); case Symbols.UNION: - final List<List<CFunction<C>>> branchFunctions = new ArrayList<>(); - for (final Bytecode<C> arg : (Bytecode<C>[]) instruction.args()) { - branchFunctions.add(compile(arg)); - } - return new UnionBranch<>(coefficient, labels, branchFunctions); + return new UnionBranch<>(coefficient, labels, Compilation.compile(instruction.args())); default: throw new RuntimeException("This is an unknown instruction:" + instruction.op()); } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java b/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java new file mode 100644 index 0000000..b0ea933 --- /dev/null +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java @@ -0,0 +1,113 @@ +/* + * 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.machine.bytecode; + +import org.apache.tinkerpop.machine.functions.CFunction; +import org.apache.tinkerpop.machine.processor.Processor; +import org.apache.tinkerpop.machine.processor.ProcessorFactory; +import org.apache.tinkerpop.machine.traversers.Traverser; +import org.apache.tinkerpop.machine.traversers.TraverserFactory; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class Compilation<C, S, E> implements Serializable { + + private final List<CFunction<C>> functions; + private final ProcessorFactory processorFactory; + private final TraverserFactory<C> traverserFactory; + private transient Processor<C, S, E> processor; + + public Compilation(final Bytecode<C> bytecode) { + BytecodeUtil.strategize(bytecode); + this.processorFactory = BytecodeUtil.getProcessorFactory(bytecode).get(); + this.traverserFactory = BytecodeUtil.getTraverserFactory(bytecode).get(); + this.functions = BytecodeUtil.compile(bytecode); + + } + + public Processor<C, S, E> getProcessor() { + this.prepareProcessor(); + return this.processor; + } + + public void reset() { + if (null != this.processor) + this.processor.reset(); + } + + private void prepareProcessor() { + if (null == this.processor) + this.processor = this.processorFactory.mint(this.traverserFactory, this.functions); + } + + public Traverser<C, E> mapTraverser(final Traverser<C, S> traverser) { + this.reset(); + this.prepareProcessor(); + this.processor.addStart(traverser); + return this.processor.next(); + } + + public Iterator<Traverser<C, E>> flatMapTraverser(final Traverser<C, S> traverser) { + this.reset(); + this.prepareProcessor(); + this.processor.addStart(traverser); + return this.processor; + } + + public boolean filterTraverser(final Traverser<C, S> traverser) { + this.reset(); + this.prepareProcessor(); + this.processor.addStart(traverser); + return this.processor.hasNext(); + } + + @Override + public String toString() { + return this.functions.toString(); + } + + public List<CFunction<C>> getFunctions() { + return this.functions; + } + + //////// + + public static <C, S, E> Compilation<C, S, E> compile(final Bytecode<C> bytecode) { + return new Compilation<>(bytecode); + } + + public static <C, S, E> Compilation<C, S, E> compileOne(final Object arg) { + return new Compilation<>((Bytecode<C>) arg); + } + + public static <C, S, E> List<Compilation<C, S, E>> compile(final Object... args) { + final List<Compilation<C, S, E>> compilations = new ArrayList<>(); + for (final Object arg : args) { + if (arg instanceof Bytecode) + compilations.add(new Compilation<>((Bytecode<C>) arg)); + } + return compilations; + } +} diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/coefficients/LongCoefficient.java b/java/core/src/main/java/org/apache/tinkerpop/machine/coefficients/LongCoefficient.java index 0facb68..3ded932 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/coefficients/LongCoefficient.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/coefficients/LongCoefficient.java @@ -65,7 +65,7 @@ public class LongCoefficient implements Coefficient<Long> { @Override public boolean isUnity() { - return this.value == 1L; + return 1L == this.value; } @Override diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/BranchFunction.java b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/BranchFunction.java index cfebf7a..8092095 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/BranchFunction.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/BranchFunction.java @@ -30,4 +30,5 @@ import java.util.function.Function; public interface BranchFunction<C, S, E> extends Function<Traverser<C, S>, Iterator<Traverser<C, E>>>, InternalFunction<C> { public List<List<CFunction<C>>> getBranches(); + } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/InternalFunction.java b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/InternalFunction.java index e399b19..a2ce8e1 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/InternalFunction.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/InternalFunction.java @@ -26,5 +26,4 @@ import org.apache.tinkerpop.machine.traversers.TraverserFactory; */ public interface InternalFunction<C> extends CFunction<C> { - public void setProcessor(final TraverserFactory<C> traverserFactory, final ProcessorFactory processorFactory); } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java index f0bc884..2723153 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java @@ -18,13 +18,10 @@ */ package org.apache.tinkerpop.machine.functions; -import java.util.List; - /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ public interface NestedFunction<C> extends InternalFunction<C> { - public List<List<CFunction<C>>> getFunctions(); } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/branch/UnionBranch.java b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/branch/UnionBranch.java index 9634b83..c2f7a21 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/branch/UnionBranch.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/branch/UnionBranch.java @@ -18,14 +18,12 @@ */ package org.apache.tinkerpop.machine.functions.branch; +import org.apache.tinkerpop.machine.bytecode.Compilation; import org.apache.tinkerpop.machine.coefficients.Coefficient; import org.apache.tinkerpop.machine.functions.AbstractFunction; import org.apache.tinkerpop.machine.functions.BranchFunction; import org.apache.tinkerpop.machine.functions.CFunction; -import org.apache.tinkerpop.machine.processor.Processor; -import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.traversers.Traverser; -import org.apache.tinkerpop.machine.traversers.TraverserFactory; import org.apache.tinkerpop.util.MultiIterator; import org.apache.tinkerpop.util.StringFactory; @@ -38,48 +36,35 @@ import java.util.Set; * @author Marko A. Rodriguez (http://markorodriguez.com) */ public final class UnionBranch<C, S, E> extends AbstractFunction<C, S, Iterator<Traverser<C, E>>> implements BranchFunction<C, S, E> { - private final List<List<CFunction<C>>> branchFunctions; + private final List<Compilation<C, S, E>> branches; - private transient List<Processor<C, S, E>> processors; - private TraverserFactory<C> traverserFactory; - private ProcessorFactory processorFactory; - public UnionBranch(final Coefficient<C> coefficient, final Set<String> labels, final List<List<CFunction<C>>> branchFunctions) { + public UnionBranch(final Coefficient<C> coefficient, final Set<String> labels, final List<Compilation<C, S, E>> branches) { super(coefficient, labels); - this.branchFunctions = branchFunctions; + this.branches = branches; } @Override public Iterator<Traverser<C, E>> apply(final Traverser<C, S> traverser) { - if (null == this.processors) { - this.processors = new ArrayList<>(this.branchFunctions.size()); - for (final List<CFunction<C>> functions : this.branchFunctions) { - this.processors.add(processorFactory.mint(traverserFactory, functions)); - } - } final MultiIterator<Traverser<C, E>> iterator = new MultiIterator<>(); - for (final Processor<C, S, E> processor : this.processors) { - processor.reset(); - processor.addStart(traverser.clone()); - iterator.addIterator(processor); + for (final Compilation<C, S, E> branch : this.branches) { + iterator.addIterator(branch.flatMapTraverser(traverser.clone())); } return iterator; } @Override - public void setProcessor(final TraverserFactory<C> traverserFactory, final ProcessorFactory processorFactory) { - this.traverserFactory = traverserFactory; - this.processorFactory = processorFactory; + public String toString() { + return StringFactory.makeFunctionString(this, this.branches); } @Override public List<List<CFunction<C>>> getBranches() { - return this.branchFunctions; - } - - @Override - public String toString() { - return StringFactory.makeFunctionString(this, this.branchFunctions.toArray()); + final List<List<CFunction<C>>> branches = new ArrayList<>(); + for (final Compilation compilation : this.branches) { + branches.add(compilation.getFunctions()); + } + return branches; } } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/filter/FilterFilter.java b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/filter/FilterFilter.java index d247e1c..b7b25bd 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/filter/FilterFilter.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/filter/FilterFilter.java @@ -18,19 +18,14 @@ */ package org.apache.tinkerpop.machine.functions.filter; +import org.apache.tinkerpop.machine.bytecode.Compilation; import org.apache.tinkerpop.machine.coefficients.Coefficient; import org.apache.tinkerpop.machine.functions.AbstractFunction; -import org.apache.tinkerpop.machine.functions.CFunction; import org.apache.tinkerpop.machine.functions.FilterFunction; import org.apache.tinkerpop.machine.functions.NestedFunction; -import org.apache.tinkerpop.machine.processor.Processor; -import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.traversers.Traverser; -import org.apache.tinkerpop.machine.traversers.TraverserFactory; import org.apache.tinkerpop.util.StringFactory; -import java.util.Collections; -import java.util.List; import java.util.Set; /** @@ -38,40 +33,20 @@ import java.util.Set; */ public final class FilterFilter<C, S> extends AbstractFunction<C, S, S> implements FilterFunction<C, S>, NestedFunction<C> { - private final List<CFunction<C>> filterFunctions; - private TraverserFactory<C> traverserFactory; - private ProcessorFactory processorFactory; + private final Compilation<C, S, ?> internalFilter; - private transient Processor<C, S, S> processor; - - public FilterFilter(final Coefficient<C> coefficient, final Set<String> labels, final List<CFunction<C>> filterFunctions) { + public FilterFilter(final Coefficient<C> coefficient, final Set<String> labels, final Compilation<C, S, ?> internalFilter) { super(coefficient, labels); - this.filterFunctions = filterFunctions; + this.internalFilter = internalFilter; } @Override public boolean test(final Traverser<C, S> traverser) { - if (null == this.processor) - this.processor = processorFactory.mint(traverserFactory, this.filterFunctions); - else - this.processor.reset(); - this.processor.addStart(traverser); - return this.processor.hasNext(); - } - - @Override - public void setProcessor(final TraverserFactory<C> traverserFactory, final ProcessorFactory processorFactory) { - this.traverserFactory = traverserFactory; - this.processorFactory = processorFactory; - } - - @Override - public List<List<CFunction<C>>> getFunctions() { - return Collections.singletonList(this.filterFunctions); + return this.internalFilter.filterTraverser(traverser); } @Override public String toString() { - return StringFactory.makeFunctionString(this, this.filterFunctions.toArray()); + return StringFactory.makeFunctionString(this, this.internalFilter); } } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/map/MapMap.java b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/map/MapMap.java index 67e30ee..edf3348 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/map/MapMap.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/functions/map/MapMap.java @@ -18,19 +18,14 @@ */ package org.apache.tinkerpop.machine.functions.map; +import org.apache.tinkerpop.machine.bytecode.Compilation; import org.apache.tinkerpop.machine.coefficients.Coefficient; import org.apache.tinkerpop.machine.functions.AbstractFunction; -import org.apache.tinkerpop.machine.functions.CFunction; import org.apache.tinkerpop.machine.functions.MapFunction; import org.apache.tinkerpop.machine.functions.NestedFunction; -import org.apache.tinkerpop.machine.processor.Processor; -import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.traversers.Traverser; -import org.apache.tinkerpop.machine.traversers.TraverserFactory; import org.apache.tinkerpop.util.StringFactory; -import java.util.Collections; -import java.util.List; import java.util.Set; /** @@ -38,40 +33,20 @@ import java.util.Set; */ public class MapMap<C, S, E> extends AbstractFunction<C, S, E> implements MapFunction<C, S, E>, NestedFunction<C> { - private final List<CFunction<C>> mapFunctions; - private TraverserFactory<C> traverserFactory; - private ProcessorFactory processorFactory; + private final Compilation<C, S, E> internalMap; - private transient Processor<C, S, E> processor; - - public MapMap(final Coefficient<C> coefficient, final Set<String> labels, final List<CFunction<C>> mapFunctions) { + public MapMap(final Coefficient<C> coefficient, final Set<String> labels, final Compilation<C, S, E> internalMap) { super(coefficient, labels); - this.mapFunctions = mapFunctions; + this.internalMap = internalMap; } @Override public E apply(final Traverser<C, S> traverser) { - if (null == this.processor) - this.processor = processorFactory.mint(traverserFactory, this.mapFunctions); - else - this.processor.reset(); - this.processor.addStart(traverser); - return this.processor.next().object(); - } - - @Override - public void setProcessor(final TraverserFactory<C> traverserFactory, final ProcessorFactory processorFactory) { - this.traverserFactory = traverserFactory; - this.processorFactory = processorFactory; - } - - @Override - public List<List<CFunction<C>>> getFunctions() { - return Collections.singletonList(this.mapFunctions); + return this.internalMap.mapTraverser(traverser).object(); } @Override public String toString() { - return StringFactory.makeFunctionString(this, this.mapFunctions.toArray()); + return StringFactory.makeFunctionString(this, this.internalMap); } } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java b/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java index 9b89efd..6f414df 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessor.java @@ -24,7 +24,7 @@ import org.apache.tinkerpop.util.FastNoSuchElementException; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public class EmptyProcessor<C, S, E> implements Processor<C, S, E> { +public final class EmptyProcessor<C, S, E> implements Processor<C, S, E> { private static final EmptyProcessor INSTANCE = new EmptyProcessor(); diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessorFactory.java b/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessorFactory.java index 5623322..ea86138 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessorFactory.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/processor/EmptyProcessorFactory.java @@ -19,14 +19,16 @@ package org.apache.tinkerpop.machine.processor; import org.apache.tinkerpop.machine.functions.CFunction; +import org.apache.tinkerpop.machine.strategies.Strategy; import org.apache.tinkerpop.machine.traversers.TraverserFactory; +import java.util.Collections; import java.util.List; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public class EmptyProcessorFactory implements ProcessorFactory { +public final class EmptyProcessorFactory implements ProcessorFactory { private static final EmptyProcessorFactory INSTANCE = new EmptyProcessorFactory(); @@ -39,6 +41,11 @@ public class EmptyProcessorFactory implements ProcessorFactory { return EmptyProcessor.instance(); } + @Override + public List<Strategy> getStrategies() { + return Collections.emptyList(); + } + public static EmptyProcessorFactory instance() { return INSTANCE; } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/processor/ProcessorFactory.java b/java/core/src/main/java/org/apache/tinkerpop/machine/processor/ProcessorFactory.java index c6e2d11..6ffa76e 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/processor/ProcessorFactory.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/processor/ProcessorFactory.java @@ -21,9 +21,11 @@ package org.apache.tinkerpop.machine.processor; import org.apache.tinkerpop.machine.bytecode.Bytecode; import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; import org.apache.tinkerpop.machine.functions.CFunction; +import org.apache.tinkerpop.machine.strategies.Strategy; import org.apache.tinkerpop.machine.traversers.TraverserFactory; import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; import java.util.List; /** @@ -36,4 +38,14 @@ public interface ProcessorFactory extends Serializable { } public <C, S, E> Processor<C, S, E> mint(final TraverserFactory<C> traverserFactory, final List<CFunction<C>> functions); + + public List<Strategy> getStrategies(); + + public static List<Strategy> processorStrategies(final Class<? extends ProcessorFactory> processFactoryClass) { + try { + return processFactoryClass.getConstructor().newInstance().getStrategies(); + } catch (final NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { + throw new RuntimeException(e.getMessage(), e); + } + } } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java b/java/core/src/main/java/org/apache/tinkerpop/machine/strategies/CoefficientStrategy.java similarity index 74% copy from java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java copy to java/core/src/main/java/org/apache/tinkerpop/machine/strategies/CoefficientStrategy.java index f0bc884..051ab39 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/functions/NestedFunction.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/strategies/CoefficientStrategy.java @@ -16,15 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.functions; +package org.apache.tinkerpop.machine.strategies; -import java.util.List; +import org.apache.tinkerpop.machine.bytecode.Bytecode; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public interface NestedFunction<C> extends InternalFunction<C> { - - public List<List<CFunction<C>>> getFunctions(); - +public final class CoefficientStrategy implements Strategy { + @Override + public <C> void apply(Bytecode<C> bytecode) { + // todo: propagate root coefficient to all child bytecode; + } } diff --git a/java/core/src/main/java/org/apache/tinkerpop/machine/traversers/Path.java b/java/core/src/main/java/org/apache/tinkerpop/machine/traversers/Path.java index 857cc1b..76b042b 100644 --- a/java/core/src/main/java/org/apache/tinkerpop/machine/traversers/Path.java +++ b/java/core/src/main/java/org/apache/tinkerpop/machine/traversers/Path.java @@ -51,6 +51,18 @@ public class Path implements Serializable { this.labels.get(this.labels.size() - 1).addAll(labels); } + public Object object(final int index) { + return this.objects.get(index); + } + + public Set<String> labels(final int index) { + return this.labels.get(index); + } + + public int size() { + return this.objects.size(); + } + @Override public String toString() { return this.objects.toString(); diff --git a/java/core/src/test/java/org/apache/tinkerpop/machine/TraversalTest.java b/java/core/src/test/java/org/apache/tinkerpop/machine/TraversalTest.java index aeebfde..1b5e3db 100644 --- a/java/core/src/test/java/org/apache/tinkerpop/machine/TraversalTest.java +++ b/java/core/src/test/java/org/apache/tinkerpop/machine/TraversalTest.java @@ -32,8 +32,8 @@ public class TraversalTest { @Test public void shouldHaveBytecode() throws Exception { - TraversalSource<Long> g = Gremlin.traversal(); - final Traversal<Long, Long, Long> traversal = g.inject(7L).is(7L).incr().as("a").is(8L).by(__.incr()); + //TraversalSource<Long> g = Gremlin.traversal(); + //final Traversal<Long, Long, Long> traversal = g.inject(7L).is(7L).incr().as("a").is(8L).by(__.incr()); //System.out.println(traversal.bytecode); //System.out.println(BytecodeUtil.apply(traversal.getBytecode())); } diff --git a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/Beam.java b/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/Beam.java index 7aedadf..bc8e3f6 100644 --- a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/Beam.java +++ b/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/Beam.java @@ -36,10 +36,8 @@ import org.apache.tinkerpop.machine.functions.CFunction; import org.apache.tinkerpop.machine.functions.FilterFunction; import org.apache.tinkerpop.machine.functions.FlatMapFunction; import org.apache.tinkerpop.machine.functions.InitialFunction; -import org.apache.tinkerpop.machine.functions.InternalFunction; import org.apache.tinkerpop.machine.functions.MapFunction; import org.apache.tinkerpop.machine.functions.ReduceFunction; -import org.apache.tinkerpop.machine.pipes.PipesProcessor; import org.apache.tinkerpop.machine.processor.Processor; import org.apache.tinkerpop.machine.traversers.Traverser; import org.apache.tinkerpop.machine.traversers.TraverserFactory; @@ -76,9 +74,6 @@ public class Beam<C, S, E> implements Processor<C, S, E> { private PCollection<Traverser<C, ?>> processFunction(PCollection<Traverser<C, ?>> collection, final CFunction<?> function, final boolean branching) { DoFn<Traverser<C, S>, Traverser<C, E>> fn = null; - if (function instanceof InternalFunction) - ((InternalFunction<C>) function).setProcessor(this.traverserFactory, new PipesProcessor()); - if (function instanceof BranchFunction) { final List<List<CFunction<C>>> branches = ((BranchFunction) function).getBranches(); final List<PCollection<Traverser<C, ?>>> collections = new ArrayList<>(branches.size()); diff --git a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java b/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java index f063362..3094ac1 100644 --- a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java +++ b/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java @@ -18,12 +18,14 @@ */ package org.apache.tinkerpop.machine.beam; -import org.apache.tinkerpop.machine.bytecode.Bytecode; +import org.apache.tinkerpop.machine.beam.strategies.BeamStrategy; import org.apache.tinkerpop.machine.functions.CFunction; import org.apache.tinkerpop.machine.processor.Processor; import org.apache.tinkerpop.machine.processor.ProcessorFactory; +import org.apache.tinkerpop.machine.strategies.Strategy; import org.apache.tinkerpop.machine.traversers.TraverserFactory; +import java.util.Collections; import java.util.List; /** @@ -33,6 +35,11 @@ public class BeamProcessor implements ProcessorFactory { @Override public <C, S, E> Processor<C, S, E> mint(TraverserFactory<C> traverserFactory, List<CFunction<C>> cFunctions) { - return new Beam<>(traverserFactory,cFunctions); + return new Beam<>(traverserFactory, cFunctions); + } + + @Override + public List<Strategy> getStrategies() { + return Collections.singletonList(new BeamStrategy()); } } diff --git a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java b/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/strategies/BeamStrategy.java similarity index 63% copy from java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java copy to java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/strategies/BeamStrategy.java index f063362..006cf55 100644 --- a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java +++ b/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/strategies/BeamStrategy.java @@ -16,23 +16,23 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.beam; +package org.apache.tinkerpop.machine.beam.strategies; +import org.apache.tinkerpop.language.Symbols; import org.apache.tinkerpop.machine.bytecode.Bytecode; -import org.apache.tinkerpop.machine.functions.CFunction; -import org.apache.tinkerpop.machine.processor.Processor; -import org.apache.tinkerpop.machine.processor.ProcessorFactory; -import org.apache.tinkerpop.machine.traversers.TraverserFactory; - -import java.util.List; +import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; +import org.apache.tinkerpop.machine.pipes.PipesProcessor; +import org.apache.tinkerpop.machine.strategies.Strategy; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public class BeamProcessor implements ProcessorFactory { +public class BeamStrategy implements Strategy { + @Override - public <C, S, E> Processor<C, S, E> mint(TraverserFactory<C> traverserFactory, List<CFunction<C>> cFunctions) { - return new Beam<>(traverserFactory,cFunctions); + public <C> void apply(final Bytecode<C> bytecode) { + if (!BytecodeUtil.hasSourceInstruction(bytecode, Symbols.WITH_PROCESSOR)) + bytecode.addSourceInstruction(Symbols.WITH_PROCESSOR, PipesProcessor.class); } } diff --git a/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/Pipes.java b/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/Pipes.java index a413b0f..7087418 100644 --- a/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/Pipes.java +++ b/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/Pipes.java @@ -46,9 +46,6 @@ public class Pipes<C, S, E> implements Processor<C, S, E> { public Pipes(final TraverserFactory<C> traverserFactory, final List<CFunction<C>> functions) { AbstractStep<C, ?, ?> previousStep = EmptyStep.instance(); for (final CFunction<?> function : functions) { - if (function instanceof InternalFunction) - ((InternalFunction<C>) function).setProcessor(traverserFactory, new PipesProcessor()); - ///////// final AbstractStep nextStep; if (function instanceof BranchFunction) nextStep = new BranchStep(previousStep, (BranchFunction<C, ?, ?>) function); diff --git a/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/PipesProcessor.java b/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/PipesProcessor.java index 5144d29..137db3c 100644 --- a/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/PipesProcessor.java +++ b/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/PipesProcessor.java @@ -19,10 +19,13 @@ package org.apache.tinkerpop.machine.pipes; import org.apache.tinkerpop.machine.functions.CFunction; +import org.apache.tinkerpop.machine.pipes.strategies.PipesStrategy; import org.apache.tinkerpop.machine.processor.Processor; import org.apache.tinkerpop.machine.processor.ProcessorFactory; +import org.apache.tinkerpop.machine.strategies.Strategy; import org.apache.tinkerpop.machine.traversers.TraverserFactory; +import java.util.Collections; import java.util.List; /** @@ -30,8 +33,15 @@ import java.util.List; */ public class PipesProcessor implements ProcessorFactory { + public PipesProcessor() {} + @Override public <C, S, E> Processor<C, S, E> mint(final TraverserFactory<C> traverserFactory, final List<CFunction<C>> functions) { - return new Pipes<>(traverserFactory,functions); + return new Pipes<>(traverserFactory, functions); + } + + @Override + public List<Strategy> getStrategies() { + return Collections.singletonList(new PipesStrategy()); } } diff --git a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java b/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/strategies/PipesStrategy.java similarity index 63% copy from java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java copy to java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/strategies/PipesStrategy.java index f063362..8b2cf53 100644 --- a/java/machine/beam/src/main/java/org/apache/tinkerpop/machine/beam/BeamProcessor.java +++ b/java/machine/pipes/src/main/java/org/apache/tinkerpop/machine/pipes/strategies/PipesStrategy.java @@ -16,23 +16,21 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.tinkerpop.machine.beam; +package org.apache.tinkerpop.machine.pipes.strategies; +import org.apache.tinkerpop.language.Symbols; import org.apache.tinkerpop.machine.bytecode.Bytecode; -import org.apache.tinkerpop.machine.functions.CFunction; -import org.apache.tinkerpop.machine.processor.Processor; -import org.apache.tinkerpop.machine.processor.ProcessorFactory; -import org.apache.tinkerpop.machine.traversers.TraverserFactory; - -import java.util.List; +import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; +import org.apache.tinkerpop.machine.pipes.PipesProcessor; +import org.apache.tinkerpop.machine.strategies.Strategy; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ -public class BeamProcessor implements ProcessorFactory { - +public class PipesStrategy implements Strategy { @Override - public <C, S, E> Processor<C, S, E> mint(TraverserFactory<C> traverserFactory, List<CFunction<C>> cFunctions) { - return new Beam<>(traverserFactory,cFunctions); + public <C> void apply(final Bytecode<C> bytecode) { + if (!BytecodeUtil.hasSourceInstruction(bytecode, Symbols.WITH_PROCESSOR)) + bytecode.addSourceInstruction(Symbols.WITH_PROCESSOR, PipesProcessor.class); } } diff --git a/java/machine/pipes/src/test/java/org/apache/tinkerpop/machine/pipes/PipesTest.java b/java/machine/pipes/src/test/java/org/apache/tinkerpop/machine/pipes/PipesTest.java index 28b24c9..a6caa8d 100644 --- a/java/machine/pipes/src/test/java/org/apache/tinkerpop/machine/pipes/PipesTest.java +++ b/java/machine/pipes/src/test/java/org/apache/tinkerpop/machine/pipes/PipesTest.java @@ -39,7 +39,7 @@ public class PipesTest { .withProcessor(PipesProcessor.class) .withStrategy(IdentityStrategy.class); - Traversal<Long, Long, ?> traversal = g.inject(7L, 10L, 12L).as("a").c(3L).map(__.incr()).identity().incr().identity().identity().sum().path().identity(); + Traversal<Long, Long, ?> traversal = g.inject(7L, 10L, 12L).identity().incr().incr().path(); System.out.println(TraversalUtil.getBytecode(traversal)); System.out.println(traversal); System.out.println(traversal.toList());