blob: 9b204cf28574c083178c08afdabfa3168c77601c [file] [log] [blame]
/*
* 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.step.map;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.CoinStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.ConnectiveStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.WhereTraversalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyStep;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.B_LP_O_P_S_SE_SL_TraverserGenerator;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.EmptyTraverser;
import org.apache.tinkerpop.gremlin.structure.T;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.function.Consumer;
import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.and;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.as;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.match;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.or;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.where;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
public class MatchStepTest extends StepTest {
@Override
protected List<Traversal> getTraversals() {
return Arrays.asList(
__.match(as("a").out("knows").as("b")),
__.match(as("a").out().as("b")),
////
__.match(where(as("a").out("knows").as("b"))),
__.match(as("a").where(out().as("b"))),
///
match(__.as("a").out().as("b"), __.as("b").out().as("c")),
match(__.as("b").out().as("c"), __.as("a").out().as("d"))
);
}
@Test
public void testPreCompilationOfStartAndEnds() {
final Traversal.Admin<?, ?> traversal = __.match(as("a").out().as("b"), as("c").path().as("d")).asAdmin();
final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
assertEquals(MatchStep.class, traversal.getStartStep().getClass());
assertEquals(2, matchStep.getGlobalChildren().size());
Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
//
pattern = matchStep.getGlobalChildren().get(1);
assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(PathStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("d", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
}
@Test
public void testPreCompilationOfOr() {
final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
__.match(as("a").out().as("b"), or(as("c").path().as("d"), as("e").coin(0.5).as("f"))).asAdmin(),
__.match(as("a").out().as("b"), as("c").path().as("d").or().as("e").coin(0.5).as("f")).asAdmin());
assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
traversals.forEach(traversal -> {
final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
assertEquals(2, matchStep.getGlobalChildren().size());
Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
//
pattern = matchStep.getGlobalChildren().get(1);
assertEquals(MatchStep.class, pattern.getStartStep().getClass());
assertEquals(ConnectiveStep.Connective.OR, ((MatchStep<?, ?>) pattern.getStartStep()).getConnective());
assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
assertEquals(CoinStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
assertEquals("f", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().get());
});
}
@Test
public void testPreCompilationOfAnd() {
final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
__.match(as("a").out().as("b"), and(as("c").path().as("d"), as("e").barrier())).asAdmin(),
__.match(as("a").out().as("b"), as("c").path().as("d").and().as("e").barrier()).asAdmin());
assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
traversals.forEach(traversal -> {
final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
assertEquals(2, matchStep.getGlobalChildren().size());
Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
//
pattern = matchStep.getGlobalChildren().get(1);
assertEquals(MatchStep.class, pattern.getStartStep().getClass());
assertEquals(ConnectiveStep.Connective.AND, ((MatchStep<?, ?>) pattern.getStartStep()).getConnective());
assertEquals("c", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep()).getSelectKey().get());
assertEquals(PathStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getStartStep().getNextStep().getClass());
assertEquals("d", ((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(0).getEndStep()).getMatchKey().get());
assertEquals("e", ((MatchStep.MatchStartStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep()).getSelectKey().get());
assertEquals(NoOpBarrierStep.class, ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getStartStep().getNextStep().getClass());
assertFalse(((MatchStep.MatchEndStep) ((MatchStep<?, ?>) pattern.getStartStep()).getGlobalChildren().get(1).getEndStep()).getMatchKey().isPresent());
});
}
@Test
public void testPreCompilationOfWhereTraversal() {
final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
__.match(as("a").out().as("b"), as("c").where(in().as("d"))).asAdmin(),
__.match(as("a").out().as("b"), where(as("c").in().as("d"))).asAdmin());
assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
traversals.forEach(traversal -> {
final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
//assertFalse(matchStep.getStartLabel().isPresent());
assertEquals(2, matchStep.getGlobalChildren().size());
Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
//
pattern = matchStep.getGlobalChildren().get(1);
assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(WhereTraversalStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
assertEquals(1, ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().size());
Traversal.Admin<?, ?> whereTraversal = ((WhereTraversalStep<?>) pattern.getStartStep().getNextStep()).getLocalChildren().get(0);
assertEquals(WhereTraversalStep.WhereStartStep.class, whereTraversal.getStartStep().getClass());
assertTrue(((WhereTraversalStep.WhereStartStep) whereTraversal.getStartStep()).getScopeKeys().isEmpty());
assertEquals(VertexStep.class, whereTraversal.getStartStep().getNextStep().getClass());
assertEquals(WhereTraversalStep.WhereEndStep.class, whereTraversal.getStartStep().getNextStep().getNextStep().getClass());
assertEquals(1, ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().size());
assertEquals("d", ((WhereTraversalStep.WhereEndStep) whereTraversal.getStartStep().getNextStep().getNextStep()).getScopeKeys().iterator().next());
});
}
@Test
public void testPreCompilationOfWherePredicate() {
final List<Traversal.Admin<?, ?>> traversals = Arrays.asList(
__.match(as("a").out().as("b"), as("c").where(P.neq("d"))).asAdmin(),
__.match(as("a").out().as("b"), where("c", P.neq("d"))).asAdmin());
assertEquals(1, new HashSet<>(traversals).size()); // the two patterns should pre-compile to the same traversal
traversals.forEach(traversal -> {
final MatchStep<?, ?> matchStep = (MatchStep<?, ?>) traversal.getStartStep();
//assertFalse(matchStep.getStartLabel().isPresent());
assertEquals(2, matchStep.getGlobalChildren().size());
Traversal.Admin<Object, Object> pattern = matchStep.getGlobalChildren().get(0);
assertEquals("a", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(VertexStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals("b", ((MatchStep.MatchEndStep) pattern.getEndStep()).getMatchKey().get());
//
pattern = matchStep.getGlobalChildren().get(1);
assertEquals(MatchStep.MatchStartStep.class, pattern.getStartStep().getClass());
assertEquals("c", ((MatchStep.MatchStartStep) pattern.getStartStep()).getSelectKey().get());
assertEquals(WherePredicateStep.class, pattern.getStartStep().getNextStep().getClass());
assertEquals(MatchStep.MatchEndStep.class, pattern.getStartStep().getNextStep().getNextStep().getClass());
assertFalse(((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getStartKey().isPresent());
assertEquals("d", ((WherePredicateStep<?>) pattern.getStartStep().getNextStep()).getPredicate().get().getOriginalValue());
});
}
@Test
public void testCountMatchAlgorithm() {
// MAKE SURE THE SORT ORDER CHANGES AS MORE RESULTS ARE RETURNED BY ONE OR THE OTHER TRAVERSAL
Traversal.Admin<?, ?> traversal = __.match(as("a").out().as("b"), as("c").in().as("d")).asAdmin();
MatchStep.CountMatchAlgorithm countMatchAlgorithm = new MatchStep.CountMatchAlgorithm();
countMatchAlgorithm.initialize(false, ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren());
Traversal.Admin<Object, Object> firstPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(0);
Traversal.Admin<Object, Object> secondPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(1);
//
assertEquals(2, countMatchAlgorithm.bundles.size());
countMatchAlgorithm.bundles.stream().forEach(bundle -> assertEquals(0.0d, bundle.multiplicity, 0.0d));
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), firstPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), firstPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(firstPattern).traversalType);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(secondPattern).traversalType);
assertEquals(2l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
assertEquals(3l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
////
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
assertEquals(2l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
assertEquals(3l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
assertEquals(3l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
assertEquals(0.5d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
assertEquals(1.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
// CHECK RE-SORTING AS MORE DATA COMES IN
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
assertEquals(1.5d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
assertEquals(1.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(1).traversal);
/////// MAKE SURE WHERE PREDICATE TRAVERSALS ARE ALWAYS FIRST AS THEY ARE SIMPLY .hasNext() CHECKS
traversal = __.match(as("a").out().as("b"), as("c").in().as("d"), where("a", P.eq("b"))).asAdmin();
countMatchAlgorithm = new MatchStep.CountMatchAlgorithm();
countMatchAlgorithm.initialize(false, ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren());
assertEquals(3, countMatchAlgorithm.bundles.size());
firstPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(0);
secondPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(1);
Traversal.Admin<Object, Object> thirdPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(2);
///
countMatchAlgorithm.bundles.stream().forEach(bundle -> assertEquals(0.0d, bundle.multiplicity, 0.0d));
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(firstPattern).traversalType);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(secondPattern).traversalType);
assertEquals(MatchStep.TraversalType.WHERE_PREDICATE, countMatchAlgorithm.getBundle(thirdPattern).traversalType);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(2).traversal);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), firstPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), firstPattern);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(thirdPattern).startsCount);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(thirdPattern).endsCount);
assertEquals(1.0d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
assertEquals(0.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
assertEquals(0.0d, countMatchAlgorithm.getBundle(thirdPattern).multiplicity, 0.01d);
assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(2).traversal);
//
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
assertEquals(3l, countMatchAlgorithm.getBundle(thirdPattern).startsCount);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
assertEquals(0l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
assertEquals(6l, countMatchAlgorithm.getBundle(thirdPattern).endsCount);
assertEquals(1.0d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
assertEquals(0.0d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
assertEquals(2.0d, countMatchAlgorithm.getBundle(thirdPattern).multiplicity, 0.01d);
assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(2).traversal);
//
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).startsCount);
assertEquals(4l, countMatchAlgorithm.getBundle(secondPattern).startsCount);
assertEquals(3l, countMatchAlgorithm.getBundle(thirdPattern).startsCount);
assertEquals(1l, countMatchAlgorithm.getBundle(firstPattern).endsCount);
assertEquals(6l, countMatchAlgorithm.getBundle(secondPattern).endsCount);
assertEquals(6l, countMatchAlgorithm.getBundle(thirdPattern).endsCount);
assertEquals(1.0d, countMatchAlgorithm.getBundle(firstPattern).multiplicity, 0.01d);
assertEquals(1.5d, countMatchAlgorithm.getBundle(secondPattern).multiplicity, 0.01d);
assertEquals(2.0d, countMatchAlgorithm.getBundle(thirdPattern).multiplicity, 0.01d);
assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(1).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(2).traversal);
}
@Test
public void testComputerAwareCountMatchAlgorithm() {
// MAKE SURE OLAP JOBS ARE BIASED TOWARDS STAR GRAPH DATA
final Consumer doNothing = s -> {
};
final Traversal.Admin<?, ?> traversal = __.match(
as("a").sideEffect(doNothing).as("b"), // 1
as("b").sideEffect(doNothing).as("c"), // 2
as("a").sideEffect(doNothing).as("d"), // 5
as("c").sideEffect(doNothing).as("e"), // 4
as("c").sideEffect(doNothing).as("f")) // 3
.asAdmin();
traversal.applyStrategies(); // necessary to enure step ids are unique
final MatchStep.CountMatchAlgorithm countMatchAlgorithm = new MatchStep.CountMatchAlgorithm();
countMatchAlgorithm.initialize(true, ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren());
Traversal.Admin<Object, Object> firstPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(0);
Traversal.Admin<Object, Object> secondPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(1);
Traversal.Admin<Object, Object> thirdPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(2);
Traversal.Admin<Object, Object> forthPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(3);
Traversal.Admin<Object, Object> fifthPattern = ((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren().get(4);
countMatchAlgorithm.bundles.stream().forEach(bundle -> assertEquals(0.0d, bundle.multiplicity, 0.0d));
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(firstPattern).traversalType);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(secondPattern).traversalType);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(thirdPattern).traversalType);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(forthPattern).traversalType);
assertEquals(MatchStep.TraversalType.MATCH_TRAVERSAL, countMatchAlgorithm.getBundle(fifthPattern).traversalType);
assertEquals(firstPattern, countMatchAlgorithm.bundles.get(0).traversal);
assertEquals(secondPattern, countMatchAlgorithm.bundles.get(1).traversal);
assertEquals(thirdPattern, countMatchAlgorithm.bundles.get(2).traversal);
assertEquals(forthPattern, countMatchAlgorithm.bundles.get(3).traversal);
assertEquals(fifthPattern, countMatchAlgorithm.bundles.get(4).traversal);
// MAKE THE SECOND PATTERN EXPENSIVE
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), secondPattern);
// MAKE THE THIRD PATTERN MORE EXPENSIVE THAN FORTH
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), thirdPattern);
// MAKE THE FORTH PATTERN EXPENSIVE
countMatchAlgorithm.recordStart(EmptyTraverser.instance(), forthPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), forthPattern);
countMatchAlgorithm.recordEnd(EmptyTraverser.instance(), forthPattern);
//
Traverser.Admin traverser = B_LP_O_P_S_SE_SL_TraverserGenerator.instance().generate(1, EmptyStep.instance(), 1l);
traverser.addLabels(Collections.singleton("a"));
assertEquals(firstPattern, countMatchAlgorithm.apply(traverser));
traverser = traverser.split(1, EmptyStep.instance());
traverser.getTags().add(firstPattern.getStartStep().getId());
traverser.addLabels(Collections.singleton("b"));
//
assertEquals(secondPattern, countMatchAlgorithm.apply(traverser));
traverser = traverser.split(1, EmptyStep.instance());
traverser.getTags().add(secondPattern.getStartStep().getId());
traverser.addLabels(Collections.singleton("c"));
//
assertEquals(fifthPattern, countMatchAlgorithm.apply(traverser));
traverser = traverser.split(1, EmptyStep.instance());
traverser.getTags().add(fifthPattern.getStartStep().getId());
traverser.addLabels(Collections.singleton("f"));
//
assertEquals(forthPattern, countMatchAlgorithm.apply(traverser));
traverser = traverser.split(1, EmptyStep.instance());
traverser.getTags().add(forthPattern.getStartStep().getId());
traverser.addLabels(Collections.singleton("e"));
//
assertEquals(thirdPattern, countMatchAlgorithm.apply(traverser));
traverser = traverser.split(1, EmptyStep.instance());
traverser.getTags().add(thirdPattern.getStartStep().getId());
traverser.addLabels(Collections.singleton("d"));
}
@Test
public void shouldCalculateStartLabelCorrectly() {
Traversal.Admin<?, ?> traversal = match(
where(and(
as("a").out("created").as("b"),
as("b").in("created").count().is(eq(3)))),
as("a").both().as("b"),
where(as("b").in())).asAdmin();
assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren()));
/////
traversal = match(
where("a", P.neq("c")),
as("a").out("created").as("b"),
or(
as("a").out("knows").has("name", "vadas"),
as("a").in("knows").and().as("a").has(T.label, "person")
),
as("b").in("created").as("c"),
as("b").in("created").count().is(P.gt(1))).asAdmin();
assertEquals("a", MatchStep.Helper.computeStartLabel(((MatchStep<?, ?>) traversal.getStartStep()).getGlobalChildren()));
}
}