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 37e596a  Compilations can now be compared and cloned -- equals, clone, 
hashcode. This entailed clone, equals, and hashcode for Arguments and 
CFunctions. We can now cache Compilations as well as split them apart for 
processors that want to thread components.
37e596a is described below

commit 37e596a972a446ec4211b7fece432f9a717c383c
Author: Marko A. Rodriguez <okramma...@gmail.com>
AuthorDate: Wed Mar 27 12:30:17 2019 -0600

    Compilations can now be compared and cloned -- equals, clone, hashcode. 
This entailed clone, equals, and hashcode for Arguments and CFunctions. We can 
now cache Compilations as well as split them apart for processors that want to 
thread components.
---
 .../tinkerpop/machine/bytecode/BytecodeUtil.java   |  4 +-
 .../machine/bytecode/compiler/Argument.java        |  4 +-
 .../bytecode/compiler/BytecodeArgument.java        | 23 +++++++-
 .../machine/bytecode/compiler/Compilation.java     | 13 +++--
 .../bytecode/compiler/CompilationCircle.java       | 29 +++++++++-
 .../bytecode/compiler/ConstantArgument.java        | 20 +++++++
 .../machine/bytecode/compiler/MethodArgument.java  | 17 ++++++
 .../bytecode/compiler/SourceCompilation.java       | 15 ++++++
 .../machine/function/AbstractFunction.java         | 24 +++++++++
 .../tinkerpop/machine/function/CFunction.java      |  7 +--
 .../machine/function/branch/BranchBranch.java      | 27 +++++++++-
 .../machine/function/branch/RepeatBranch.java      | 35 +++++++++---
 .../machine/function/filter/FilterFilter.java      | 34 +++++++++---
 .../machine/function/filter/HasKeyFilter.java      | 23 +++++++-
 .../machine/function/filter/HasKeyValueFilter.java | 28 ++++++++--
 .../machine/function/filter/IsFilter.java          | 24 +++++++--
 .../machine/function/flatmap/FlatMapFlatMap.java   | 22 +++++++-
 .../machine/function/initial/InitialInitial.java   | 14 ++++-
 .../machine/function/map/ConstantMap.java          | 12 +++++
 .../tinkerpop/machine/function/map/MapMap.java     | 23 ++++++--
 .../tinkerpop/machine/function/map/PathMap.java    | 23 +++++++-
 .../tinkerpop/machine/function/map/ValueMap.java   | 23 ++++++--
 .../machine/function/reduce/GroupCountReduce.java  | 22 +++++++-
 .../machine/bytecode/compiler/CompilationTest.java | 62 ++++++++++++++++++++++
 24 files changed, 476 insertions(+), 52 deletions(-)

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 aa6bca6..5272ce7 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
@@ -19,7 +19,9 @@
 package org.apache.tinkerpop.machine.bytecode;
 
 import org.apache.tinkerpop.machine.bytecode.compiler.BytecodeCompiler;
+import org.apache.tinkerpop.machine.bytecode.compiler.CommonCompiler;
 import org.apache.tinkerpop.machine.bytecode.compiler.CompositeCompiler;
+import org.apache.tinkerpop.machine.bytecode.compiler.CoreCompiler;
 import org.apache.tinkerpop.machine.bytecode.compiler.CoreCompiler.Symbols;
 import org.apache.tinkerpop.machine.coefficient.Coefficient;
 import org.apache.tinkerpop.machine.processor.ProcessorFactory;
