示例#1
0
        private static IList<FilterSpecParam> ComputePermutation(
            FilterParamExprMap filterParamExprMap,
            object[] permutation,
            FilterParamExprMap[][] orNodesMaps,
            FilterSpecCompilerArgs args)
        {
            var mapAll = new FilterParamExprMap();
            mapAll.Add(filterParamExprMap);

            // combine
            for (int orNodeNum = 0; orNodeNum < permutation.Length; orNodeNum++)
            {
                var orChildNodeNum = permutation[orNodeNum].AsInt();
                FilterParamExprMap mapOrSub = orNodesMaps[orNodeNum][orChildNodeNum];
                mapAll.Add(mapOrSub);
            }

            // consolidate across
            FilterSpecCompilerConsolidateUtil.Consolidate(mapAll, args.StatementName);

            IList<FilterSpecParam> filterParams = new List<FilterSpecParam>();
            filterParams.AddAll(mapAll.FilterParams);
            int countUnassigned = mapAll.CountUnassignedExpressions();

            if (countUnassigned == 0)
            {
                return filterParams;
            }

            FilterSpecParamExprNode node = MakeRemainingNode(mapAll.UnassignedExpressions, args);
            filterParams.Add(node);
            return filterParams;
        }
示例#2
0
        internal static IList<FilterSpecParam>[] PlanFilterParameters(
            IList<ExprNode> validatedNodes,
            FilterSpecCompilerArgs args)
        {
            if (validatedNodes.IsEmpty())
            {
                return AllocateListArray(0);
            }

            var filterParamExprMap = new FilterParamExprMap();

            // Make filter parameter for each expression node, if it can be optimized
            DecomposePopulateConsolidate(filterParamExprMap, validatedNodes, args);

            // Use all filter parameter and unassigned expressions
            IList<FilterSpecParam> filterParams = new List<FilterSpecParam>();
            filterParams.AddAll(filterParamExprMap.FilterParams);
            int countUnassigned = filterParamExprMap.CountUnassignedExpressions();

            // we are done if there are no remaining nodes
            if (countUnassigned == 0)
            {
                return AllocateListArraySizeOne(filterParams);
            }

            // determine max-width
            int filterServiceMaxFilterWidth =
                args.ConfigurationInformation.EngineDefaults.ExecutionConfig.FilterServiceMaxFilterWidth;
            HintAttribute hint = HintEnum.MAX_FILTER_WIDTH.GetHint(args.Annotations);
            if (hint != null)
            {
                string hintValue = HintEnum.MAX_FILTER_WIDTH.GetHintAssignedValue(hint);
                filterServiceMaxFilterWidth = int.Parse(hintValue);
            }

            IList<FilterSpecParam>[] plan = null;
            if (filterServiceMaxFilterWidth > 0)
            {
                plan = PlanRemainingNodesIfFeasible(filterParamExprMap, args, filterServiceMaxFilterWidth);
            }

            if (plan != null)
            {
                return plan;
            }

            // handle no-plan
            FilterSpecParamExprNode node = MakeRemainingNode(filterParamExprMap.UnassignedExpressions, args);
            filterParams.Add(node);
            return AllocateListArraySizeOne(filterParams);
        }
示例#3
0
        // remove duplicate propertyName + filterOperator items making a judgement to optimize or simply remove the optimized form
        private static void Consolidate(IList <FilterSpecParam> items, FilterParamExprMap filterParamExprMap, string statementName)
        {
            var op = items[0].FilterOperator;

            if (op == FilterOperator.NOT_EQUAL)
            {
                HandleConsolidateNotEqual(items, filterParamExprMap, statementName);
            }
            else
            {
                // for all others we simple remove the second optimized form (filter param with same prop name and filter op)
                // and thus the boolean expression that started this is included
                for (var i = 1; i < items.Count; i++)
                {
                    filterParamExprMap.RemoveValue(items[i]);
                }
            }
        }
示例#4
0
        public static void Consolidate(FilterParamExprMap filterParamExprMap, string statementName)
        {
            // consolidate or place in a boolean expression (by removing filter spec param from the map)
            // any filter parameter that feature the same property name and filter operator,
            // i.e. we are looking for "a!=5 and a!=6"  to transform to "a not in (5,6)" which can match faster
            // considering that "a not in (5,6) and a not in (7,8)" is "a not in (5, 6, 7, 8)" therefore
            // we need to consolidate until there is no more work to do
            IDictionary <Pair <FilterSpecLookupable, FilterOperator>, IList <FilterSpecParam> > mapOfParams = new Dictionary <Pair <FilterSpecLookupable, FilterOperator>, IList <FilterSpecParam> >();

            bool haveConsolidated;

            do
            {
                haveConsolidated = false;
                mapOfParams.Clear();

                // sort into buckets of propertyName + filterOperator combination
                foreach (var currentParam in filterParamExprMap.FilterParams)
                {
                    var lookupable = currentParam.Lookupable;
                    var op         = currentParam.FilterOperator;
                    var key        = new Pair <FilterSpecLookupable, FilterOperator>(lookupable, op);

                    var existingParam = mapOfParams.Get(key);
                    if (existingParam == null)
                    {
                        existingParam = new List <FilterSpecParam>();
                        mapOfParams.Put(key, existingParam);
                    }
                    existingParam.Add(currentParam);
                }

                foreach (var entry in mapOfParams.Values)
                {
                    if (entry.Count > 1)
                    {
                        haveConsolidated = true;
                        Consolidate(entry, filterParamExprMap, statementName);
                    }
                }
            }while(haveConsolidated);
        }
