Esempio n. 1
0
        private static QueryPlanNode BuildPlanNode(
            int numStreams,
            int streamNo,
            string[] streamNames,
            QueryGraph queryGraph,
            OuterInnerDirectionalGraph outerInnerGraph,
            OuterJoinDesc[] outerJoinDescList,
            InnerJoinGraph innerJoinGraph,
            QueryPlanIndex[] indexSpecs,
            EventType[] typesPerStream,
            bool[] ishistorical,
            DependencyGraph dependencyGraph,
            HistoricalStreamIndexList[] historicalStreamIndexLists,
            ExprEvaluatorContext exprEvaluatorContext,
            TableMetadata[] tablesPerStream)
        {
            // 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];

            // 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
            var lookupInstructions = BuildLookupInstructions(streamNo, substreamsPerStream, requiredPerStream,
                                                             streamNames, queryGraph, indexSpecs, typesPerStream, outerJoinDescList, ishistorical, historicalStreamIndexLists, exprEvaluatorContext, tablesPerStream);

            // build strategy tree for putting the result back together
            var assemblyTopNodeFactory       = AssemblyStrategyTreeBuilder.Build(streamNo, substreamsPerStream, requiredPerStream);
            var assemblyInstructionFactories = BaseAssemblyNodeFactory.GetDescendentNodesBottomUp(assemblyTopNodeFactory);

            return(new LookupInstructionQueryPlanNode(streamNo, streamNames[streamNo], numStreams, requiredPerStream,
                                                      lookupInstructions, assemblyInstructionFactories));
        }
        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);
        }