public void TestComputeBestPath() { NStreamQueryPlanBuilder.BestChainResult bestChain = NStreamQueryPlanBuilder.ComputeBestPath(0, queryGraph, dependencyGraph); Assert.AreEqual(3, bestChain.Depth); Assert.IsTrue(Arrays.AreEqual(bestChain.Chain, new int[] { 2, 4, 3, 1 })); bestChain = NStreamQueryPlanBuilder.ComputeBestPath(3, queryGraph, dependencyGraph); Assert.AreEqual(4, bestChain.Depth); Assert.IsTrue(Arrays.AreEqual(bestChain.Chain, new int[] { 4, 2, 0, 1 })); // try a stream that is not connected in any way queryGraph = new QueryGraphForge(6, null, false); bestChain = NStreamQueryPlanBuilder.ComputeBestPath(5, queryGraph, dependencyGraph); log.Debug(".testComputeBestPath bestChain=" + bestChain); Assert.AreEqual(0, bestChain.Depth); Assert.IsTrue(Arrays.AreEqual(bestChain.Chain, new int[] { 0, 1, 2, 3, 4 })); }
private static QueryPlanNodeForgeDesc BuildPlanNode( int numStreams, int streamNo, string[] streamNames, QueryGraphForge queryGraph, OuterInnerDirectionalGraph outerInnerGraph, OuterJoinDesc[] outerJoinDescList, InnerJoinGraph innerJoinGraph, QueryPlanIndexForge[] indexSpecs, EventType[] typesPerStream, bool[] isHistorical, DependencyGraph dependencyGraph, HistoricalStreamIndexListForge[] historicalStreamIndexLists, TableMetaData[] tablesPerStream, StreamJoinAnalysisResultCompileTime streamJoinAnalysisResult, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { // For each stream build an array of substreams, considering required streams (inner joins) first // The order is relevant therefore preserving order via a LinkedHashMap. var substreamsPerStream = new LinkedHashMap<int, int[]>(); var requiredPerStream = new bool[numStreams]; var additionalForgeables = new List<StmtClassForgeableFactory>(); // Recursive populating the required (outer) and optional (inner) relationships // of this stream and the substream ISet<int> completedStreams = new HashSet<int>(); // keep track of tree path as only those stream events are always available to historical streams var streamCallStack = new Stack<int>(); streamCallStack.Push(streamNo); // For all inner-joins, the algorithm is slightly different if (innerJoinGraph.IsAllInnerJoin) { requiredPerStream.Fill(true); RecursiveBuildInnerJoin( streamNo, streamCallStack, queryGraph, completedStreams, substreamsPerStream, dependencyGraph); // compute a best chain to see if all streams are handled and add the remaining var bestChain = NStreamQueryPlanBuilder.ComputeBestPath(streamNo, queryGraph, dependencyGraph); AddNotYetNavigated(streamNo, numStreams, substreamsPerStream, bestChain); } else { RecursiveBuild( streamNo, streamCallStack, queryGraph, outerInnerGraph, innerJoinGraph, completedStreams, substreamsPerStream, requiredPerStream, dependencyGraph); } // verify the substreamsPerStream, all streams must exists and be linked VerifyJoinedPerStream(streamNo, substreamsPerStream); // build list of instructions for lookup LookupInstructionPlanDesc lookupDesc = BuildLookupInstructions( streamNo, substreamsPerStream, requiredPerStream, streamNames, queryGraph, indexSpecs, typesPerStream, outerJoinDescList, isHistorical, historicalStreamIndexLists, tablesPerStream, streamJoinAnalysisResult, statementRawInfo, services); var lookupInstructions = lookupDesc.Forges; additionalForgeables.AddAll(lookupDesc.AdditionalForgeables); // build historical index and lookup strategies foreach (var lookups in lookupInstructions) { foreach (var historical in lookups.HistoricalPlans) { if (historical == null) { continue; } JoinSetComposerPrototypeHistoricalDesc desc = historicalStreamIndexLists[historical.StreamNum] .GetStrategy(historical.LookupStreamNum, statementRawInfo, services.SerdeResolver); historical.HistoricalIndexLookupStrategy = desc.LookupForge; historical.PollResultIndexingStrategy = desc.IndexingForge; additionalForgeables.AddAll(desc.AdditionalForgeables); } } // build strategy tree for putting the result back together var assemblyTopNodeFactory = AssemblyStrategyTreeBuilder.Build( streamNo, substreamsPerStream, requiredPerStream); var assemblyInstructionFactories = BaseAssemblyNodeFactory.GetDescendentNodesBottomUp(assemblyTopNodeFactory); var forge = new LookupInstructionQueryPlanNodeForge( streamNo, streamNames[streamNo], numStreams, requiredPerStream, lookupInstructions, assemblyInstructionFactories); return new QueryPlanNodeForgeDesc(forge, additionalForgeables); }