示例#5
0
        private static void DecomposePopulateConsolidate(
            FilterParamExprMap filterParamExprMap,
            IList<ExprNode> validatedNodes,
            FilterSpecCompilerArgs args)

        {
            IList<ExprNode> constituents = DecomposeCheckAggregation(validatedNodes);

            // Make filter parameter for each expression node, if it can be optimized
            foreach (ExprNode constituent in constituents)
            {
                FilterSpecParam param = FilterSpecCompilerMakeParamUtil.MakeFilterParam(
                    constituent, args.ArrayEventTypes, args.ExprEvaluatorContext, args.StatementName);
                filterParamExprMap.Put(constituent, param);
                    // accepts null values as the expression may not be optimized
            }

            // Consolidate entries as possible, i.e. (a != 5 and a != 6) is (a not in (5,6))
            // Removes duplicates for same property and same filter operator for filter service index optimizations
            FilterSpecCompilerConsolidateUtil.Consolidate(filterParamExprMap, args.StatementName);
        }
示例#6
0
        // consolidate "val != 3 and val != 4 and val != 5"
        // to "val not in (3, 4, 5)"
        private static void HandleConsolidateNotEqual(IList <FilterSpecParam> parameters, FilterParamExprMap filterParamExprMap, string statementName)
        {
            IList <FilterSpecParamInValue> values = new List <FilterSpecParamInValue>();

            ExprNode lastNotEqualsExprNode = null;

            foreach (var param in parameters)
            {
                if (param is FilterSpecParamConstant)
                {
                    var constantParam = (FilterSpecParamConstant)param;
                    var constant      = constantParam.FilterConstant;
                    values.Add(new InSetOfValuesConstant(constant));
                }
                else if (param is FilterSpecParamEventProp)
                {
                    var eventProp = (FilterSpecParamEventProp)param;
                    values.Add(new InSetOfValuesEventProp(eventProp.ResultEventAsName, eventProp.ResultEventProperty,
                                                          eventProp.IsMustCoerce, TypeHelper.GetBoxedType(eventProp.CoercionType)));
                }
                else if (param is FilterSpecParamEventPropIndexed)
                {
                    var eventProp = (FilterSpecParamEventPropIndexed)param;
                    values.Add(new InSetOfValuesEventPropIndexed(eventProp.ResultEventAsName, eventProp.ResultEventIndex, eventProp.ResultEventProperty,
                                                                 eventProp.IsMustCoerce, TypeHelper.GetBoxedType(eventProp.CoercionType), statementName));
                }
                else
                {
                    throw new ArgumentException("Unknown filter parameter:" + param.ToString());
                }

                lastNotEqualsExprNode = filterParamExprMap.RemoveEntry(param);
            }

            var paramIn = new FilterSpecParamIn(parameters[0].Lookupable, FilterOperator.NOT_IN_LIST_OF_VALUES, values);

            filterParamExprMap.Put(lastNotEqualsExprNode, paramIn);
        }
示例#7
0
        private static IList<FilterSpecParam>[] PlanRemainingNodesIfFeasible(
            FilterParamExprMap overallExpressions,
            FilterSpecCompilerArgs args,
            int filterServiceMaxFilterWidth)

        {
            IList<ExprNode> unassigned = overallExpressions.UnassignedExpressions;
            IList<ExprOrNode> orNodes = new List<ExprOrNode>(unassigned.Count);

            foreach (ExprNode node in unassigned)
            {
                if (node is ExprOrNode)
                {
                    orNodes.Add((ExprOrNode) node);
                }
            }

            var expressionsWithoutOr = new FilterParamExprMap();
            expressionsWithoutOr.Add(overallExpressions);

            // first dimension: or-node index
            // second dimension: or child node index
            var orNodesMaps = new FilterParamExprMap[orNodes.Count][];
            int countOr = 0;
            int sizeFactorized = 1;
            var sizePerOr = new int[orNodes.Count];
            foreach (ExprOrNode orNode in orNodes)
            {
                expressionsWithoutOr.RemoveNode(orNode);
                orNodesMaps[countOr] = new FilterParamExprMap[orNode.ChildNodes.Length];
                int len = orNode.ChildNodes.Length;

                for (int i = 0; i < len; i++)
                {
                    var map = new FilterParamExprMap();
                    orNodesMaps[countOr][i] = map;
                    IList<ExprNode> nodes = Collections.SingletonList(orNode.ChildNodes[i]);
                    DecomposePopulateConsolidate(map, nodes, args);
                }

                sizePerOr[countOr] = len;
                sizeFactorized = sizeFactorized*len;
                countOr++;
            }

            // we become too large
            if (sizeFactorized > filterServiceMaxFilterWidth)
            {
                return null;
            }

            // combine
            var result = new IList<FilterSpecParam>[sizeFactorized];
            IEnumerable<object[]> permutations = CombinationEnumeration.FromZeroBasedRanges(sizePerOr);
            int count = 0;
            foreach (var permutation in permutations)
            {
                result[count] = ComputePermutation(expressionsWithoutOr, permutation, orNodesMaps, args);
                count++;
            }
            return result;
        }
示例#8
0
 public void Add(FilterParamExprMap other)
 {
     _exprNodes.PutAll(other._exprNodes);
     _specParams.PutAll(other._specParams);
 }