@@ -86,7 +88,7 @@ public final class BytecodeUtil {
         final List<BytecodeCompiler> compilers = new ArrayList<>();
         BytecodeUtil.getProcessorFactory(bytecode).ifPresent(f -> 
compilers.addAll(f.getCompilers()));
         BytecodeUtil.getStructureFactory(bytecode).ifPresent(f -> 
compilers.addAll(f.getCompilers()));
-        return CompositeCompiler.create(compilers);
+        return CompositeCompiler.create(compilers.isEmpty() ? 
List.of(CoreCompiler.instance(), CommonCompiler.instance()) : compilers);
     }
 
     public static <C> Optional<Coefficient<C>> getCoefficient(final 
Bytecode<C> bytecode) {
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Argument.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Argument.java
index 495d9a2..f55edc0 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Argument.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Argument.java
@@ -27,7 +27,7 @@ import java.util.Arrays;
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public interface Argument<E> extends Serializable {
+public interface Argument<E> extends Serializable, Cloneable {
 
     public <C, S> E mapArg(final Traverser<C, S> traverser);
 
@@ -42,4 +42,6 @@ public interface Argument<E> extends Serializable {
             return new ConstantArgument<>((E) args[0]);
     }
 
+    public Argument<E> clone();
+
 }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeArgument.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeArgument.java
index 5711ab5..eb2dbaf 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeArgument.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/BytecodeArgument.java
@@ -26,7 +26,7 @@ import org.apache.tinkerpop.machine.traverser.Traverser;
  */
 public class BytecodeArgument<E> implements Argument<E> {
 
-    private final Compilation compilation;
+    private Compilation compilation;
 
     public BytecodeArgument(final Bytecode arg) {
         this.compilation = Compilation.compile(arg);
@@ -43,6 +43,27 @@ public class BytecodeArgument<E> implements Argument<E> {
     }
 
     @Override
+    public int hashCode() {
+        return this.compilation.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof BytecodeArgument && 
this.compilation.equals(((BytecodeArgument) object).compilation);
+    }
+
+    @Override
+    public BytecodeArgument<E> clone() {
+        try {
+            final BytecodeArgument<E> clone = (BytecodeArgument<E>) 
super.clone();
+            clone.compilation = this.compilation.clone();
+            return clone;
+        } catch (final CloneNotSupportedException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Override
     public String toString() {
         return this.compilation.toString();
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java
index 9b15d95..0571a03 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/Compilation.java
@@ -21,6 +21,7 @@ package org.apache.tinkerpop.machine.bytecode.compiler;
 import org.apache.tinkerpop.machine.bytecode.Bytecode;
 import org.apache.tinkerpop.machine.bytecode.BytecodeUtil;
 import org.apache.tinkerpop.machine.function.CFunction;
+import org.apache.tinkerpop.machine.processor.EmptyProcessor;
 import org.apache.tinkerpop.machine.processor.Processor;
 import org.apache.tinkerpop.machine.processor.ProcessorFactory;
 import org.apache.tinkerpop.machine.structure.EmptyStructure;
@@ -29,6 +30,7 @@ import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.traverser.TraverserFactory;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -36,9 +38,9 @@ import java.util.List;
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public final class Compilation<C, S, E> implements Serializable {
+public final class Compilation<C, S, E> implements Serializable, Cloneable {
 
-    private final List<CFunction<C>> functions;
+    private List<CFunction<C>> functions;
     private final StructureFactory structureFactory;
     private final ProcessorFactory processorFactory;
     private final TraverserFactory<C> traverserFactory;
@@ -47,7 +49,7 @@ public final class Compilation<C, S, E> implements 
Serializable {
     public Compilation(final Bytecode<C> bytecode) {
         BytecodeUtil.strategize(bytecode);
         this.structureFactory = 
BytecodeUtil.getStructureFactory(bytecode).orElse(EmptyStructure.instance());
-        this.processorFactory = 
BytecodeUtil.getProcessorFactory(bytecode).get();
+        this.processorFactory = 
BytecodeUtil.getProcessorFactory(bytecode).orElse(EmptyProcessor.instance());
         this.traverserFactory = 
BytecodeUtil.getTraverserFactory(bytecode).get();
         this.functions = BytecodeUtil.getCompilers(bytecode).compile(bytecode);
     }
@@ -148,7 +150,10 @@ public final class Compilation<C, S, E> implements 
Serializable {
         try {
             final Compilation<C, S, E> clone = (Compilation<C, S, E>) 
super.clone();
             clone.processor = null;
-            // clone.functions =  ... we need to do a deep clone given the 
nested compilations
+            clone.functions = new ArrayList<>(this.functions.size());
+            for (final CFunction<C> function : this.functions) {
+                clone.functions.add(function.clone());
+            }
             return clone;
         } catch (final CloneNotSupportedException e) {
             throw new RuntimeException(e.getMessage(), e);
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationCircle.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationCircle.java
index 831ba14..94f8e95 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationCircle.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationCircle.java
@@ -19,14 +19,15 @@
 package org.apache.tinkerpop.machine.bytecode.compiler;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public final class CompilationCircle<C, S, E> implements Serializable {
+public final class CompilationCircle<C, S, E> implements Serializable, 
Cloneable {
 
-    private final List<Compilation<C, S, E>> compilations;
+    private List<Compilation<C, S, E>> compilations;
     private final boolean hasCompilations;
     private int currentCompilation = -1;
 
@@ -53,7 +54,31 @@ public final class CompilationCircle<C, S, E> implements 
Serializable {
     }
 
     @Override
+    public int hashCode() {
+        return this.compilations.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof CompilationCircle && 
this.compilations.equals(((CompilationCircle) object).compilations);
+    }
+
+    @Override
     public String toString() {
         return this.compilations.toString();
     }
+
+    @Override
+    public CompilationCircle<C, S, E> clone() {
+        try {
+            final CompilationCircle<C, S, E> clone = (CompilationCircle<C, S, 
E>) super.clone();
+            clone.compilations = new ArrayList<>(this.compilations.size());
+            for (final Compilation<C, S, E> compilation : this.compilations) {
+                clone.compilations.add(compilation.clone());
+            }
+            return clone;
+        } catch (final CloneNotSupportedException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
 }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/ConstantArgument.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/ConstantArgument.java
index ecc9b9d..967d4f1 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/ConstantArgument.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/ConstantArgument.java
@@ -40,4 +40,24 @@ public class ConstantArgument<E> implements Argument<E> {
     public <C, S> boolean filterArg(final Traverser<C, S> traverser) {
         return (Boolean) this.constant;
     }
+
+    @Override
+    public ConstantArgument<E> clone() {
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return this.constant.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof ConstantArgument && 
this.constant.equals(((ConstantArgument) object).constant);
+    }
+
+    @Override
+    public String toString() {
+        return this.constant.toString();
+    }
 }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/MethodArgument.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/MethodArgument.java
index e940ad4..eb985d0 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/MethodArgument.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/MethodArgument.java
@@ -65,6 +65,23 @@ public class MethodArgument<E> implements Argument<E> {
     }
 
     @Override
+    public int hashCode() {
+        return this.method.hashCode() ^ Arrays.hashCode(this.arguments);
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof MethodArgument &&
+                this.method.equals(((MethodArgument) object).method) &&
+                Arrays.equals(this.arguments, ((MethodArgument) 
object).arguments);
+    }
+
+    @Override
+    public MethodArgument<E> clone() {
+        return this;
+    }
+
+    @Override
     public String toString() {
         return this.method + "(" + Arrays.toString(this.arguments) + ")";
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java
index 4b03ce9..70a9603 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java
@@ -67,4 +67,19 @@ public final class SourceCompilation<C> {
         return this.originalSource;
     }
 
+    @Override
+    public int hashCode() {
+        return this.originalSource.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof SourceCompilation && 
this.originalSource.equals(((SourceCompilation) object).originalSource);
+    }
+
+    @Override
+    public String toString() {
+        return this.originalSource.getSourceInstructions().toString();
+    }
+
 }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/AbstractFunction.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/AbstractFunction.java
index dfb6f8d..97c6bd1 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/AbstractFunction.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/AbstractFunction.java
@@ -48,4 +48,28 @@ public abstract class AbstractFunction<C> implements 
CFunction<C> {
     public String toString() {
         return StringFactory.makeFunctionString(this);
     }
+
+    @Override
+    public int hashCode() {
+        return this.coefficient.hashCode() ^ (null == this.label ? 1 : 
this.label.hashCode());
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof AbstractFunction &&
+                this.coefficient.equals(((AbstractFunction) 
object).coefficient) &&
+                ((null == this.label && null == ((AbstractFunction) 
object).label) ||
+                        (null != this.label && 
this.label.equals(((AbstractFunction) object).label)));
+    }
+
+    @Override
+    public AbstractFunction<C> clone() {
+        try {
+            final AbstractFunction<C> clone = (AbstractFunction<C>) 
super.clone();
+            clone.coefficient = this.coefficient.clone(); // TODO: make 
ImmutableCoefficient?
+            return clone;
+        } catch (final CloneNotSupportedException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
 }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/CFunction.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/CFunction.java
index 4f5ee31..38a7d37 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/CFunction.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/CFunction.java
@@ -21,17 +21,18 @@ package org.apache.tinkerpop.machine.function;
 import org.apache.tinkerpop.machine.coefficient.Coefficient;
 
 import java.io.Serializable;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public interface CFunction<C> extends Serializable {
+public interface CFunction<C> extends Serializable, Cloneable {
 
     public Coefficient<C> coefficient();
 
     public String label();
 
-    // TODO: reset() -- some functions do have state that needs resetting. 
E.g. nested compilation functions.
+    public CFunction<C> clone();
 
+    // TODO: reset() -- some functions do have state that needs resetting. 
E.g. nested compilation functions.
+    //                  most internal compilations reset() the compilation on 
every traverser insert. Except branch compilations.
 }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/BranchBranch.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/BranchBranch.java
index af9c126..fbf86e3 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/BranchBranch.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/BranchBranch.java
@@ -29,14 +29,13 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class BranchBranch<C, S, E> extends AbstractFunction<C> 
implements BranchFunction<C, S, E> {
 
-    private final Map<Compilation<C, S, ?>, List<Compilation<C, S, E>>> 
branches;
+    private Map<Compilation<C, S, ?>, List<Compilation<C, S, E>>> branches;
 
     private BranchBranch(final Coefficient<C> coefficient, final String label, 
final Map<Compilation<C, S, ?>, List<Compilation<C, S, E>>> branches) {
         super(coefficient, label);
@@ -48,6 +47,30 @@ public final class BranchBranch<C, S, E> extends 
AbstractFunction<C> implements
         return this.branches;
     }
 
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.branches.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof BranchBranch && 
this.branches.equals(((BranchBranch) object).branches) && super.equals(object);
+    }
+
+    @Override
+    public BranchBranch<C, S, E> clone() {
+        final BranchBranch<C, S, E> clone = (BranchBranch<C, S, E>) 
super.clone();
+        clone.branches = new HashMap<>(this.branches.size());
+        for (final Map.Entry<Compilation<C, S, ?>, List<Compilation<C, S, E>>> 
entry : this.branches.entrySet()) {
+            final List<Compilation<C, S, E>> compilations = new 
ArrayList<>(entry.getValue().size());
+            for (final Compilation<C, S, E> compilation : entry.getValue()) {
+                compilations.add(compilation.clone());
+            }
+            clone.branches.put(entry.getKey().clone(), compilations);
+        }
+        return clone;
+    }
+
     public static <C, S, E> BranchBranch<C, S, E> compile(final Instruction<C> 
instruction) {
         final Object[] args = instruction.args();
         final Map<Compilation<C, S, ?>, List<Compilation<C, S, E>>> branches = 
new HashMap<>();
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java
index c13fd69..b496666 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/branch/RepeatBranch.java
@@ -28,17 +28,13 @@ import 
org.apache.tinkerpop.machine.processor.LoopsProcessor;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
 import java.util.ArrayList;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class RepeatBranch<C, S> extends AbstractFunction<C> {
 
-    private final Map<Character, Compilation<C, S, S>> compilations; // TODO: 
remove
     private Compilation<C, S, S> repeatCompilation;
     private Compilation<C, S, ?> untilCompilation;
     private Compilation<C, S, ?> emitCompilation;
@@ -50,7 +46,6 @@ public final class RepeatBranch<C, S> extends 
AbstractFunction<C> {
     public RepeatBranch(final Coefficient<C> coefficient, final String label, 
final List<Object> arguments) {
         super(coefficient, label);
         int location = 1;
-        this.compilations = new LinkedHashMap<>();
         for (int i = 0; i < arguments.size(); i = i + 2) {
             final Character type = (Character) arguments.get(i);
             if ('e' == type) {
@@ -71,14 +66,12 @@ public final class RepeatBranch<C, S> extends 
AbstractFunction<C> {
                 this.repeatCompilation = (Compilation<C, S, S>) 
arguments.get(i + 1);
                 location = 3;
             }
-
-            this.compilations.put((Character) arguments.get(i), 
(Compilation<C, S, S>) arguments.get(i + 1));
         }
     }
 
     @Override
     public String toString() {
-        return StringFactory.makeFunctionString(this, this.compilations);
+        return StringFactory.makeFunctionString(this, repeatCompilation, 
untilCompilation, emitCompilation); // todo: this is random
     }
 
     public Compilation<C, S, S> getRepeat() {
@@ -109,6 +102,32 @@ public final class RepeatBranch<C, S> extends 
AbstractFunction<C> {
         return this.hasEndPredicates;
     }
 
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.repeatCompilation.hashCode() ^ 
this.emitCompilation.hashCode() ^ this.untilCompilation.hashCode() ^
+                this.emitLocation ^ this.untilLocation;
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof RepeatBranch &&
+                this.repeatCompilation.equals(((RepeatBranch) 
object).repeatCompilation) &&
+                this.emitCompilation.equals(((RepeatBranch) 
object).emitCompilation) &&
+                this.untilCompilation.equals(((RepeatBranch) 
object).untilCompilation) &&
+                this.emitLocation == ((RepeatBranch) object).emitLocation &&
+                this.untilLocation == ((RepeatBranch) object).untilLocation &&
+                super.equals(object);
+    }
+
+    @Override
+    public RepeatBranch<C, S> clone() {
+        final RepeatBranch<C, S> clone = (RepeatBranch<C, S>) super.clone();
+        clone.repeatCompilation = this.repeatCompilation.clone();
+        clone.emitCompilation = this.emitCompilation.clone();
+        clone.untilCompilation = this.untilCompilation.clone();
+        return clone;
+    }
+
     public static <C, S> RepeatBranch<C, S> compile(final Instruction<C> 
instruction) {
         final List<Object> objects = new ArrayList<>();
         for (final Object arg : instruction.args()) {
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/FilterFilter.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/FilterFilter.java
index 90820cd..fd7a68c 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/FilterFilter.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/FilterFilter.java
@@ -27,28 +27,39 @@ import org.apache.tinkerpop.machine.function.FilterFunction;
 import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
-import java.util.Set;
-
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class FilterFilter<C, S> extends AbstractFunction<C> implements 
FilterFunction<C, S> {
 
-    private final Pred pred;
-    private final Argument<S> argument;
+    private final Pred predicate;
+    private Argument<S> argument;
 
 
-    private FilterFilter(final Coefficient<C> coefficient, final String label, 
final Pred pred, final Argument<S> argument) {
+    private FilterFilter(final Coefficient<C> coefficient, final String label, 
final Pred predicate, final Argument<S> argument) {
         super(coefficient, label);
-        this.pred = pred;
+        this.predicate = predicate;
         this.argument = argument;
     }
 
     @Override
     public boolean test(final Traverser<C, S> traverser) {
-        return null == this.pred ?
+        return null == this.predicate ?
                 this.argument.filterArg(traverser) :
-                this.pred.test(traverser.object(), 
this.argument.mapArg(traverser));
+                this.predicate.test(traverser.object(), 
this.argument.mapArg(traverser));
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.predicate.hashCode() ^ 
this.argument.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof FilterFilter &&
+                this.predicate.equals(((FilterFilter) object).predicate) &&
+                this.argument.equals(((FilterFilter) object).argument) &&
+                super.equals(object);
     }
 
     @Override
@@ -56,6 +67,13 @@ public final class FilterFilter<C, S> extends 
AbstractFunction<C> implements Fil
         return StringFactory.makeFunctionString(this, this.argument);
     }
 
+    @Override
+    public FilterFilter<C, S> clone() {
+        final FilterFilter<C, S> clone = (FilterFilter<C, S>) super.clone();
+        clone.argument = this.argument.clone();
+        return clone;
+    }
+
     public static <C, S> FilterFilter<C, S> compile(final Instruction<C> 
instruction) {
         final boolean oneArg = instruction.args().length == 1;
         return new FilterFilter<>(instruction.coefficient(), 
instruction.label(),
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyFilter.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyFilter.java
index 2dbefe4..17c4e13 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyFilter.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyFilter.java
@@ -29,7 +29,6 @@ import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
 import java.util.Iterator;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -37,7 +36,7 @@ import java.util.Set;
 public final class HasKeyFilter<C, K, V> extends AbstractFunction<C> 
implements FilterFunction<C, TMap<K, V>> {
 
     private final Pred predicate;
-    private final Argument<K> key;
+    private Argument<K> key;
 
     private HasKeyFilter(final Coefficient<C> coefficient, final String label, 
final Pred predicate, final Argument<K> key) {
         super(coefficient, label);
@@ -62,10 +61,30 @@ public final class HasKeyFilter<C, K, V> extends 
AbstractFunction<C> implements
     }
 
     @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.predicate.hashCode() ^ 
this.key.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof HasKeyFilter &&
+                this.predicate.equals(((HasKeyFilter) object).predicate) &&
+                this.key.equals(((HasKeyFilter) object).key) &&
+                super.equals(object);
+    }
+
+    @Override
     public String toString() {
         return StringFactory.makeFunctionString(this, this.key);
     }
 
+    @Override
+    public HasKeyFilter<C, K, V> clone() {
+        final HasKeyFilter<C, K, V> clone = (HasKeyFilter<C, K, V>) 
super.clone();
+        clone.key = this.key.clone();
+        return clone;
+    }
+
     public static <C, K, V> HasKeyFilter<C, K, V> compile(final Instruction<C> 
instruction) {
         return new HasKeyFilter<>(instruction.coefficient(), 
instruction.label(), Pred.valueOf(instruction.args()[0]), 
Argument.create(instruction.args()[1]));
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyValueFilter.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyValueFilter.java
index a97a182..c300af3 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyValueFilter.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/HasKeyValueFilter.java
@@ -27,15 +27,13 @@ import org.apache.tinkerpop.machine.structure.data.TMap;
 import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
-import java.util.Set;
-
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class HasKeyValueFilter<C, K, V> extends AbstractFunction<C> 
implements FilterFunction<C, TMap<K, V>> {
 
-    private final Argument<K> key;
-    private final Argument<V> value;
+    private Argument<K> key;
+    private Argument<V> value;
 
     private HasKeyValueFilter(final Coefficient<C> coefficient, final String 
label, final Argument<K> key, final Argument<V> value) {
         super(coefficient, label);
@@ -50,10 +48,32 @@ public final class HasKeyValueFilter<C, K, V> extends 
AbstractFunction<C> implem
     }
 
     @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.key.hashCode() ^ this.value.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof HasKeyValueFilter &&
+                this.key.equals(((HasKeyValueFilter) object).key) &&
+                this.value.equals(((HasKeyValueFilter) object).value) &&
+                super.equals(object);
+    }
+
+    @Override
     public String toString() {
         return StringFactory.makeFunctionString(this, this.key, this.value);
     }
 
+
+    @Override
+    public HasKeyValueFilter<C, K, V> clone() {
+        final HasKeyValueFilter<C, K, V> clone = (HasKeyValueFilter<C, K, V>) 
super.clone();
+        clone.key = this.key.clone();
+        clone.value = this.value.clone();
+        return clone;
+    }
+
     public static <C, K, V> HasKeyValueFilter<C, K, V> compile(final 
Instruction<C> instruction) {
         return new HasKeyValueFilter<>(instruction.coefficient(), 
instruction.label(), Argument.create(instruction.args()[0]), 
Argument.create(instruction.args()[1]));
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/IsFilter.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/IsFilter.java
index e9bb748..e8549b8 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/IsFilter.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/filter/IsFilter.java
@@ -27,15 +27,13 @@ import org.apache.tinkerpop.machine.function.FilterFunction;
 import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
-import java.util.Set;
-
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class IsFilter<C, S> extends AbstractFunction<C> implements 
FilterFunction<C, S> {
 
     private final Pred predicate;
-    private final Argument<S> argument;
+    private Argument<S> argument;
 
     private IsFilter(final Coefficient<C> coefficient, final String label, 
final Pred predicate, final Argument<S> argument) {
         super(coefficient, label);
@@ -49,10 +47,30 @@ public final class IsFilter<C, S> extends 
AbstractFunction<C> implements FilterF
     }
 
     @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.predicate.hashCode() ^ 
this.argument.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof IsFilter &&
+                this.predicate.equals(((IsFilter) object).predicate) &&
+                this.argument.equals(((IsFilter) object).argument) &&
+                super.equals(object);
+    }
+
+    @Override
     public String toString() {
         return StringFactory.makeFunctionString(this, this.predicate, 
this.argument);
     }
 
+    @Override
+    public IsFilter<C, S> clone() {
+        final IsFilter<C, S> clone = (IsFilter<C, S>) super.clone();
+        clone.argument = this.argument.clone();
+        return clone;
+    }
+
     public static <C, S> IsFilter<C, S> compile(final Instruction<C> 
instruction) {
         return new IsFilter<>(instruction.coefficient(), instruction.label(), 
Pred.valueOf(instruction.args()[0]), Argument.create(instruction.args()[1]));
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/flatmap/FlatMapFlatMap.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/flatmap/FlatMapFlatMap.java
index c89825f..47a84cd 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/flatmap/FlatMapFlatMap.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/flatmap/FlatMapFlatMap.java
@@ -30,14 +30,13 @@ import org.apache.tinkerpop.machine.util.IteratorUtils;
 import java.lang.reflect.Array;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class FlatMapFlatMap<C, S, E> extends AbstractFunction<C> 
implements FlatMapFunction<C, S, E> {
 
-    private final Argument<E> argument;
+    private Argument<E> argument;
 
     private FlatMapFlatMap(final Coefficient<C> coefficient, final String 
label, final Argument<E> argument) {
         super(coefficient, label);
@@ -71,6 +70,25 @@ public final class FlatMapFlatMap<C, S, E> extends 
AbstractFunction<C> implement
         }
     }
 
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.argument.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof FlatMapFlatMap &&
+                this.argument.equals(((FlatMapFlatMap) object).argument) &&
+                super.equals(object);
+    }
+
+    @Override
+    public FlatMapFlatMap<C, S, E> clone() {
+        final FlatMapFlatMap<C, S, E> clone = (FlatMapFlatMap<C, S, E>) 
super.clone();
+        clone.argument = this.argument.clone();
+        return clone;
+    }
+
     public static <C, S, E> FlatMapFlatMap<C, S, E> compile(final 
Instruction<C> instruction) {
         return new FlatMapFlatMap<>(instruction.coefficient(), 
instruction.label(), Argument.create(instruction.args()));
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/InitialInitial.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/InitialInitial.java
index e8c490a..601e81f 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/InitialInitial.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/initial/InitialInitial.java
@@ -25,8 +25,8 @@ import org.apache.tinkerpop.machine.function.InitialFunction;
 import org.apache.tinkerpop.machine.util.ArrayIterator;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
+import java.util.Arrays;
 import java.util.Iterator;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -46,6 +46,18 @@ public final class InitialInitial<C, S> extends 
AbstractFunction<C> implements I
     }
 
     @Override
+    public int hashCode() {
+        return super.hashCode() ^ Arrays.hashCode(this.objects);
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof InitialInitial &&
+                Arrays.equals(this.objects, ((InitialInitial) object).objects) 
&&
+                super.equals(object);
+    }
+
+    @Override
     public String toString() {
         return StringFactory.makeFunctionString(this, this.objects);
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ConstantMap.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ConstantMap.java
index a5a87aa..bd26b5c 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ConstantMap.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ConstantMap.java
@@ -43,6 +43,18 @@ public final class ConstantMap<C, S, E> extends 
AbstractFunction<C> implements M
     }
 
     @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.constant.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof ConstantMap &&
+                this.constant.equals(((ConstantMap) object).constant) &&
+                super.equals(object);
+    }
+
+    @Override
     public String toString() {
         return StringFactory.makeFunctionString(this, this.constant);
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/MapMap.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/MapMap.java
index cfc03a2..2176295 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/MapMap.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/MapMap.java
@@ -26,14 +26,12 @@ import org.apache.tinkerpop.machine.function.MapFunction;
 import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
-import java.util.Set;
-
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class MapMap<C, S, E> extends AbstractFunction<C> implements 
MapFunction<C, S, E> {
 
-    private final Argument<E> argument;
+    private Argument<E> argument;
 
     private MapMap(final Coefficient<C> coefficient, final String label, final 
Argument<E> argument) {
         super(coefficient, label);
@@ -50,6 +48,25 @@ public final class MapMap<C, S, E> extends 
AbstractFunction<C> implements MapFun
         return StringFactory.makeFunctionString(this, this.argument);
     }
 
+    @Override
+    public int hashCode() {
+        return this.argument.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof MapMap &&
+                this.argument.equals(((MapMap) object).argument) &&
+                super.equals(object);
+    }
+
+    @Override
+    public MapMap<C, S, E> clone() {
+        final MapMap<C, S, E> clone = (MapMap<C, S, E>) super.clone();
+        clone.argument = this.argument.clone();
+        return clone;
+    }
+
     public static <C, S, E> MapMap<C, S, E> compile(final Instruction<C> 
instruction) {
         return new MapMap<>(instruction.coefficient(), instruction.label(), 
Argument.create(instruction.args()));
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/PathMap.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/PathMap.java
index 75333a8..65eec4d 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/PathMap.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/PathMap.java
@@ -30,7 +30,6 @@ import org.apache.tinkerpop.machine.traverser.path.Path;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
@@ -38,7 +37,7 @@ import java.util.Set;
 public final class PathMap<C, S> extends AbstractFunction<C> implements 
MapFunction<C, S, Path> {
 
     private final List<String> pathLabels;
-    private final CompilationCircle<C, Object, Object> byCompilations;
+    private CompilationCircle<C, Object, Object> byCompilations;
     private final boolean hasPathLabels;
     private final boolean hasByCompilations;
 
@@ -71,6 +70,26 @@ public final class PathMap<C, S> extends AbstractFunction<C> 
implements MapFunct
         }
     }
 
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.pathLabels.hashCode() ^ 
this.byCompilations.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof PathMap &&
+                this.pathLabels.equals(((PathMap) object).pathLabels) &&
+                this.byCompilations.equals(((PathMap) object).byCompilations) 
&&
+                super.equals(object);
+    }
+
+    @Override
+    public PathMap<C, S> clone() {
+        final PathMap<C, S> clone = (PathMap<C, S>) super.clone();
+        clone.byCompilations = this.byCompilations.clone();
+        return clone;
+    }
+
     public static <C, S> PathMap<C, S> compile(final Instruction<C> 
instruction) {
         final List<String> labels = new ArrayList<>();
         final List<Compilation<C, Object, Object>> compilations = new 
ArrayList<>();
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ValueMap.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ValueMap.java
index d9b88c2..4461902 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ValueMap.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/map/ValueMap.java
@@ -27,14 +27,12 @@ import org.apache.tinkerpop.machine.structure.data.TMap;
 import org.apache.tinkerpop.machine.traverser.Traverser;
 import org.apache.tinkerpop.machine.util.StringFactory;
 
-import java.util.Set;
-
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class ValueMap<C, K, V> extends AbstractFunction<C> implements 
MapFunction<C, TMap<K, V>, V> {
 
-    private final Argument<K> key;
+    private Argument<K> key;
 
     private ValueMap(final Coefficient<C> coefficient, final String label, 
final Argument<K> key) {
         super(coefficient, label);
@@ -47,6 +45,25 @@ public final class ValueMap<C, K, V> extends 
AbstractFunction<C> implements MapF
     }
 
     @Override
+    public ValueMap<C, K, V> clone() {
+        final ValueMap<C, K, V> clone = (ValueMap<C, K, V>) super.clone();
+        clone.key = this.key.clone();
+        return clone;
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.key.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof ValueMap &&
+                this.key.equals(((ValueMap) object).key) &&
+                super.equals(object);
+    }
+
+    @Override
     public String toString() {
         return StringFactory.makeFunctionString(this, this.key);
     }
diff --git 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/reduce/GroupCountReduce.java
 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/reduce/GroupCountReduce.java
index 18b7df4..a90d0fc 100644
--- 
a/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/reduce/GroupCountReduce.java
+++ 
b/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/function/reduce/GroupCountReduce.java
@@ -30,14 +30,13 @@ import org.apache.tinkerpop.machine.util.StringFactory;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
 public final class GroupCountReduce<C, S, E> extends AbstractFunction<C> 
implements ReduceFunction<C, S, TMap<E, Long>> {
 
-    private final Compilation<C, S, E> byCompilation;
+    private Compilation<C, S, E> byCompilation;
 
     private GroupCountReduce(final Coefficient<C> coefficient, final String 
label, final Compilation<C, S, E> byCompilation) {
         super(coefficient, label);
@@ -69,6 +68,25 @@ public final class GroupCountReduce<C, S, E> extends 
AbstractFunction<C> impleme
         return StringFactory.makeFunctionString(this, this.byCompilation);
     }
 
+    @Override
+    public int hashCode() {
+        return super.hashCode() ^ this.byCompilation.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return object instanceof GroupCountReduce &&
+                this.byCompilation.equals(((GroupCountReduce) 
object).byCompilation) &&
+                super.equals(object);
+    }
+
+    @Override
+    public GroupCountReduce<C, S, E> clone() {
+        final GroupCountReduce<C, S, E> clone = (GroupCountReduce<C, S, E>) 
super.clone();
+        clone.byCompilation = this.byCompilation.clone();
+        return clone;
+    }
+
     public static <C, S, E> GroupCountReduce<C, S, E> compile(final 
Instruction<C> instruction) {
         return new GroupCountReduce<>(instruction.coefficient(), 
instruction.label(), Compilation.compileOrNull(0, instruction.args()));
     }
diff --git 
a/java/machine/machine-core/src/test/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationTest.java
 
b/java/machine/machine-core/src/test/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationTest.java
new file mode 100644
index 0000000..bf89aed
--- /dev/null
+++ 
b/java/machine/machine-core/src/test/java/org/apache/tinkerpop/machine/bytecode/compiler/CompilationTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.compiler;
+
+import org.apache.tinkerpop.machine.bytecode.Bytecode;
+import org.apache.tinkerpop.machine.coefficient.LongCoefficient;
+import org.apache.tinkerpop.machine.function.CFunction;
+import org.apache.tinkerpop.machine.structure.data.TMap;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+class CompilationTest {
+
+    @Test
+    void shouldCloneCorrectly() {
+        final Bytecode<Long> bytecode = new Bytecode<>();
+        final Bytecode<Long> inner = new Bytecode<>();
+        inner.addInstruction(LongCoefficient.create(), 
CommonCompiler.Symbols.VALUE, "name");
+        bytecode.addInstruction(LongCoefficient.create(), 
CommonCompiler.Symbols.HAS_KEY, "eq", inner);
+        bytecode.addInstruction(LongCoefficient.create(), 
CommonCompiler.Symbols.COUNT);
+
+        final Compilation<Long, TMap, Long> compilationA = 
Compilation.compile(bytecode);
+        final Compilation<Long, TMap, Long> compilationB = 
compilationA.clone();
+        assertEquals(compilationA.hashCode(), compilationB.hashCode());
+        assertEquals(compilationA, compilationB);
+        assertNotSame(compilationA, compilationB);
+
+        final List<CFunction<Long>> listA = compilationA.getFunctions();
+        final List<CFunction<Long>> listB = compilationB.getFunctions();
+        assertEquals(listA.hashCode(), listB.hashCode());
+        assertEquals(listA, listB);
+        assertNotSame(listA, listB);
+        for (int i = 0; i < listA.size(); i++) {
+            assertEquals(listA.get(i).hashCode(), listB.get(i).hashCode());
+            assertEquals(listA.get(i), listB.get(i));
+            assertNotSame(listA.get(i), listB.get(i));
+        }
+    }
+}

Reply via email to