/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.epl.join.plan;
import com.espertech.esper.client.EventType;
import com.espertech.esper.core.support.SupportEventAdapterService;
import com.espertech.esper.epl.expression.core.ExprIdentNode;
import com.espertech.esper.epl.expression.core.ExprIdentNodeImpl;
import com.espertech.esper.epl.join.base.HistoricalViewableDesc;
import com.espertech.esper.epl.table.mgmt.TableMetadata;
import com.espertech.esper.supportunit.bean.*;
import com.espertech.esper.util.DependencyGraph;
import junit.framework.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
public class TestNStreamQueryPlanBuilder extends TestCase {
private EventType[] typesPerStream;
private QueryGraph queryGraph;
private DependencyGraph dependencyGraph;
public void setUp() {
typesPerStream = new EventType[]{
SupportEventAdapterService.getService().addBeanType(SupportBean_S0.class.getName(), SupportBean_S0.class, true, true, true),
SupportEventAdapterService.getService().addBeanType(SupportBean_S1.class.getName(), SupportBean_S1.class, true, true, true),
SupportEventAdapterService.getService().addBeanType(SupportBean_S2.class.getName(), SupportBean_S2.class, true, true, true),
SupportEventAdapterService.getService().addBeanType(SupportBean_S3.class.getName(), SupportBean_S3.class, true, true, true),
SupportEventAdapterService.getService().addBeanType(SupportBean_S4.class.getName(), SupportBean_S4.class, true, true, true)
};
queryGraph = new QueryGraph(5, null, false);
queryGraph.addStrictEquals(0, "p00", make(0, "p00"), 1, "p10", make(1, "p10"));
queryGraph.addStrictEquals(0, "p01", make(0, "p01"), 2, "p20", make(2, "p20"));
queryGraph.addStrictEquals(4, "p40", make(4, "p40"), 3, "p30", make(3, "p30"));
queryGraph.addStrictEquals(4, "p41", make(4, "p41"), 3, "p31", make(3, "p31"));
queryGraph.addStrictEquals(4, "p42", make(4, "p42"), 2, "p21", make(2, "p21"));
dependencyGraph = new DependencyGraph(5, false);
}
public void testBuild() {
QueryPlan plan = NStreamQueryPlanBuilder.build(queryGraph, typesPerStream, new HistoricalViewableDesc(6), dependencyGraph, null, false, new String[queryGraph.getNumStreams()][][], new TableMetadata[queryGraph.getNumStreams()]);
log.debug(".testBuild plan=" + plan);
}
public void testCreateStreamPlan() {
QueryPlanIndex[] indexes = QueryPlanIndexBuilder.buildIndexSpec(queryGraph, typesPerStream, new String[queryGraph.getNumStreams()][][]);
for (int i = 0; i < indexes.length; i++) {
log.debug(".testCreateStreamPlan index " + i + " = " + indexes[i]);
}
QueryPlanNode plan = NStreamQueryPlanBuilder.createStreamPlan(0, new int[]{2, 4, 3, 1}, queryGraph, indexes, typesPerStream, new boolean[5], null, new TableMetadata[queryGraph.getNumStreams()]);
log.debug(".testCreateStreamPlan plan=" + plan);
assertTrue(plan instanceof NestedIterationNode);
NestedIterationNode nested = (NestedIterationNode) plan;
TableLookupNode tableLookupSpec = (TableLookupNode) nested.getChildNodes().get(0);
// Check lookup strategy for first lookup
IndexedTableLookupPlanSingle lookupStrategySpec = (IndexedTableLookupPlanSingle) tableLookupSpec.getLookupStrategySpec();
assertEquals("p01", ((QueryGraphValueEntryHashKeyedProp) lookupStrategySpec.getHashKey()).getKeyProperty());
assertEquals(0, lookupStrategySpec.getLookupStream());
assertEquals(2, lookupStrategySpec.getIndexedStream());
assertNotNull(lookupStrategySpec.getIndexNum());
// Check lookup strategy for last lookup
tableLookupSpec = (TableLookupNode) nested.getChildNodes().get(3);
FullTableScanLookupPlan unkeyedSpecScan = (FullTableScanLookupPlan) tableLookupSpec.getLookupStrategySpec();
assertEquals(1, unkeyedSpecScan.getIndexedStream());
assertNotNull(unkeyedSpecScan.getIndexNum());
}
public void testComputeBestPath() {
NStreamQueryPlanBuilder.BestChainResult bestChain = NStreamQueryPlanBuilder.computeBestPath(0, queryGraph, dependencyGraph);
assertEquals(3, bestChain.getDepth());
assertTrue(Arrays.equals(bestChain.getChain(), new int[]{2, 4, 3, 1}));
bestChain = NStreamQueryPlanBuilder.computeBestPath(3, queryGraph, dependencyGraph);
assertEquals(4, bestChain.getDepth());
assertTrue(Arrays.equals(bestChain.getChain(), new int[]{4, 2, 0, 1}));
// try a stream that is not connected in any way
queryGraph = new QueryGraph(6, null, false);
bestChain = NStreamQueryPlanBuilder.computeBestPath(5, queryGraph, dependencyGraph);
log.debug(".testComputeBestPath bestChain=" + bestChain);
assertEquals(0, bestChain.getDepth());
assertTrue(Arrays.equals(bestChain.getChain(), new int[]{0, 1, 2, 3, 4}));
}
public void testComputeNavigableDepth() {
queryGraph.addStrictEquals(3, "p30", null, 2, "p20", null);
queryGraph.addStrictEquals(2, "p30", null, 1, "p20", null);
int depth = NStreamQueryPlanBuilder.computeNavigableDepth(0, new int[]{1, 2, 3, 4}, queryGraph);
assertEquals(4, depth);
depth = NStreamQueryPlanBuilder.computeNavigableDepth(0, new int[]{4, 2, 3, 1}, queryGraph);
assertEquals(0, depth);
depth = NStreamQueryPlanBuilder.computeNavigableDepth(4, new int[]{3, 2, 1, 0}, queryGraph);
assertEquals(4, depth);
depth = NStreamQueryPlanBuilder.computeNavigableDepth(1, new int[]{0, 3, 4, 2}, queryGraph);
assertEquals(1, depth);
}
public void testBuildDefaultNestingOrder() {
int[] result = NStreamQueryPlanBuilder.buildDefaultNestingOrder(4, 0);
assertTrue(Arrays.equals(result, new int[]{1, 2, 3}));
result = NStreamQueryPlanBuilder.buildDefaultNestingOrder(4, 1);
assertTrue(Arrays.equals(result, new int[]{0, 2, 3}));
result = NStreamQueryPlanBuilder.buildDefaultNestingOrder(4, 2);
assertTrue(Arrays.equals(result, new int[]{0, 1, 3}));
result = NStreamQueryPlanBuilder.buildDefaultNestingOrder(4, 3);
assertTrue(Arrays.equals(result, new int[]{0, 1, 2}));
}
public void testIsDependencySatisfied() {
DependencyGraph graph = new DependencyGraph(3, false);
graph.addDependency(1, 0);
graph.addDependency(2, 0);
assertTrue(NStreamQueryPlanBuilder.isDependencySatisfied(0, new int[]{1, 2}, graph));
assertFalse(NStreamQueryPlanBuilder.isDependencySatisfied(1, new int[]{0, 2}, graph));
assertFalse(NStreamQueryPlanBuilder.isDependencySatisfied(2, new int[]{0, 1}, graph));
graph = new DependencyGraph(5, false);
graph.addDependency(4, 1);
graph.addDependency(4, 2);
graph.addDependency(2, 0);
assertTrue(NStreamQueryPlanBuilder.isDependencySatisfied(0, new int[]{1, 2, 3, 4}, graph));
assertTrue(NStreamQueryPlanBuilder.isDependencySatisfied(1, new int[]{0, 2, 3, 4}, graph));
assertFalse(NStreamQueryPlanBuilder.isDependencySatisfied(1, new int[]{2, 0, 3, 4}, graph));
assertFalse(NStreamQueryPlanBuilder.isDependencySatisfied(1, new int[]{4, 0, 3, 2}, graph));
assertFalse(NStreamQueryPlanBuilder.isDependencySatisfied(3, new int[]{4, 0, 1, 2}, graph));
assertFalse(NStreamQueryPlanBuilder.isDependencySatisfied(2, new int[]{3, 1, 4, 0}, graph));
assertTrue(NStreamQueryPlanBuilder.isDependencySatisfied(3, new int[]{1, 0, 2, 4}, graph));
}
private ExprIdentNode make(int stream, String p) {
return new ExprIdentNodeImpl(typesPerStream[stream], p, stream);
}
private final static Logger log = LoggerFactory.getLogger(TestNStreamQueryPlanBuilder.class);
}