/// <summary> /// Returns the cheapest incoming plan edge and its cost, /// excluding nodes contained within the given top super node (if given) /// </summary> public override PlanEdge GetCheapestIncoming(PlanPseudoNode excludeTopNode, out float minCost) { minCost = float.MaxValue; PlanEdge minEdge = null; PlanPseudoNode current = Child; do { float curCost; PlanEdge curEdge = current.GetCheapestIncoming(excludeTopNode, out curCost); if (curEdge != null) { PlanPseudoNode target = curEdge.Target; while (target.SuperNode != this) { target = target.SuperNode; } if (PreferNewEdge(minEdge, minCost, curEdge, curCost)) { minCost = curCost; minEdge = curEdge; } } current = current.IncomingMSAEdge.Source; while (current.SuperNode != this) { current = current.SuperNode; } }while(current != Child); return(minEdge); }
/// <summary> /// Returns the cheapest incoming plan edge and its cost, /// excluding nodes contained within the given top super node (if given) /// </summary> public override PlanEdge GetCheapestIncoming(PlanPseudoNode excludeTopNode, out float minCost) { minCost = float.MaxValue; PlanEdge minEdge = null; foreach (PlanEdge edge in IncomingEdges) { if (excludeTopNode != null && edge.Source.TopNode == excludeTopNode) { continue; } if (PreferNewEdge(minEdge, minCost, edge, edge.mstCost)) { minCost = edge.mstCost; minEdge = edge; } } return(minEdge); }
/// <summary> /// Decides whether a new edge is better than a known best edge up to now. /// </summary> /// <returns>true if new edge should be chosen</returns> public bool PreferNewEdge(PlanEdge minEdge, float minEdgeCost, PlanEdge newEdge, float newEdgeCost) { float epsilon = 0.001f; float costDiff = minEdgeCost - newEdgeCost; if (costDiff < -epsilon) { return(false); } if (costDiff > epsilon) { return(true); } // Choose equally expensive operations in this order: implicit, non-lookup, edge lookups, node lookups if (minEdge.Source.NodeType == PlanNodeType.Edge) { return(false); // minEdge is implicit op } if (newEdge.Source.NodeType == PlanNodeType.Edge) { return(true); // newEdge is implicit op } if (minEdge.Source.NodeType != PlanNodeType.Root) { return(false); // minEdge is non-lookup op } if (newEdge.Source.NodeType != PlanNodeType.Root) { return(true); // newEdge is non-lookup op } if (minEdge.Target.NodeType == PlanNodeType.Edge) { return(false); // minEdge is edge lookup } if (newEdge.Target.NodeType == PlanNodeType.Edge) { return(true); // newEdge is edge lookup } return(false); // minEdge and newEdge are node lookups, keep minEdge }
/// <summary> /// Decides whether a new edge is better than a known best edge up to now. /// </summary> /// <returns>true if new edge should be chosen</returns> public bool PreferNewEdge(PlanEdge minEdge, float minEdgeCost, PlanEdge newEdge, float newEdgeCost) { float epsilon = 0.001f; float costDiff = minEdgeCost - newEdgeCost; if (costDiff < -epsilon) return false; if (costDiff > epsilon) return true; // Choose equally expensive operations in this order: implicit, non-lookup, edge lookups, node lookups if (minEdge.Source.NodeType == PlanNodeType.Edge) return false; // minEdge is implicit op if (newEdge.Source.NodeType == PlanNodeType.Edge) return true; // newEdge is implicit op if (minEdge.Source.NodeType != PlanNodeType.Root) return false; // minEdge is non-lookup op if (newEdge.Source.NodeType != PlanNodeType.Root) return true; // newEdge is non-lookup op if (minEdge.Target.NodeType == PlanNodeType.Edge) return false; // minEdge is edge lookup if (newEdge.Target.NodeType == PlanNodeType.Edge) return true; // newEdge is edge lookup return false; // minEdge and newEdge are node lookups, keep minEdge }
public static void CreatePickMapCastAssignPlanEdges(PatternEdge edge, List<PlanEdge> planEdges, float zeroCost) { if(edge.Storage != null && edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { PlanEdge storAccessPlanEdge = new PlanEdge( edge.StorageIndex != null ? SearchOperationType.MapWithStorageDependent : SearchOperationType.PickFromStorageDependent, edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness().TempPlanMapping, edge.TempPlanMapping, zeroCost); planEdges.Add(storAccessPlanEdge); edge.TempPlanMapping.IncomingEdges.Add(storAccessPlanEdge); } else if(edge.IndexAccess != null && edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { PlanEdge indexAccessPlanEdge = new PlanEdge( SearchOperationType.PickFromIndexDependent, edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness().TempPlanMapping, edge.TempPlanMapping, zeroCost); planEdges.Add(indexAccessPlanEdge); edge.TempPlanMapping.IncomingEdges.Add(indexAccessPlanEdge); } else if(edge.NameLookup != null && edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { PlanEdge nameAccessPlanEdge = new PlanEdge( SearchOperationType.PickByNameDependent, edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness().TempPlanMapping, edge.TempPlanMapping, zeroCost); planEdges.Add(nameAccessPlanEdge); edge.TempPlanMapping.IncomingEdges.Add(nameAccessPlanEdge); } else if(edge.UniqueLookup != null && edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { PlanEdge uniqueAccessPlanEdge = new PlanEdge( SearchOperationType.PickByUniqueDependent, edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness().TempPlanMapping, edge.TempPlanMapping, zeroCost); planEdges.Add(uniqueAccessPlanEdge); edge.TempPlanMapping.IncomingEdges.Add(uniqueAccessPlanEdge); } else if(edge.ElementBeforeCasting != null) { PlanEdge castPlanEdge = new PlanEdge(SearchOperationType.Cast, edge.ElementBeforeCasting.TempPlanMapping, edge.TempPlanMapping, zeroCost); planEdges.Add(castPlanEdge); edge.TempPlanMapping.IncomingEdges.Add(castPlanEdge); } else if(edge.AssignmentSource != null) { PlanEdge assignPlanEdge = new PlanEdge(SearchOperationType.Assign, edge.AssignmentSource.TempPlanMapping, edge.TempPlanMapping, zeroCost); planEdges.Add(assignPlanEdge); edge.TempPlanMapping.IncomingEdges.Add(assignPlanEdge); if(!edge.AssignmentSource.TempPlanMapping.IsPreset) { PlanEdge assignPlanEdgeOpposite = new PlanEdge(SearchOperationType.Assign, edge.TempPlanMapping, edge.AssignmentSource.TempPlanMapping, zeroCost); planEdges.Add(assignPlanEdgeOpposite); edge.AssignmentSource.TempPlanMapping.IncomingEdges.Add(assignPlanEdge); } } }
private void CreateSourceTargetIncomingOutgoingPlanEdges(PatternEdge edge, PlanNode planNode, List<PlanEdge> planEdges, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent, LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isPreset, float zeroCost) { // only add implicit source operation if edge source is needed and the edge source is // not a preset node and not a storage node and not an index node and not a cast node PatternNode source = GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent); if(source != null && !source.TempPlanMapping.IsPreset && source.Storage == null && source.IndexAccess == null && source.NameLookup == null && source.UniqueLookup == null && source.ElementBeforeCasting == null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.ImplicitSource : SearchOperationType.Implicit; PlanEdge implSrcPlanEdge = new PlanEdge(operation, planNode, source.TempPlanMapping, zeroCost); planEdges.Add(implSrcPlanEdge); source.TempPlanMapping.IncomingEdges.Add(implSrcPlanEdge); } // only add implicit target operation if edge target is needed and the edge target is // not a preset node and not a storage node and not an index node and not a cast node PatternNode target = GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent); if(target != null && !target.TempPlanMapping.IsPreset && target.Storage == null && target.IndexAccess == null && target.NameLookup == null && target.UniqueLookup == null && target.ElementBeforeCasting == null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.ImplicitTarget : SearchOperationType.Implicit; PlanEdge implTgtPlanEdge = new PlanEdge(operation, planNode, target.TempPlanMapping, zeroCost); planEdges.Add(implTgtPlanEdge); target.TempPlanMapping.IncomingEdges.Add(implTgtPlanEdge); } // edge must only be reachable from other nodes if it's not a preset and not storage determined and not index determined and not a cast if(!isPreset && edge.Storage == null && edge.IndexAccess == null && edge.NameLookup == null && edge.UniqueLookup == null && edge.ElementBeforeCasting == null) { // no outgoing on source node if no source if(source != null) { int targetTypeID; if(target != null) targetTypeID = target.TypeID; else targetTypeID = model.NodeModel.RootType.TypeID; // cost of walking along edge #if MONO_MULTIDIMARRAY_WORKAROUND float normCost = graphStatistics.vstructs[((source.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + targetTypeID) * 2 + (int)LGSPDirection.Out]; if(!edge.fixedDirection) { normCost += graphStatistics.vstructs[((source.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + targetTypeID) * 2 + (int)LGSPDirection.In]; } #else float normCost = graph.statistics.vstructs[source.TypeID, edge.TypeID, targetTypeID, (int) LGSPDirection.Out]; if (!edge.fixedDirection) { normCost += graph.statistics.vstructs[source.TypeID, edge.TypeID, targetTypeID, (int) LGSPDirection.In]; } #endif if(graphStatistics.nodeCounts[source.TypeID] != 0) normCost /= graphStatistics.nodeCounts[source.TypeID]; normCost = CostIncreaseForInlinedIndependent(edge, normCost); SearchOperationType operation = edge.fixedDirection ? SearchOperationType.Outgoing : SearchOperationType.Incident; PlanEdge outPlanEdge = new PlanEdge(operation, source.TempPlanMapping, planNode, normCost); planEdges.Add(outPlanEdge); planNode.IncomingEdges.Add(outPlanEdge); } // no incoming on target node if no target if(target != null) { int sourceTypeID; if(source != null) sourceTypeID = source.TypeID; else sourceTypeID = model.NodeModel.RootType.TypeID; // cost of walking in opposite direction of edge #if MONO_MULTIDIMARRAY_WORKAROUND float revCost = graphStatistics.vstructs[((target.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + sourceTypeID) * 2 + (int)LGSPDirection.In]; if(!edge.fixedDirection) { revCost += graphStatistics.vstructs[((target.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size + sourceTypeID) * 2 + (int)LGSPDirection.Out]; } #else float revCost = graph.statistics.vstructs[target.TypeID, edge.TypeID, sourceTypeID, (int) LGSPDirection.In]; if (!edge.fixedDirection) { revCost += graph.statistics.vstructs[target.TypeID, edge.TypeID, sourceTypeID, (int) LGSPDirection.Out]; } #endif if(graphStatistics.nodeCounts[target.TypeID] != 0) revCost /= graphStatistics.nodeCounts[target.TypeID]; revCost = CostIncreaseForInlinedIndependent(edge, revCost); SearchOperationType operation = edge.fixedDirection ? SearchOperationType.Incoming : SearchOperationType.Incident; PlanEdge inPlanEdge = new PlanEdge(operation, target.TempPlanMapping, planNode, revCost); planEdges.Add(inPlanEdge); planNode.IncomingEdges.Add(inPlanEdge); } } }
private static void CreatePlanNodeAndLookupPlanEdge(PatternEdge edge, int elemId, LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isNegativeOrIndependent, bool isSubpatternLike, PlanNode planRoot, float zeroCost, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent, IDictionary<PatternElement, SetValueType> presetsFromIndependentInlining, out bool isPreset, out PlanNode planNode, out PlanEdge rootToNodePlanEdge) { float cost; SearchOperationType searchOperationType; if(edge.DefToBeYieldedTo) { cost = zeroCost; isPreset = true; searchOperationType = SearchOperationType.DefToBeYieldedTo; } else if(edge.PointOfDefinition == null) { cost = zeroCost; isPreset = true; searchOperationType = isSubpatternLike ? SearchOperationType.SubPreset : SearchOperationType.ActionPreset; } else if(edge.PointOfDefinition != patternGraph && edge.OriginalIndependentElement == null) { cost = zeroCost; isPreset = true; searchOperationType = isNegativeOrIndependent ? SearchOperationType.NegIdptPreset : SearchOperationType.SubPreset; } else if(presetsFromIndependentInlining.ContainsKey(edge)) { cost = zeroCost; isPreset = true; searchOperationType = SearchOperationType.NegIdptPreset; edge.PresetBecauseOfIndependentInlining = true; } else if(edge.Storage != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickFromStorage; // pick from storage instead of lookup from graph } } else if(edge.IndexAccess != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickFromIndex; // pick from index instead of lookup from graph } } else if(edge.NameLookup != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickByName; // pick by name instead of lookup from graph } } else if(edge.UniqueLookup != null) { if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation } else { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.PickByUnique; // pick by unique instead of lookup from graph } } else if(edge.ElementBeforeCasting != null) { cost = zeroCost; isPreset = false; searchOperationType = SearchOperationType.Void; // the element before casting is needed, so there is no lookup like operation } else { cost = graphStatistics.edgeCounts[edge.TypeID]; cost = CostIncreaseForInlinedIndependent(edge, cost); isPreset = false; searchOperationType = SearchOperationType.Lookup; } PatternNode source = GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent); PatternNode target = GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent); planNode = new PlanNode(edge, elemId, isPreset, source != null ? source.TempPlanMapping : null, target != null ? target.TempPlanMapping : null); rootToNodePlanEdge = null; if(searchOperationType != SearchOperationType.Void) rootToNodePlanEdge = new PlanEdge(searchOperationType, planRoot, planNode, cost); }
private void DumpEdge(StreamWriter sw, PlanEdge edge, bool markRed) { String typeStr = " #"; switch(edge.Type) { case SearchOperationType.Outgoing: typeStr = "--"; break; case SearchOperationType.Incoming: typeStr = "->"; break; case SearchOperationType.Incident: typeStr = "<->"; break; case SearchOperationType.ImplicitSource: typeStr = "IS"; break; case SearchOperationType.ImplicitTarget: typeStr = "IT"; break; case SearchOperationType.Implicit: typeStr = "IM"; break; case SearchOperationType.Lookup: typeStr = " *"; break; case SearchOperationType.ActionPreset: typeStr = " p"; break; case SearchOperationType.NegIdptPreset: typeStr = "np"; break; case SearchOperationType.SubPreset: typeStr = "sp"; break; } sw.WriteLine("edge:{{sourcename:\"{0}\" targetname:\"{1}\" label:\"{2} / {3:0.00} ({4:0.00}) \"{5}}}", GetDumpName(edge.Source), GetDumpName(edge.Target), typeStr, edge.mstCost, edge.Cost, markRed ? " color:red" : ""); }
/// <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 static 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)); }
private static void CreateSourceTargetIncomingOutgoingPlanEdges(PatternEdge edge, PlanNode planNode, List<PlanEdge> planEdges, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent, PatternGraph patternGraph, bool isPreset, float zeroCost) { // only add implicit source operation if edge source is needed and the edge source is // not a preset node and not a storage node and not an index node and not a cast node PatternNode source = LGSPMatcherGenerator.GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent); if(source != null && !source.TempPlanMapping.IsPreset && source.Storage == null && source.IndexAccess == null && source.NameLookup == null && source.UniqueLookup == null && source.ElementBeforeCasting == null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.ImplicitSource : SearchOperationType.Implicit; PlanEdge implSrcPlanEdge = new PlanEdge(operation, planNode, source.TempPlanMapping, zeroCost); planEdges.Add(implSrcPlanEdge); source.TempPlanMapping.IncomingEdges.Add(implSrcPlanEdge); } // only add implicit target operation if edge target is needed and the edge target is // not a preset node and not a storage node and not an index node and not a cast node PatternNode target = LGSPMatcherGenerator.GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent); if(target != null && !target.TempPlanMapping.IsPreset && target.Storage == null && target.IndexAccess == null && target.NameLookup == null && target.UniqueLookup == null && target.ElementBeforeCasting == null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.ImplicitTarget : SearchOperationType.Implicit; PlanEdge implTgtPlanEdge = new PlanEdge(operation, planNode, target.TempPlanMapping, zeroCost); planEdges.Add(implTgtPlanEdge); target.TempPlanMapping.IncomingEdges.Add(implTgtPlanEdge); } // edge must only be reachable from other nodes if it's not a preset and not storage determined and not index determined and not a cast if(!isPreset && edge.Storage == null && edge.IndexAccess == null && edge.NameLookup == null && edge.UniqueLookup == null && edge.ElementBeforeCasting == null) { float cost = (edge.Cost + 5.5f) / 2; cost = LGSPMatcherGenerator.CostIncreaseForInlinedIndependent(edge, cost); // no outgoing on source node if no source if(source != null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.Outgoing : SearchOperationType.Incident; PlanEdge outPlanEdge = new PlanEdge(operation, source.TempPlanMapping, planNode, cost); planEdges.Add(outPlanEdge); planNode.IncomingEdges.Add(outPlanEdge); } // no incoming on target node if no target if(target != null) { SearchOperationType operation = edge.fixedDirection ? SearchOperationType.Incoming : SearchOperationType.Incident; PlanEdge inPlanEdge = new PlanEdge(operation, target.TempPlanMapping, planNode, cost); planEdges.Add(inPlanEdge); planNode.IncomingEdges.Add(inPlanEdge); } } }
public PlanEdge[] Edges; // edges of the plan graph, representing search operations public PlanGraph(PlanNode root, PlanNode[] nodes, PlanEdge[] edges) { Root = root; Nodes = nodes; Edges = edges; }