Esempio n. 1
0
        /// <summary>
        /// Tries to assign compound indexes to expressions if applicable...
        /// </summary>
        private static List <ProxyAndPredicate> AssignCompoundIndices(ProxyAndPredicate set,
                                                                      IEnumerable <IIndex> indexes, IQueryStore queryStore)
        {
            var attribExprList  = new OrderedList <string, ComparisonPredicate>();
            var proxyPredicates = new List <ProxyAndPredicate>();

            //For every expression in the set ready for assignment.
            foreach (var expresson in set.TreePredicates)
            {
                var expression = (ComparisonPredicate)expresson;
                if (expression.IsBinaryExpression)
                {
                    continue;
                }
                attribExprList.Add(expression.AttributeNames[0], expression);
            }

            //Each compound index will create a new state of the expression.
            foreach (var index in indexes)
            {
                int matchedNumber  = 0;
                var matchedAttribs = new List <string>();

                //If keys (attributes list) does not contain the first prefix of the index
                //Then the index is not usable.
                if (attribExprList.ContainsKey(index.Attributes.Name))
                {
                    matchedAttribs.Add(index.Attributes.Name);
                    matchedNumber += attribExprList[index.Attributes.Name].Count;
                }


                //if matched attributes are < 2 no need of compound assignment.
                if (matchedAttribs.Count < 2)
                {
                    continue;
                }

                //Assign each of them an index and get them to the predicate, and get the one with the lowest cost.
                ComparisonPredicate cheapestExpression = attribExprList[matchedAttribs[0]][0];
                IPredicate          cheapestPredicate  = cheapestExpression.AssignIndexPredicate(index, queryStore);
                for (int i = 1; i < attribExprList[matchedAttribs[0]].Count; i++)
                {
                    ComparisonPredicate tempExpression = attribExprList[matchedAttribs[0]][i];
                    IPredicate          tempPredicate  = tempExpression.AssignIndexPredicate(index, queryStore);

                    if (tempPredicate.Statistics[Statistic.ExpectedIO] <
                        cheapestPredicate.Statistics[Statistic.ExpectedIO])
                    {
                        cheapestExpression = tempExpression;
                        cheapestPredicate  = tempPredicate;
                    }
                }

                //For filteration and adding rest of expressions to the index.
                ITreePredicate assingedExpression = null;
                if (!matchedNumber.Equals(2))
                {
                    AndTreePredicate assingedAnd = new AndTreePredicate();
                    foreach (var attribute in matchedAttribs)
                    {
                        foreach (var expression in attribExprList[attribute])
                        {
                            if (expression != cheapestExpression)
                            {
                                assingedAnd.Add(expression);
                            }
                        }
                    }
                    assingedExpression = assingedAnd;
                }
                else
                {
                    foreach (var expression in attribExprList[matchedAttribs[1]])
                    {
                        assingedExpression = expression;
                    }
                }

                FilterPredicate filterPredicate = new FilterPredicate(assingedExpression, index);
                filterPredicate.AddChildPredicate(cheapestPredicate);
                ProxyAndPredicate proxyAnd = (ProxyAndPredicate)set.Clone();

                //Removing assigned expressions.
                foreach (var attribute in matchedAttribs)
                {
                    foreach (var expression in attribExprList[attribute])
                    {
                        proxyAnd.TreePredicates.Remove(expression);
                    }
                }

                proxyAnd.AddChildPredicate(new ProxyPredicate(filterPredicate, null));
                proxyPredicates.Add(proxyAnd);
            }

            foreach (var proxyAnd in proxyPredicates)
            {
                //Recursive call for each ProxyAndPredicate.
                if (proxyAnd.TreePredicates.Count > 1)
                {
                    var values = AssignCompoundIndices(proxyAnd, indexes, queryStore);
                    foreach (var value in values)
                    {
                        proxyPredicates.Add(value);
                    }
                }
            }
            return(proxyPredicates);
        }