added RepeatUnrollStrategy for when the loop amount is known at compile time. Fixed a bug in BranchStep around child integration.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/8753366a Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/8753366a Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/8753366a Branch: refs/heads/TINKERPOP-1254 Commit: 8753366a975101ba4edaa1888163abda3238f7ff Parents: 0787e46 Author: Marko A. Rodriguez <[email protected]> Authored: Tue Jun 28 10:44:32 2016 -0600 Committer: Marko A. Rodriguez <[email protected]> Committed: Tue Jun 28 10:44:32 2016 -0600 ---------------------------------------------------------------------- .../process/traversal/TraversalStrategies.java | 2 + .../traversal/step/branch/BranchStep.java | 12 +- .../optimization/RepeatUnrollStrategy.java | 75 +++++++++ .../IdentityRemovalStrategyTest.java | 35 ++++- .../optimization/RepeatUnrollStrategyTest.java | 154 +++++++++++++++++++ .../process/traversal/step/map/ProfileTest.java | 36 +++-- 6 files changed, 291 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java index 137abb9..b093676 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalStrategies.java @@ -30,6 +30,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.Matc import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.OrderLimitStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.PathProcessorStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ComputerVerificationStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.StandardVerificationStrategy; import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies; @@ -193,6 +194,7 @@ public interface TraversalStrategies extends Serializable, Cloneable { FilterRankingStrategy.instance(), IdentityRemovalStrategy.instance(), MatchPredicateStrategy.instance(), + RepeatUnrollStrategy.instance(), RangeByIsCountStrategy.instance(), ProfileStrategy.instance(), StandardVerificationStrategy.instance()); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java index 2cd954d..19df2a6 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/branch/BranchStep.java @@ -165,18 +165,22 @@ public class BranchStep<S, E, M> extends ComputerAwareStep<S, E> implements Trav final List<Traversal.Admin<S, E>> clonedTraversals = clone.traversalOptions.compute(entry.getKey(), (k, v) -> (v == null) ? new ArrayList<>(traversals.size()) : v); for (final Traversal.Admin<S, E> traversal : traversals) { - final Traversal.Admin<S, E> clonedTraversal = traversal.clone(); - clonedTraversals.add(clonedTraversal); - clone.integrateChild(clonedTraversal); + clonedTraversals.add(traversal.clone()); } } } clone.branchTraversal = this.branchTraversal.clone(); - clone.integrateChild(clone.branchTraversal); return clone; } @Override + public void setTraversal(final Traversal.Admin<?, ?> parentTraversal) { + super.setTraversal(parentTraversal); + this.integrateChild(this.branchTraversal); + this.traversalOptions.values().stream().flatMap(List::stream).forEach(this::integrateChild); + } + + @Override public int hashCode() { int result = super.hashCode(); if (this.traversalOptions != null) http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java new file mode 100644 index 0000000..9047478 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategy.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization; + +import org.apache.tinkerpop.gremlin.process.traversal.Step; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.lambda.LoopTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.step.branch.RepeatStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.map.NoOpBarrierStep; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +public final class RepeatUnrollStrategy extends AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements TraversalStrategy.OptimizationStrategy { + + private static final RepeatUnrollStrategy INSTANCE = new RepeatUnrollStrategy(); + + private RepeatUnrollStrategy() { + } + + @Override + public void apply(final Traversal.Admin<?, ?> traversal) { + if (!TraversalHelper.hasStepOfAssignableClass(RepeatStep.class, traversal) || + TraversalHelper.onGraphComputer(traversal)) + return; + + for (int i = 0; i < traversal.getSteps().size(); i++) { + if (traversal.getSteps().get(i) instanceof RepeatStep) { + final RepeatStep<?> repeatStep = (RepeatStep) traversal.getSteps().get(i); + if (null == repeatStep.getEmitTraversal() && repeatStep.getUntilTraversal() instanceof LoopTraversal) { + final Traversal.Admin<?, ?> repeatTraversal = repeatStep.getGlobalChildren().get(0); + final int repeatLength = repeatTraversal.getSteps().size() - 1; + repeatTraversal.removeStep(repeatLength); + int insertIndex = i; + final int loops = (int) ((LoopTraversal) repeatStep.getUntilTraversal()).getMaxLoops(); + for (int j = 0; j < loops; j++) { + TraversalHelper.insertTraversal(insertIndex, repeatTraversal.clone(), traversal); // removes the RepeatEndStep + insertIndex = insertIndex + repeatLength + 1; + traversal.addStep(insertIndex, new NoOpBarrierStep<>(traversal)); + } + if (!repeatStep.getLabels().isEmpty()) { + final Step<?, ?> lastStep = (Step) traversal.getSteps().get(insertIndex); + repeatStep.getLabels().forEach(lastStep::addLabel); + } + traversal.removeStep(i); // remove the RepeatStep + } + } + } + } + + + public static RepeatUnrollStrategy instance() { + return INSTANCE; + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java index fd1ec2b..c71ad99 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/IdentityRemovalStrategyTest.java @@ -22,6 +22,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies; +import org.apache.tinkerpop.gremlin.util.TimeUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -29,6 +30,8 @@ import org.junit.runners.Parameterized; import java.util.Arrays; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * @author Marko A. Rodriguez (http://markorodriguez.com) @@ -36,6 +39,8 @@ import static org.junit.Assert.assertEquals; @RunWith(Parameterized.class) public class IdentityRemovalStrategyTest { + private static boolean executedshouldBeFaster = false; + @Parameterized.Parameter(value = 0) public Traversal original; @@ -43,7 +48,7 @@ public class IdentityRemovalStrategyTest { public Traversal optimized; - void applyIdentityRemovalStrategy(final Traversal traversal) { + private void applyIdentityRemovalStrategy(final Traversal traversal) { final TraversalStrategies strategies = new DefaultTraversalStrategies(); strategies.addStrategies(IdentityRemovalStrategy.instance()); traversal.asAdmin().setStrategies(strategies); @@ -70,4 +75,30 @@ public class IdentityRemovalStrategyTest { {__.out().identity().as("a").out().in().identity().identity().as("b").identity().out(), __.out().as("a").out().in().as("b").out()}, }); } -} \ No newline at end of file + + @Test + public void shouldBeFaster() { + if (executedshouldBeFaster) + return; + else + executedshouldBeFaster = true; + final int startSize = 1000; + final int clockRuns = 1000; + final Integer[] starts = new Integer[startSize]; + for (int i = 0; i < startSize; i++) { + starts[i] = i; + } + + final Runnable original = () -> __.inject(starts).identity().identity().identity().identity().iterate(); + + final Runnable optimized = () -> { + final Traversal<Integer, Integer> traversal = __.inject(starts).identity().identity().identity().identity(); + traversal.asAdmin().setStrategies(traversal.asAdmin().getStrategies().clone().addStrategies(IdentityRemovalStrategy.instance())); + traversal.iterate(); + }; + + //System.out.println(TimeUtil.clock(clockRuns, original) + "---" + TimeUtil.clock(clockRuns,optimized)); + assertTrue(TimeUtil.clock(clockRuns, original) > TimeUtil.clock(clockRuns, optimized)); + assertTrue(TimeUtil.clock(clockRuns, optimized) < TimeUtil.clock(clockRuns, original)); + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java new file mode 100644 index 0000000..1c4c4b7 --- /dev/null +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/RepeatUnrollStrategyTest.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization; + +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; +import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies; +import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.util.TimeUtil; +import org.javatuples.Pair; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Random; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Marko A. Rodriguez (http://markorodriguez.com) + */ +@RunWith(Parameterized.class) +public class RepeatUnrollStrategyTest { + + private static final Random RANDOM = new Random(); + private static boolean shouldBeFasterWithUniqueStreamExecuted = false; + private static boolean shouldBeFasterWithDuplicateStreamExecuted = false; + + @Parameterized.Parameter(value = 0) + public Traversal original; + + @Parameterized.Parameter(value = 1) + public Traversal optimized; + + + private void applyRepeatUnrollStrategy(final Traversal traversal) { + final TraversalStrategies strategies = new DefaultTraversalStrategies(); + strategies.addStrategies(RepeatUnrollStrategy.instance()); + traversal.asAdmin().setStrategies(strategies); + traversal.asAdmin().applyStrategies(); + + } + + @Test + public void doTest() { + applyRepeatUnrollStrategy(original); + assertEquals(optimized, original); + } + + @Parameterized.Parameters(name = "{0}") + public static Iterable<Object[]> generateTestParameters() { + + final Predicate<Traverser<Vertex>> predicate = t -> t.loops() > 5; + return Arrays.asList(new Traversal[][]{ + {__.identity(), __.identity()}, + {__.out().as("a").in().repeat(__.outE("created").bothV()).times(2).in(), __.out().as("a").in().outE("created").bothV().barrier().outE("created").bothV().barrier().in()}, + {__.out().repeat(__.outE("created").bothV()).times(1).in(), __.out().outE("created").bothV().barrier().in()}, + {__.repeat(__.outE("created").bothV()).times(1).in(), __.outE("created").bothV().barrier().in()}, + {__.repeat(__.out()).times(2).as("x").repeat(__.in().as("b")).times(3), __.out().barrier().out().barrier().as("x").in().as("b").barrier().in().as("b").barrier().in().as("b").barrier()}, + {__.repeat(__.outE("created").inV()).times(2), __.outE("created").inV().barrier().outE("created").inV().barrier()}, + {__.repeat(__.out()).times(3), __.out().barrier().out().barrier().out().barrier()}, + {__.repeat(__.local(__.select("a").out("knows"))).times(2), __.local(__.select("a").out("knows")).barrier().local(__.select("a").out("knows")).barrier()}, + {__.<Vertex>times(2).repeat(__.out()), __.out().barrier().out().barrier()}, + {__.<Vertex>out().times(2).repeat(__.out().as("a")).as("x"), __.out().out().as("a").barrier().out().as("a").barrier().as("x")}, + {__.repeat(__.out()).emit().times(2), __.repeat(__.out()).emit().times(2)}, + {__.repeat(__.out()).until(predicate), __.repeat(__.out()).until(predicate)}, + {__.repeat(__.out()).until(predicate).repeat(__.out()).times(2), __.repeat(__.out()).until(predicate).out().barrier().out().barrier()}, + {__.repeat(__.union(__.both(), __.identity())).times(2).out(), __.union(__.both(), __.identity()).barrier().union(__.both(), __.identity()).barrier().out()}, + }); + } + + @Test + public void shouldBeFasterWithUniqueStream() { + if (shouldBeFasterWithUniqueStreamExecuted) + return; + shouldBeFasterWithUniqueStreamExecuted = true; + final int startSize = 1000; + final int clockRuns = 1000; + final Integer[] starts = new Integer[startSize]; + for (int i = 0; i < startSize; i++) { + starts[i] = i; // 1000 unique objects + } + assertEquals(startSize, new HashSet<>(Arrays.asList(starts)).size()); + clockTraversals(starts, clockRuns); + } + + @Test + public void shouldBeFasterWithDuplicateStream() { + if (shouldBeFasterWithDuplicateStreamExecuted) + return; + shouldBeFasterWithDuplicateStreamExecuted = true; + final int startSize = 1000; + final int clockRuns = 1000; + final int uniques = 100; + final Integer[] starts = new Integer[startSize]; + for (int i = 0; i < startSize; i++) { + starts[i] = i % uniques; // 100 unique objects + } + assertEquals(uniques, new HashSet<>(Arrays.asList(starts)).size()); + clockTraversals(starts, clockRuns); + } + + private void clockTraversals(final Integer[] starts, final int clockRuns) { + final int times = RANDOM.nextInt(4) + 2; + assertTrue(times > 1 && times < 6); + final Supplier<Long> original = () -> __.inject(starts).repeat(__.identity()).times(times).<Long>sum().next(); + + final TraversalStrategies strategies = new DefaultTraversalStrategies(); + strategies.addStrategies(RepeatUnrollStrategy.instance()); + final Supplier<Long> optimized = () -> { + final Traversal<Integer, Long> traversal = __.inject(starts).repeat(__.identity()).times(times).sum(); + traversal.asAdmin().setStrategies(strategies); + return traversal.next(); + }; + + final Pair<Double, Long> originalResult; + final Pair<Double, Long> optimizedResult; + if (RANDOM.nextBoolean()) { + originalResult = TimeUtil.clockWithResult(clockRuns, original); + optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized); + } else { + optimizedResult = TimeUtil.clockWithResult(clockRuns, optimized); + originalResult = TimeUtil.clockWithResult(clockRuns, original); + } + + // System.out.println(originalResult + "---" + optimizedResult); + assertEquals(originalResult.getValue1(), optimizedResult.getValue1()); + assertTrue(originalResult.getValue0() > optimizedResult.getValue0()); + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/8753366a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java index 4d0ce49..548e7ab 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/ProfileTest.java @@ -33,6 +33,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.process.traversal.step.Profiling; import org.apache.tinkerpop.gremlin.process.traversal.step.util.ProfileStep; import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RangeByIsCountStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ComputerVerificationStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException; import org.apache.tinkerpop.gremlin.process.traversal.util.Metrics; import org.apache.tinkerpop.gremlin.process.traversal.util.MutableMetrics; @@ -231,7 +233,9 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest { printTraversalForm(traversal); final TraversalMetrics traversalMetrics = traversal.next(); - validate_g_V_repeat_both_modern_profile(traversalMetrics); + validate_g_V_repeat_both_modern_profile(traversalMetrics, + traversal.asAdmin().getStrategies().toList().contains(RepeatUnrollStrategy.instance()) && + !traversal.asAdmin().getStrategies().toList().contains(ComputerVerificationStrategy.instance())); } @Test @@ -241,10 +245,12 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest { printTraversalForm(traversal); traversal.iterate(); final TraversalMetrics traversalMetrics = traversal.asAdmin().getSideEffects().<TraversalMetrics>get(METRICS_KEY); - validate_g_V_repeat_both_modern_profile(traversalMetrics); + validate_g_V_repeat_both_modern_profile(traversalMetrics, + traversal.asAdmin().getStrategies().toList().contains(RepeatUnrollStrategy.instance()) && + !traversal.asAdmin().getStrategies().toList().contains(ComputerVerificationStrategy.instance())); } - private void validate_g_V_repeat_both_modern_profile(TraversalMetrics traversalMetrics) { + private void validate_g_V_repeat_both_modern_profile(TraversalMetrics traversalMetrics, boolean withRepeatUnrollStrategy) { traversalMetrics.toString(); // ensure no exceptions are thrown Metrics metrics = traversalMetrics.getMetrics(0); @@ -252,25 +258,21 @@ public abstract class ProfileTest extends AbstractGremlinProcessTest { assertEquals(6, metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue()); metrics = traversalMetrics.getMetrics(1); - assertEquals(72, metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue()); + assertEquals(withRepeatUnrollStrategy ? 12 : 72, metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue()); assertNotEquals(0, metrics.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); - assertTrue("Count should be greater than traversers.", metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > metrics.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); + if (!withRepeatUnrollStrategy) + assertTrue("Count should be greater than traversers.", metrics.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > metrics.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); assertTrue("Percent duration should be positive.", (Double) metrics.getAnnotation(TraversalMetrics.PERCENT_DURATION_KEY) >= 0); assertTrue("Times should be positive.", metrics.getDuration(TimeUnit.MICROSECONDS) >= 0); // Test the nested global metrics of the repeat step - final Metrics vertexStepNestedInRepeat = (Metrics) metrics.getNested().toArray()[0]; - assertEquals(114, vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue()); - assertNotEquals(0, vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); - assertTrue("Count should be greater than traversers.", vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); - assertTrue("Times should be positive.", vertexStepNestedInRepeat.getDuration(TimeUnit.MICROSECONDS) >= 0); - - /*final Metrics repeatEndStepNestedInRepeat = (Metrics) metrics.getNested().toArray()[1]; - assertEquals(72, repeatEndStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue()); - assertNotEquals(0, repeatEndStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); - assertTrue("Count should be greater than traversers.", repeatEndStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > repeatEndStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); - assertTrue("Times should be positive.", repeatEndStepNestedInRepeat.getDuration(TimeUnit.MICROSECONDS) >= 0);*/ - + if (!withRepeatUnrollStrategy) { + final Metrics vertexStepNestedInRepeat = (Metrics) metrics.getNested().toArray()[0]; + assertEquals(114, vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID).longValue()); + assertNotEquals(0, vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); + assertTrue("Count should be greater than traversers.", vertexStepNestedInRepeat.getCount(TraversalMetrics.ELEMENT_COUNT_ID) > vertexStepNestedInRepeat.getCount(TraversalMetrics.TRAVERSER_COUNT_ID).longValue()); + assertTrue("Times should be positive.", vertexStepNestedInRepeat.getDuration(TimeUnit.MICROSECONDS) >= 0); + } double totalPercentDuration = 0; for (Metrics m : traversalMetrics.getMetrics()) {
