private Rule_testRule() { PatternNode node_p2 = new PatternNode((int) NodeTypes.@Process, "node_p2", node_p2_AllowedTypes, node_p2_IsAllowedType, PatternElementType.Normal, -1); PatternNode node_p1 = new PatternNode((int) NodeTypes.@Process, "node_p1", node_p1_AllowedTypes, node_p1_IsAllowedType, PatternElementType.Normal, -1); PatternEdge edge__edge0 = new PatternEdge(node_p1, node_p2, (int) EdgeTypes.@connection, "edge__edge0", edge__edge0_AllowedTypes, edge__edge0_IsAllowedType, PatternElementType.Normal, -1); patternGraph = new PatternGraph( new PatternNode[] { node_p2, node_p1 }, new PatternEdge[] { edge__edge0 }, new Condition[] { }, new bool[2, 2] { { true, false, }, { false, true, }, }, new bool[1, 1] { { true, }, }, new bool[] { false, false, }, new bool[] { false, } ); negativePatternGraphs = new PatternGraph[] {}; inputs = new GrGenType[] { }; outputs = new GrGenType[] { }; }
/// <summary> /// Instantiates a new PatternEdge object as a copy from an original edge, used for independent inlining. /// </summary> /// <param name="original">The original pattern edge to be copy constructed.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern edge (to avoid name collisions).</param> public PatternEdge(PatternEdge original, String nameSuffix) : base(original, nameSuffix) { fixedDirection = original.fixedDirection; }
/// <summary> /// Instantiates a new PatternEdge object as a copy from an original edge, used for subpattern inlining. /// </summary> /// <param name="original">The original pattern edge to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new pattern element will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the pattern edge (to avoid name collisions).</param> public PatternEdge(PatternEdge original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix) : base(original, inlinedSubpatternEmbedding, newHost, nameSuffix) { fixedDirection = original.fixedDirection; }
public static PatternNode GetTargetPlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent) { PatternNode target = patternGraph.GetTargetPlusInlined(edge); if(edge.OriginalIndependentElement != null && target == null) { PatternNode targetOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetTargetPlusInlined((PatternEdge)edge.OriginalIndependentElement); if(originalToInlinedIndependent.ContainsKey(targetOriginal)) target = originalToInlinedIndependent[targetOriginal]; else target = targetOriginal; // not declared in independent itself, but in some parent } return target; }
public static PatternNode GetSourcePlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent) { PatternNode source = patternGraph.GetSourcePlusInlined(edge); if(edge.OriginalIndependentElement != null && source == null) { PatternNode sourceOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetSourcePlusInlined((PatternEdge)edge.OriginalIndependentElement); if(originalToInlinedIndependent.ContainsKey(sourceOriginal)) source = originalToInlinedIndependent[sourceOriginal]; else source = sourceOriginal; // not declared in independent itself, but in some parent } return source; }
/// <summary> /// Builds a pattern graph out of the graph. /// The pattern graph retains links to the original graph elements and uses them for attribute comparison. /// </summary> /// <param name="graph">The graph which is to be transfered into a pattern</param> /// <returns></returns> public PatternGraph BuildPatternGraph(LGSPGraph graph) { int numNodes = graph.NumNodes; int numEdges = graph.NumEdges; int count = 0; PatternNode[] nodes = new PatternNode[numNodes]; INode[] correspondingNodes = new INode[numNodes]; foreach(INode node in graph.Nodes) { LGSPNode n = (LGSPNode)node; nodes[count] = new PatternNode( n.Type.TypeID, n.Type, n.Type.PackagePrefixedName, graph.Name+"_node_"+count, "node_"+count, null, null, 1.0f, -1, false, null, null, null, null, null, null, false, null ); correspondingNodes[count] = node; ++count; } count = 0; PatternEdge[] edges = new PatternEdge[numEdges]; IEdge[] correspondingEdges = new IEdge[numEdges]; foreach(IEdge edge in graph.Edges) { LGSPEdge e = (LGSPEdge)edge; edges[count] = new PatternEdge( true, e.Type.TypeID, e.Type, e.Type.PackagePrefixedName, graph.Name+"_edge_"+count, "edge_"+count, null, null, 1.0f, -1, false, null, null, null, null, null, null, false, null ); correspondingEdges[count] = edge; ++count; } bool[,] homNodes = new bool[numNodes, numNodes]; for(int i = 0; i < numNodes; ++i) for(int j = 0; j < numNodes; ++j) homNodes[i, j] = false; bool[,] homEdges = new bool[numEdges, numEdges]; for(int i = 0; i < numEdges; ++i) for(int j = 0; j < numEdges; ++j) homEdges[i, j] = false; bool[,] homNodesGlobal = new bool[numNodes, numNodes]; for(int i = 0; i < numNodes; ++i) for(int j = 0; j < numNodes; ++j) homNodesGlobal[i, j] = false; bool[,] homEdgesGlobal = new bool[numEdges, numEdges]; for(int i = 0; i < numEdges; ++i) for(int j = 0; j < numEdges; ++j) homEdgesGlobal[i, j] = false; bool[] totallyHomNodes = new bool[numNodes]; for(int i = 0; i < numNodes; ++i) totallyHomNodes[i] = false; bool[] totallyHomEdges = new bool[numEdges]; for(int i = 0; i < numEdges; ++i) totallyHomEdges[i] = false; List<PatternCondition> pcs = new List<PatternCondition>(); for(int i = 0; i < numNodes; ++i) { if(nodes[i].Type.NumAttributes > 0) pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingNodes[i], nodes[i]), new string[] { nodes[i].name }, new string[] { }, new string[] { }, new VarType[] { })); } for(int i = 0; i < numEdges; ++i) { if(edges[i].Type.NumAttributes > 0) pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingEdges[i], edges[i]), new string[] { }, new string[] { edges[i].name }, new string[] { }, new VarType[] { })); } PatternCondition[] patternConditions = pcs.ToArray(); PatternGraph patternGraph = new PatternGraph( graph.Name, "", null, graph.Name, false, false, nodes, edges, new PatternVariable[0], new PatternGraphEmbedding[0], new Alternative[0], new Iterated[0], new PatternGraph[0], new PatternGraph[0], patternConditions, new PatternYielding[0], homNodes, homEdges, homNodesGlobal, homEdgesGlobal, totallyHomNodes, totallyHomEdges ); foreach(PatternNode node in nodes) node.pointOfDefinition = patternGraph; foreach(PatternEdge edge in edges) edge.pointOfDefinition = patternGraph; patternGraph.correspondingNodes = correspondingNodes; patternGraph.correspondingEdges = correspondingEdges; foreach(IEdge edge in graph.Edges) { int edgeIndex = Array.IndexOf<IEdge>(correspondingEdges, edge); int sourceIndex = Array.IndexOf<INode>(correspondingNodes, edge.Source); int targetIndex = Array.IndexOf<INode>(correspondingNodes, edge.Target); patternGraph.edgeToSourceNode.Add(edges[edgeIndex], nodes[sourceIndex]); patternGraph.edgeToTargetNode.Add(edges[edgeIndex], nodes[targetIndex]); } PatternGraphAnalyzer.PrepareInline(patternGraph); return patternGraph; }
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); }
/// <summary> /// Generate plan graph for given pattern graph with costs from the analyzed host graph. /// Plan graph contains nodes representing the pattern elements (nodes and edges) /// and edges representing the matching operations to get the elements by. /// Edges in plan graph are given in the nodes by incoming list, as needed for MSA computation. /// </summary> public PlanGraph GeneratePlanGraph(LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isNegativeOrIndependent, bool isSubpatternLike, IDictionary<PatternElement, SetValueType> presetsFromIndependentInlining) { // // If you change this method, chances are high you also want to change GenerateStaticPlanGraph in LGSPGrGen // look there for version without ifdef junk // todo: unify it with GenerateStaticPlanGraph in LGSPGrGen // // Create root node // Create plan graph nodes for all pattern graph nodes and all pattern graph edges // Create "lookup" plan graph edge from root node to each plan graph node // Create "implicit source" plan graph edge from each plan graph node originating with a pattern edge // to the plan graph node created by the source node of the pattern graph edge // Create "implicit target" plan graph edge from each plan graph node originating with a pattern edge // to the plan graph node created by the target node of the pattern graph edge // Create "incoming" plan graph edge from each plan graph node originating with a pattern node // to a plan graph node created by one of the incoming edges of the pattern node // Create "outgoing" plan graph edge from each plan graph node originating with a pattern node // to a plan graph node created by one of the outgoing edges of the pattern node // Ensured: there's no plan graph edge with a preset element as target besides the lookup, // so presets are only search operation sources // Create "pick from storage" plan graph edge for plan graph nodes which are to be picked from a storage, // from root node on, instead of lookup, no other plan graph edge having this node as target // Create "pick from storage attribute" plan graph edge from storage attribute owner to storage picking result, // no lookup, no other plan graph edge having this node as target // Create "map" by storage plan graph edge from accessor to storage mapping result // no lookup, no other plan graph edge having this node as target // Create "pick from index" plan graph edge for plan graph nodes which are to be picked from an index, // from root node on, instead of lookup, no other plan graph edge having this node as target // Create "pick from index depending" plan graph edge from node the index expressions depend on, // no lookup, no other plan graph edge having this node as target // Create "cast" plan graph edge from element before casting to cast result, // no lookup, no other plan graph edge having this node as target int numNodes = patternGraph.nodesPlusInlined.Length; if(InlineIndependents && !isNegativeOrIndependent) numNodes += LGSPMatcherGenerator.NumNodesInIndependentsMatchedThere(patternGraph); int numEdges = patternGraph.edgesPlusInlined.Length; if(InlineIndependents && !isNegativeOrIndependent) numEdges += LGSPMatcherGenerator.NumEdgesInIndependentsMatchedThere(patternGraph); PlanNode[] planNodes = new PlanNode[numNodes + numEdges]; List<PlanEdge> planEdges = new List<PlanEdge>(numNodes + 5 * numEdges); // upper bound for num of edges (lookup nodes + lookup edges + impl. tgt + impl. src + incoming + outgoing) Dictionary<PatternNode, PatternNode> originalToInlinedIndependent = new Dictionary<PatternNode, PatternNode>(); int nodesIndex = 0; float zeroCost = 1; PlanNode planRoot = new PlanNode("root"); // create plan nodes and lookup plan edges for all pattern graph nodes for(int i = 0; i < patternGraph.nodesPlusInlined.Length; i++) { PatternNode node = patternGraph.nodesPlusInlined[i]; PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(node, i + 1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } node.TempPlanMapping = planNode; ++nodesIndex; } if(InlineIndependents && !isNegativeOrIndependent) // independent inlining only if not in negative/independent { foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { foreach(PatternNode nodeOriginal in LGSPMatcherGenerator.NodesInIndependentMatchedThere(independent)) { PatternNode node = new PatternNode(nodeOriginal, "_inlined_" + independent.name); originalToInlinedIndependent.Add(nodeOriginal, node); PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(node, -1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } node.TempPlanMapping = planNode; ++nodesIndex; } } } // create plan nodes and lookup plus incidence handling plan edges for all pattern graph edges for(int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i) { PatternEdge edge = patternGraph.edgesPlusInlined[i]; bool isPreset; PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(edge, i + 1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out isPreset, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } CreateSourceTargetIncomingOutgoingPlanEdges(edge, planNode, planEdges, originalToInlinedIndependent, graphStatistics, patternGraph, isPreset, zeroCost); edge.TempPlanMapping = planNode; ++nodesIndex; } if(InlineIndependents && !isNegativeOrIndependent) // independent inlining only if not in negative/independent { foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined) { foreach(PatternEdge edgeOriginal in LGSPMatcherGenerator.EdgesInIndependentMatchedThere(independent)) { PatternEdge edge = new PatternEdge(edgeOriginal, "_inlined_" + independent.name); bool isPreset; PlanNode planNode; PlanEdge rootToNodePlanEdge; CreatePlanNodeAndLookupPlanEdge(edge, -1, graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost, originalToInlinedIndependent, presetsFromIndependentInlining, out isPreset, out planNode, out rootToNodePlanEdge); planNodes[nodesIndex] = planNode; if(rootToNodePlanEdge != null) { planEdges.Add(rootToNodePlanEdge); planNode.IncomingEdges.Add(rootToNodePlanEdge); } CreateSourceTargetIncomingOutgoingPlanEdges(edge, planNode, planEdges, originalToInlinedIndependent, graphStatistics, patternGraph, isPreset, zeroCost); edge.TempPlanMapping = planNode; ++nodesIndex; } } } //////////////////////////////////////////////////////////////////////////// // second run handling dependent storage and index picking (can't be done in first run due to dependencies between elements) // create map/pick/cast/assign plan edges for all pattern graph nodes for(int i = 0; i < patternGraph.nodesPlusInlined.Length; ++i) { PatternNode node = patternGraph.nodesPlusInlined[i]; if(node.PointOfDefinition == patternGraph && !presetsFromIndependentInlining.ContainsKey(node)) CreatePickMapCastAssignPlanEdges(node, planEdges, zeroCost); } // create map/pick/cast/assign plan edges for all pattern graph edges for(int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i) { PatternEdge edge = patternGraph.edgesPlusInlined[i]; if(edge.PointOfDefinition == patternGraph && !presetsFromIndependentInlining.ContainsKey(edge)) CreatePickMapCastAssignPlanEdges(edge, planEdges, zeroCost); } return new PlanGraph(planRoot, planNodes, planEdges.ToArray()); }
PatternNode GetTargetPlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent) { PatternNode target = patternGraph.GetTargetPlusInlined(edge); if(edge.OriginalIndependentElement != null && target == null) { PatternNode targetOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetTargetPlusInlined((PatternEdge)edge.OriginalIndependentElement); target = originalToInlinedIndependent[targetOriginal]; } return target; }
PatternNode GetSourcePlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent) { PatternNode source = patternGraph.GetSourcePlusInlined(edge); if(edge.OriginalIndependentElement != null && source == null) { PatternNode sourceOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetSourcePlusInlined((PatternEdge)edge.OriginalIndependentElement); source = originalToInlinedIndependent[sourceOriginal]; } return source; }
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); } } }
/// <summary> /// Instantiates an edge plan node. /// </summary> /// <param name="patEdge">The pattern edge for this plan node.</param> /// <param name="elemID">The element ID for this plan node.</param> /// <param name="isPreset">True, if this element is a known element.</param> /// <param name="patternEdgeSource">The plan node corresponding to the source of the pattern edge.</param> /// <param name="patternEdgeTarget">The plan node corresponding to the target of the pattern edge.</param> public PlanNode(PatternEdge patEdge, int elemID, bool isPreset, PlanNode patternEdgeSource, PlanNode patternEdgeTarget) { NodeType = PlanNodeType.Edge; ElementID = elemID; IsPreset = isPreset; PatternElement = patEdge; PatternEdgeSource = patternEdgeSource; PatternEdgeTarget = patternEdgeTarget; }
private void initialize() { bool[,] testRule_isNodeHomomorphicGlobal = new bool[3, 3] { { false, false, false, }, { false, false, false, }, { false, false, false, }, }; bool[,] testRule_isEdgeHomomorphicGlobal = new bool[2, 2] { { false, false, }, { false, false, }, }; bool[] testRule_isNodeTotallyHomomorphic = new bool[3] { false, false, false, }; bool[] testRule_isEdgeTotallyHomomorphic = new bool[2] { false, false, }; GRGEN_LGSP.PatternNode testRule_node_a = new GRGEN_LGSP.PatternNode((int)GRGEN_MODEL.NodeTypes.@D231_4121, GRGEN_MODEL.NodeType_D231_4121.typeVar, "GRGEN_MODEL.ID231_4121", "testRule_node_a", "a", testRule_node_a_AllowedTypes, testRule_node_a_IsAllowedType, 5.5F, -1, false, null, null, null, null, null, null, false, null); GRGEN_LGSP.PatternNode testRule_node_f = new GRGEN_LGSP.PatternNode((int)GRGEN_MODEL.NodeTypes.@B21, GRGEN_MODEL.NodeType_B21.typeVar, "GRGEN_MODEL.IB21", "testRule_node_f", "f", testRule_node_f_AllowedTypes, testRule_node_f_IsAllowedType, 5.5F, -1, false, null, null, null, null, null, null, false, null); GRGEN_LGSP.PatternNode testRule_node_m = new GRGEN_LGSP.PatternNode((int)GRGEN_MODEL.NodeTypes.@D2211_2222_31, GRGEN_MODEL.NodeType_D2211_2222_31.typeVar, "GRGEN_MODEL.ID2211_2222_31", "testRule_node_m", "m", testRule_node_m_AllowedTypes, testRule_node_m_IsAllowedType, 5.5F, -1, false, null, null, null, null, null, null, false, null); GRGEN_LGSP.PatternEdge testRule_edge__edge0 = new GRGEN_LGSP.PatternEdge(true, (int)GRGEN_MODEL.EdgeTypes.@Edge, GRGEN_MODEL.EdgeType_Edge.typeVar, "GRGEN_LIBGR.IEdge", "testRule_edge__edge0", "_edge0", testRule_edge__edge0_AllowedTypes, testRule_edge__edge0_IsAllowedType, 5.5F, -1, false, null, null, null, null, null, null, false, null); GRGEN_LGSP.PatternEdge testRule_edge__edge1 = new GRGEN_LGSP.PatternEdge(true, (int)GRGEN_MODEL.EdgeTypes.@Edge, GRGEN_MODEL.EdgeType_Edge.typeVar, "GRGEN_LIBGR.IEdge", "testRule_edge__edge1", "_edge1", testRule_edge__edge1_AllowedTypes, testRule_edge__edge1_IsAllowedType, 5.5F, -1, false, null, null, null, null, null, null, false, null); pat_testRule = new GRGEN_LGSP.PatternGraph( "testRule", "", null, "testRule", false, false, new GRGEN_LGSP.PatternNode[] { testRule_node_a, testRule_node_f, testRule_node_m }, new GRGEN_LGSP.PatternEdge[] { testRule_edge__edge0, testRule_edge__edge1 }, new GRGEN_LGSP.PatternVariable[] { }, new GRGEN_LGSP.PatternGraphEmbedding[] { }, new GRGEN_LGSP.Alternative[] { }, new GRGEN_LGSP.Iterated[] { }, new GRGEN_LGSP.PatternGraph[] { }, new GRGEN_LGSP.PatternGraph[] { }, new GRGEN_LGSP.PatternCondition[] { }, new GRGEN_LGSP.PatternYielding[] { }, new bool[3, 3] { { true, false, false, }, { false, true, false, }, { false, false, true, }, }, new bool[2, 2] { { true, false, }, { false, true, }, }, testRule_isNodeHomomorphicGlobal, testRule_isEdgeHomomorphicGlobal, testRule_isNodeTotallyHomomorphic, testRule_isEdgeTotallyHomomorphic ); pat_testRule.edgeToSourceNode.Add(testRule_edge__edge0, testRule_node_a); pat_testRule.edgeToTargetNode.Add(testRule_edge__edge0, testRule_node_f); pat_testRule.edgeToSourceNode.Add(testRule_edge__edge1, testRule_node_f); pat_testRule.edgeToTargetNode.Add(testRule_edge__edge1, testRule_node_m); testRule_node_a.pointOfDefinition = pat_testRule; testRule_node_f.pointOfDefinition = pat_testRule; testRule_node_m.pointOfDefinition = pat_testRule; testRule_edge__edge0.pointOfDefinition = pat_testRule; testRule_edge__edge1.pointOfDefinition = pat_testRule; patternGraph = pat_testRule; }