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; }
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; }