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 9e21a74 implemented a basic implementation of explain(). Some smart cleanup and it will be pretty slammin'. 9e21a74 is described below commit 9e21a74e583b58c387e276ac8d8d436053bd8af5 Author: Marko A. Rodriguez <okramma...@gmail.com> AuthorDate: Tue Mar 19 12:40:24 2019 -0600 implemented a basic implementation of explain(). Some smart cleanup and it will be pretty slammin'. --- .../tinkerpop/language/gremlin/Traversal.java | 9 ++- .../tinkerpop/machine/bytecode/BytecodeUtil.java | 8 +-- .../tinkerpop/machine/bytecode/Compilation.java | 30 +++++--- .../tinkerpop/machine/bytecode/CoreCompiler.java | 1 + .../machine/processor/ExplainProcessor.java | 82 +++++++++++++++++++++ .../machine/traverser/ShellTraverser.java | 84 ++++++++++++++++++++++ .../machine/processor/pipes/PipesTest.java | 5 +- .../blueprints/bytecode/BlueprintsCompiler.java | 7 +- .../provider/BlueprintsVerticesStrategy.java | 2 +- 9 files changed, 205 insertions(+), 23 deletions(-) diff --git a/java/language/gremlin/src/main/java/org/apache/tinkerpop/language/gremlin/Traversal.java b/java/language/gremlin/src/main/java/org/apache/tinkerpop/language/gremlin/Traversal.java index 7c27824..af444ec 100644 --- a/java/language/gremlin/src/main/java/org/apache/tinkerpop/language/gremlin/Traversal.java +++ b/java/language/gremlin/src/main/java/org/apache/tinkerpop/language/gremlin/Traversal.java @@ -42,6 +42,7 @@ public class Traversal<C, S, E> implements Iterator<E> { protected final Bytecode<C> bytecode; private Compilation<C, S, E> compilation; private Coefficient<C> currentCoefficient; + private boolean locked = false; // TODO: when a traversal has been submitted, we need to make sure new modulations can't happen. // iteration helpers private long lastCount = 0L; @@ -114,6 +115,11 @@ public class Traversal<C, S, E> implements Iterator<E> { return this; } + public Traversal<C, S, String> explain() { + this.bytecode.addInstruction(this.currentCoefficient, Symbols.EXPLAIN); + return (Traversal) this; + } + public Traversal<C, S, E> filter(final Traversal<C, E, ?> filterTraversal) { this.bytecode.addInstruction(this.currentCoefficient, Symbols.FILTER, filterTraversal.bytecode); return this; @@ -293,7 +299,6 @@ public class Traversal<C, S, E> implements Iterator<E> { @Override public String toString() { - this.prepareTraversal(); - return this.compilation.getProcessor().toString(); + return this.bytecode.toString(); } } diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java index d267b5c..e1ee051 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/BytecodeUtil.java @@ -46,7 +46,7 @@ public final class BytecodeUtil { } } - private static <C> void strategize(final Bytecode<C> bytecode, Strategy strategy) { + public 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()) { @@ -56,7 +56,7 @@ public final class BytecodeUtil { } } - private static <C> Set<Strategy<?>> getStrategies(final Bytecode<C> bytecode) { + public static <C> Set<Strategy<?>> getStrategies(final Bytecode<C> bytecode) { try { final Set<Strategy<?>> strategies = new HashSet<>(); for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { @@ -97,7 +97,7 @@ public final class BytecodeUtil { } } - static <C> Optional<ProcessorFactory> getProcessorFactory(final Bytecode<C> bytecode) { + public static <C> Optional<ProcessorFactory> getProcessorFactory(final Bytecode<C> bytecode) { try { ProcessorFactory processor = null; for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { @@ -111,7 +111,7 @@ public final class BytecodeUtil { } } - static <C> Optional<StructureFactory> getStructureFactory(final Bytecode<C> bytecode) { + public static <C> Optional<StructureFactory> getStructureFactory(final Bytecode<C> bytecode) { try { StructureFactory structure = null; for (final SourceInstruction sourceInstruction : bytecode.getSourceInstructions()) { diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java index 6732443..2e9b8df 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/Compilation.java @@ -19,12 +19,14 @@ package org.apache.tinkerpop.machine.bytecode; import org.apache.tinkerpop.machine.function.CFunction; +import org.apache.tinkerpop.machine.processor.ExplainProcessor; import org.apache.tinkerpop.machine.processor.FilterProcessor; import org.apache.tinkerpop.machine.processor.LoopsProcessor; import org.apache.tinkerpop.machine.processor.Processor; import org.apache.tinkerpop.machine.processor.ProcessorFactory; import org.apache.tinkerpop.machine.structure.EmptyStructure; import org.apache.tinkerpop.machine.structure.StructureFactory; +import org.apache.tinkerpop.machine.traverser.COTraverserFactory; import org.apache.tinkerpop.machine.traverser.Traverser; import org.apache.tinkerpop.machine.traverser.TraverserFactory; @@ -48,11 +50,19 @@ public final class Compilation<C, S, E> implements Serializable { private transient Processor<C, S, E> processor; public Compilation(final Bytecode<C> bytecode) { - BytecodeUtil.strategize(bytecode); - this.structureFactory = BytecodeUtil.getStructureFactory(bytecode).orElse(EmptyStructure.instance()); - this.processorFactory = BytecodeUtil.getProcessorFactory(bytecode).get(); - this.traverserFactory = BytecodeUtil.getTraverserFactory(bytecode).get(); - this.functions = CompositeCompiler.compile(bytecode, Arrays.asList(CoreCompiler.instance(), this.structureFactory.getCompiler().orElse(new CoreCompiler()))); + if (bytecode.lastInstruction().op().equals(CoreCompiler.Symbols.EXPLAIN)) { + this.processorFactory = new ExplainProcessor(bytecode); + this.traverserFactory = null; + this.functions = Collections.emptyList(); + this.structureFactory = null; + + } else { + BytecodeUtil.strategize(bytecode); + this.structureFactory = BytecodeUtil.getStructureFactory(bytecode).orElse(EmptyStructure.instance()); + this.processorFactory = BytecodeUtil.getProcessorFactory(bytecode).get(); + this.traverserFactory = BytecodeUtil.getTraverserFactory(bytecode).get(); + this.functions = CompositeCompiler.compile(bytecode, Arrays.asList(CoreCompiler.instance(), this.structureFactory.getCompiler().orElse(new CoreCompiler()))); + } } public Compilation(final ProcessorFactory processorFactory) { @@ -116,11 +126,6 @@ public final class Compilation<C, S, E> implements Serializable { return this.processor.hasNext() ? Optional.of(this.processor.next()) : Optional.empty(); } - @Override - public String toString() { - return this.functions.toString(); - } - public List<CFunction<C>> getFunctions() { return this.functions; } @@ -129,6 +134,11 @@ public final class Compilation<C, S, E> implements Serializable { return this.traverserFactory; } + @Override + public String toString() { + return this.functions.toString(); + } + //////// public static <C, S, E> Compilation<C, S, E> compile(final Bytecode<C> bytecode) { diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/CoreCompiler.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/CoreCompiler.java index b4b60e4..4b541b7 100644 --- a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/CoreCompiler.java +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/CoreCompiler.java @@ -173,6 +173,7 @@ public final class CoreCompiler implements BytecodeCompiler { public static final String CONSTANT = "constant"; // [count] public static final String COUNT = "count"; + public static final String EXPLAIN = "explain"; // [filter, [bc]] public static final String FILTER = "filter"; // [groupCount, ?[bc]] diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/ExplainProcessor.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/ExplainProcessor.java new file mode 100644 index 0000000..23262d3 --- /dev/null +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/processor/ExplainProcessor.java @@ -0,0 +1,82 @@ +/* + * 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.processor; + +import org.apache.tinkerpop.machine.bytecode.Bytecode; +import org.apache.tinkerpop.machine.bytecode.BytecodeUtil; +import org.apache.tinkerpop.machine.bytecode.CompositeCompiler; +import org.apache.tinkerpop.machine.bytecode.CoreCompiler; +import org.apache.tinkerpop.machine.coefficient.LongCoefficient; +import org.apache.tinkerpop.machine.strategy.Strategy; +import org.apache.tinkerpop.machine.structure.EmptyStructure; +import org.apache.tinkerpop.machine.traverser.ShellTraverser; +import org.apache.tinkerpop.machine.traverser.Traverser; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class ExplainProcessor extends SimpleProcessor<Long, String, String> { + + public ExplainProcessor(final Bytecode bytecode) { + bytecode.getInstructions().remove(bytecode.getInstructions().size() - 1); + super.traverser = new ShellTraverser<>(LongCoefficient.create(), ExplainProcessor.processBytecode(bytecode)); + } + + @Override + public void addStart(final Traverser<Long, String> traverser) { + throw new IllegalStateException("This shouldn't occur"); // TODO: exception handling system + } + + private static String processBytecode(final Bytecode<Long> bytecode) { + final Map<String, String> explain = new LinkedHashMap<>(); + explain.put("Original", bytecode.toString()); + for (final Strategy strategy : BytecodeUtil.getStrategies(bytecode)) { + BytecodeUtil.strategize(bytecode, strategy); + explain.put(strategy.toString(), bytecode.toString()); + } + int maxLength = 0; + for (final String key : explain.keySet()) { + if (maxLength < key.length()) + maxLength = key.length(); + } + final StringBuilder builder = new StringBuilder(); + for (final Map.Entry<String, String> entry : explain.entrySet()) { + final int spaces = maxLength - entry.getKey().length(); + builder.append(entry.getKey()); + for (int i = 0; i < spaces; i++) { + builder.append(" "); + } + builder.append("\t\t").append(entry.getValue()).append("\n"); + } + final String functions = CompositeCompiler.compile(bytecode, Arrays.asList(CoreCompiler.instance(), + BytecodeUtil.getStructureFactory(bytecode).orElse(EmptyStructure.instance()).getCompiler().orElse(new CoreCompiler()))).toString(); + + builder.append("Final"); + for (int i = 0; i < maxLength - "Final".length(); i++) { + builder.append(" "); + } + builder.append("\t\t").append(functions); + return builder.toString(); + + } +} diff --git a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/ShellTraverser.java b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/ShellTraverser.java new file mode 100644 index 0000000..bb69ee2 --- /dev/null +++ b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/traverser/ShellTraverser.java @@ -0,0 +1,84 @@ +/* + * 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.traverser; + +import org.apache.tinkerpop.machine.coefficient.Coefficient; +import org.apache.tinkerpop.machine.function.CFunction; +import org.apache.tinkerpop.machine.traverser.path.EmptyPath; +import org.apache.tinkerpop.machine.traverser.path.Path; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public class ShellTraverser<C, S> implements Traverser<C, S> { + + private final Coefficient<C> coefficient; + private final S object; + + public ShellTraverser(final Coefficient<C> coefficient, final S object) { + this.coefficient = coefficient; + this.object = object; + } + + @Override + public Coefficient<C> coefficient() { + return this.coefficient; + } + + @Override + public S object() { + return this.object; + } + + @Override + public Path path() { + return EmptyPath.instance(); + } + + @Override + public void incrLoops() { + + } + + @Override + public int loops() { + return 0; + } + + @Override + public void resetLoops() { + + } + + @Override + public <E> Traverser<C, E> split(CFunction<C> function, E object) { + return null; + } + + @Override + public <E> Traverser<C, E> split(E object) { + return null; + } + + @Override + public Traverser<C, S> clone() { + return this; + } + +} diff --git a/java/machine/processor/pipes/src/test/java/org/apache/tinkerpop/machine/processor/pipes/PipesTest.java b/java/machine/processor/pipes/src/test/java/org/apache/tinkerpop/machine/processor/pipes/PipesTest.java index 536ff0d..546bb0c 100644 --- a/java/machine/processor/pipes/src/test/java/org/apache/tinkerpop/machine/processor/pipes/PipesTest.java +++ b/java/machine/processor/pipes/src/test/java/org/apache/tinkerpop/machine/processor/pipes/PipesTest.java @@ -25,7 +25,6 @@ import org.apache.tinkerpop.language.gremlin.TraversalSource; import org.apache.tinkerpop.language.gremlin.TraversalUtil; import org.apache.tinkerpop.language.gremlin.__; import org.apache.tinkerpop.machine.coefficient.LongCoefficient; -import org.apache.tinkerpop.machine.processor.pipes.PipesProcessor; import org.apache.tinkerpop.machine.strategy.optimization.IdentityStrategy; import org.apache.tinkerpop.machine.structure.tinkergraph.TinkerGraphStructure; import org.junit.jupiter.api.Test; @@ -50,11 +49,11 @@ public class PipesTest { .withStructure(TinkerGraphStructure.class) .withStrategy(IdentityStrategy.class); - Traversal<Long, ?, ?> traversal = g.V().identity().map(__.count()); + Traversal<Long, ?, ?> traversal = g.V().identity().union(__.count(),__.count()).map(__.<Long,Long>count().identity()).explain(); System.out.println(TraversalUtil.getBytecode(traversal)); System.out.println(traversal); System.out.println(TraversalUtil.getBytecode(traversal)); - System.out.println(traversal.toList()); + System.out.println(traversal.next()); System.out.println("\n----------\n"); } diff --git a/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/bytecode/BlueprintsCompiler.java b/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/bytecode/BlueprintsCompiler.java index 0391324..f82768a 100644 --- a/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/bytecode/BlueprintsCompiler.java +++ b/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/bytecode/BlueprintsCompiler.java @@ -31,12 +31,13 @@ import java.util.Set; * @author Marko A. Rodriguez (http://markorodriguez.com) */ public class BlueprintsCompiler implements BytecodeCompiler { + @Override public <C> CFunction<C> compile(final Instruction<C> instruction) { final String op = instruction.op(); final Coefficient<C> coefficient = instruction.coefficient(); final Set<String> labels = instruction.labels(); - if (op.equals(Symbols.TG_V)) + if (op.equals(Symbols.BP_V)) return new VerticesFlatMap<>(coefficient, labels); else return null; @@ -44,7 +45,7 @@ public class BlueprintsCompiler implements BytecodeCompiler { @Override public FunctionType getFunctionType(final String op) { - return op.equals(Symbols.TG_V) ? FunctionType.INITIAL : null; + return op.equals(Symbols.BP_V) ? FunctionType.INITIAL : null; } public static class Symbols { @@ -53,6 +54,6 @@ public class BlueprintsCompiler implements BytecodeCompiler { // static instance } - public static final String TG_V = "tg:V"; + public static final String BP_V = "bp:V"; } } diff --git a/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/strategy/provider/BlueprintsVerticesStrategy.java b/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/strategy/provider/BlueprintsVerticesStrategy.java index 19357db..1fb857a 100644 --- a/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/strategy/provider/BlueprintsVerticesStrategy.java +++ b/java/machine/structure/blueprints/src/main/java/org/apache/tinkerpop/machine/structure/blueprints/strategy/provider/BlueprintsVerticesStrategy.java @@ -38,6 +38,6 @@ public class BlueprintsVerticesStrategy extends AbstractStrategy<Strategy.Provid temp = instruction; } if (null != temp) - BytecodeUtil.replaceInstruction(bytecode, temp, new Instruction<>(temp.coefficient(), BlueprintsCompiler.Symbols.TG_V)); + BytecodeUtil.replaceInstruction(bytecode, temp, new Instruction<>(temp.coefficient(), BlueprintsCompiler.Symbols.BP_V)); } }