public static void CostDecreaseForLeavingInlinedIndependent(SearchPlanEdge planEdge) { // considerably lower the costs for operations leaving the inlined independent part, so this is done early if(planEdge.Target is SearchPlanEdgeNode) // we may leave the independent part only with an edge { if(planEdge.Source.PatternElement.OriginalIndependentElement != null) // when the start is a node from an inlined independent { SearchPlanEdgeNode edge = (SearchPlanEdgeNode)planEdge.Target; if(edge.PatternEdgeSource.PatternElement.OriginalIndependentElement != null && edge.PatternEdgeTarget.PatternElement.OriginalIndependentElement == null || edge.PatternEdgeSource.PatternElement.OriginalIndependentElement == null && edge.PatternEdgeTarget.PatternElement.OriginalIndependentElement != null) { // and the edge is incident to elements inside and outside of the inlined independent planEdge.Cost = (float)Math.Sqrt(Math.Sqrt(planEdge.Cost)); } } } }
/// <summary> /// Generate search plan graph out of the plan graph, /// search plan graph only contains edges chosen by the MSA algorithm. /// Edges in search plan graph are given in the nodes by outgoing list, as needed for scheduling, /// in contrast to incoming list in plan graph, as needed for MSA computation. /// </summary> /// <param name="planGraph">The source plan graph</param> /// <returns>A new search plan graph</returns> public SearchPlanGraph GenerateSearchPlanGraph(PlanGraph planGraph) { SearchPlanNode searchPlanRoot = new SearchPlanNode("search plan root"); SearchPlanNode[] searchPlanNodes = new SearchPlanNode[planGraph.Nodes.Length]; SearchPlanEdge[] searchPlanEdges = new SearchPlanEdge[planGraph.Nodes.Length - 1 + 1]; // +1 for root Dictionary<PlanNode, SearchPlanNode> planToSearchPlanNode = // for generating edges new Dictionary<PlanNode, SearchPlanNode>(planGraph.Nodes.Length); planToSearchPlanNode.Add(planGraph.Root, searchPlanRoot); // generate the search plan graph nodes, same as plan graph nodes, // representing pattern graph nodes and edges int i = 0; foreach(PlanNode planNode in planGraph.Nodes) { if(planNode.NodeType == PlanNodeType.Edge) searchPlanNodes[i] = new SearchPlanEdgeNode(planNode, null, null); else searchPlanNodes[i] = new SearchPlanNodeNode(planNode); planToSearchPlanNode.Add(planNode, searchPlanNodes[i]); ++i; } // generate the search plan graph edges, // that are the plan graph edges chosen by the MSA algorithm, in reversed direction // and add references to originating pattern elements i = 0; foreach(PlanNode planNode in planGraph.Nodes) { PlanEdge planEdge = planNode.IncomingMSAEdge; searchPlanEdges[i] = new SearchPlanEdge(planEdge.Type, planToSearchPlanNode[planEdge.Source], planToSearchPlanNode[planEdge.Target], planEdge.Cost); planToSearchPlanNode[planEdge.Source].OutgoingEdges.Add(searchPlanEdges[i]); if(planNode.NodeType == PlanNodeType.Edge) { SearchPlanEdgeNode searchPlanEdgeNode = (SearchPlanEdgeNode) planToSearchPlanNode[planNode]; SearchPlanNode patElem; if(planEdge.Target.PatternEdgeSource != null && planToSearchPlanNode.TryGetValue(planEdge.Target.PatternEdgeSource, out patElem)) { searchPlanEdgeNode.PatternEdgeSource = (SearchPlanNodeNode) patElem; searchPlanEdgeNode.PatternEdgeSource.OutgoingPatternEdges.Add(searchPlanEdgeNode); } if(planEdge.Target.PatternEdgeTarget != null && planToSearchPlanNode.TryGetValue(planEdge.Target.PatternEdgeTarget, out patElem)) { searchPlanEdgeNode.PatternEdgeTarget = (SearchPlanNodeNode) patElem; searchPlanEdgeNode.PatternEdgeTarget.IncomingPatternEdges.Add(searchPlanEdgeNode); } } ++i; } return new SearchPlanGraph(searchPlanRoot, searchPlanNodes, searchPlanEdges); }