Ejemplo n.º 1
0
        /// <summary>
        /// Walks the chain of lookups and constructs lookup strategy and plan specification based
        /// on the index specifications.
        /// </summary>
        /// <param name="lookupStream">the stream to construct the query plan for</param>
        /// <param name="bestChain">the chain that the lookup follows to make best use of indexes</param>
        /// <param name="queryGraph">the repository for key properties to indexes</param>
        /// <param name="indexSpecsPerStream">specifications of indexes</param>
        /// <param name="typesPerStream">event types for each stream</param>
        /// <param name="isHistorical">indicator for each stream if it is a historical streams or not</param>
        /// <param name="historicalStreamIndexLists">index management, populated for the query plan</param>
        /// <returns>NestedIterationNode with lookups attached underneath</returns>
        internal static QueryPlanNode CreateStreamPlan(
            int lookupStream,
            int[] bestChain,
            QueryGraph queryGraph,
            QueryPlanIndex[] indexSpecsPerStream,
            EventType[] typesPerStream,
            bool[] isHistorical,
            HistoricalStreamIndexList[] historicalStreamIndexLists,
            TableMetadata[] tablesPerStream)
        {
            var nestedIterNode      = new NestedIterationNode(bestChain);
            var currentLookupStream = lookupStream;

            // Walk through each successive lookup
            for (var i = 0; i < bestChain.Length; i++)
            {
                var indexedStream = bestChain[i];

                QueryPlanNode node;
                if (isHistorical[indexedStream])
                {
                    if (historicalStreamIndexLists[indexedStream] == null)
                    {
                        historicalStreamIndexLists[indexedStream] = new HistoricalStreamIndexList(indexedStream, typesPerStream, queryGraph);
                    }
                    historicalStreamIndexLists[indexedStream].AddIndex(currentLookupStream);
                    node = new HistoricalDataPlanNode(indexedStream, lookupStream, currentLookupStream, typesPerStream.Length, null);
                }
                else
                {
                    var tableLookupPlan = CreateLookupPlan(queryGraph, currentLookupStream, indexedStream, indexSpecsPerStream[indexedStream], typesPerStream, tablesPerStream[indexedStream]);
                    node = new TableLookupNode(tableLookupPlan);
                }
                nestedIterNode.AddChildNode(node);

                currentLookupStream = bestChain[i];
            }

            return(nestedIterNode);
        }
Ejemplo n.º 2
0
        private static IList <LookupInstructionPlan> BuildLookupInstructions(
            int rootStreamNum,
            LinkedHashMap <int, int[]> substreamsPerStream,
            bool[] requiredPerStream,
            string[] streamNames,
            QueryGraph queryGraph,
            QueryPlanIndex[] indexSpecs,
            EventType[] typesPerStream,
            OuterJoinDesc[] outerJoinDescList,
            bool[] isHistorical,
            HistoricalStreamIndexList[] historicalStreamIndexLists,
            ExprEvaluatorContext exprEvaluatorContext,
            TableMetadata[] tablesPerStream)
        {
            IList <LookupInstructionPlan> result = new List <LookupInstructionPlan>();

            foreach (int fromStream in substreamsPerStream.Keys)
            {
                var substreams = substreamsPerStream.Get(fromStream);

                // for streams with no substreams we don't need to look up
                if (substreams.Length == 0)
                {
                    continue;
                }

                var plans           = new TableLookupPlan[substreams.Length];
                var historicalPlans = new HistoricalDataPlanNode[substreams.Length];

                for (var i = 0; i < substreams.Length; i++)
                {
                    var toStream = substreams[i];

                    if (isHistorical[toStream])
                    {
                        // There may not be an outer-join descriptor, use if provided to build the associated expression
                        ExprNode outerJoinExpr = null;
                        if (outerJoinDescList.Length > 0)
                        {
                            OuterJoinDesc outerJoinDesc;
                            if (toStream == 0)
                            {
                                outerJoinDesc = outerJoinDescList[0];
                            }
                            else
                            {
                                outerJoinDesc = outerJoinDescList[toStream - 1];
                            }
                            outerJoinExpr = outerJoinDesc.MakeExprNode(exprEvaluatorContext);
                        }

                        if (historicalStreamIndexLists[toStream] == null)
                        {
                            historicalStreamIndexLists[toStream] = new HistoricalStreamIndexList(toStream, typesPerStream, queryGraph);
                        }
                        historicalStreamIndexLists[toStream].AddIndex(fromStream);
                        historicalPlans[i] = new HistoricalDataPlanNode(toStream, rootStreamNum, fromStream, typesPerStream.Length, outerJoinExpr);
                    }
                    else
                    {
                        plans[i] = NStreamQueryPlanBuilder.CreateLookupPlan(queryGraph, fromStream, toStream, indexSpecs[toStream], typesPerStream, tablesPerStream[toStream]);
                    }
                }

                var fromStreamName = streamNames[fromStream];
                var instruction    = new LookupInstructionPlan(fromStream, fromStreamName, substreams, plans, historicalPlans, requiredPerStream);
                result.Add(instruction);
            }

            return(result);
        }