private static IList<FilterSpecParamForge>[] PlanRemainingNodesIfFeasible( FilterSpecParaForgeMap 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); } } FilterSpecParaForgeMap expressionsWithoutOr = new FilterSpecParaForgeMap(); expressionsWithoutOr.Add(overallExpressions); // first dimension: or-node index // second dimension: or child node index FilterSpecParaForgeMap[][] orNodesMaps = new FilterSpecParaForgeMap[orNodes.Count][]; int countOr = 0; int sizeFactorized = 1; int[] sizePerOr = new int[orNodes.Count]; foreach (ExprOrNode orNode in orNodes) { expressionsWithoutOr.RemoveNode(orNode); orNodesMaps[countOr] = new FilterSpecParaForgeMap[orNode.ChildNodes.Length]; int len = orNode.ChildNodes.Length; for (int i = 0; i < len; i++) { FilterSpecParaForgeMap map = new FilterSpecParaForgeMap(); 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 IList<FilterSpecParamForge>[] result = new IList<FilterSpecParamForge>[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; }
internal static FilterSpecPlanForge PlanRemainingNodesBasic( FilterSpecParaForgeMap overallExpressions, FilterSpecCompilerArgs args, int filterServiceMaxFilterWidth) { var unassigned = overallExpressions.UnassignedExpressions; IList<ExprOrNode> orNodes = new List<ExprOrNode>(unassigned.Count); foreach (var node in unassigned) { if (node is ExprOrNode) { orNodes.Add((ExprOrNode) node); } } var expressionsWithoutOr = new FilterSpecParaForgeMap(); expressionsWithoutOr.Add(overallExpressions); // first dimension: or-node index // second dimension: or child node index var orNodesMaps = new FilterSpecParaForgeMap[orNodes.Count][]; var countOr = 0; var sizeFactorized = 1; var sizePerOr = new int[orNodes.Count]; foreach (var orNode in orNodes) { expressionsWithoutOr.RemoveNode(orNode); orNodesMaps[countOr] = new FilterSpecParaForgeMap[orNode.ChildNodes.Length]; var len = orNode.ChildNodes.Length; for (var i = 0; i < len; i++) { var map = new FilterSpecParaForgeMap(); orNodesMaps[countOr][i] = map; var nodes = Collections.SingletonList(orNode.ChildNodes[i]); DecomposePopulateConsolidate(map, false, nodes, args); } sizePerOr[countOr] = len; sizeFactorized = sizeFactorized * len; countOr++; } // we become too large if (sizeFactorized > filterServiceMaxFilterWidth) { return null; } // combine var result = new FilterSpecPlanPathForge[sizeFactorized]; var count = 0; foreach (var permutation in CombinationEnumeration.FromZeroBasedRanges(sizePerOr)) { result[count] = ComputePermutation(expressionsWithoutOr, permutation, orNodesMaps, args); count++; } return new FilterSpecPlanForge(result, null, null, null); }
internal static FilterSpecPlanForge PlanRemainingNodesWithConditions( FilterSpecParaForgeMap overallExpressions, FilterSpecCompilerArgs args, int filterServiceMaxFilterWidth, ExprNode topLevelNegator) { var unassigned = overallExpressions.UnassignedExpressions; var orNodes = new List <ExprOrNode>(unassigned.Count); foreach (var node in unassigned) { if (node is ExprOrNode) { orNodes.Add((ExprOrNode)node); } } var expressionsWithoutOr = new FilterSpecParaForgeMap(); expressionsWithoutOr.Add(overallExpressions); // first dimension: or-node index // second dimension: or child node index var countOr = 0; var sizeFactorized = 1; var sizePerOr = new int[orNodes.Count]; var orChildNodes = new OrChildNode[orNodes.Count][]; var hasControl = false; foreach (var orNode in orNodes) { expressionsWithoutOr.RemoveNode(orNode); // get value-nodes and non-value nodes var nonValueNodes = GetNonValueChildNodes(orNode); var valueNodes = new List <ExprNode>(Arrays.AsList(orNode.ChildNodes)); valueNodes.RemoveAll(nonValueNodes); ExprNode singleValueNode = ExprNodeUtilityMake.ConnectExpressionsByLogicalOrWhenNeeded(valueNodes); // get all child nodes; last one is confirm if present IList <ExprNode> allChildNodes = new List <ExprNode>(nonValueNodes); if (singleValueNode != null) { allChildNodes.Add(singleValueNode); } var len = allChildNodes.Count; orChildNodes[countOr] = new OrChildNode[len]; for (var i = 0; i < len; i++) { var child = allChildNodes[i]; if (child == singleValueNode) { hasControl = true; orChildNodes[countOr][i] = new OrChildNodeV(singleValueNode); } else { var map = new FilterSpecParaForgeMap(); var nodes = Collections.SingletonList(child); var confirm = DecomposePopulateConsolidate(map, true, nodes, args); if (confirm == null) { orChildNodes[countOr][i] = new OrChildNodeNV(child, map); } else { hasControl = true; orChildNodes[countOr][i] = new OrChildNodeNVNegated(child, map, confirm); } } } sizePerOr[countOr] = len; sizeFactorized = sizeFactorized * len; countOr++; } // compute permutations var permutations = new CombPermutationTriplets[sizeFactorized]; var combinationEnumeration = CombinationEnumeration.FromZeroBasedRanges(sizePerOr); var count = 0; foreach (var permutation in combinationEnumeration) { permutations[count] = ComputePermutation(expressionsWithoutOr, permutation, orChildNodes, hasControl, args); count++; } // Remove any permutations that only have a control-confirm var result = new List <FilterSpecPlanPathForge>(sizeFactorized); var pathControlConfirm = new List <ExprNode>(); foreach (var permutation in permutations) { if (permutation.Triplets.Length > 0) { result.Add(new FilterSpecPlanPathForge(permutation.Triplets, permutation.NegateCondition)); } else { pathControlConfirm.Add(permutation.NegateCondition); } } if (result.Count > filterServiceMaxFilterWidth) { return(null); } var pathArray = result.ToArray(); ExprNode topLevelConfirmer = ExprNodeUtilityMake.ConnectExpressionsByLogicalOrWhenNeeded(pathControlConfirm); // determine when the path-negate condition is the same as the root confirm-expression if (topLevelConfirmer != null) { var not = new ExprNotNode(); not.AddChildNode(topLevelConfirmer); foreach (var path in pathArray) { if (ExprNodeUtilityCompare.DeepEquals(not, path.PathNegate, true)) { path.PathNegate = null; } } } var convertor = new MatchedEventConvertorForge( args.taggedEventTypes, args.arrayEventTypes, args.allTagNamesOrdered, null, true); return(new FilterSpecPlanForge(pathArray, topLevelConfirmer, topLevelNegator, convertor)); }