Exemplo n.º 1
0
        /// <summary>
        /// Copy constructor helper.
        /// </summary>
        /// <param name="dataSource">The LGSPGraph object to get the data from</param>
        /// <param name="newName">Name of the copied graph.</param>
        /// <param name="oldToNewMap">A map of the old elements to the new elements after cloning,
        /// just forget about it if you don't need it.</param>
        private void Copy(LGSPGraph dataSource, String newName, out IDictionary<IGraphElement, IGraphElement> oldToNewMap)
        {
            model = dataSource.model;
            name = newName;

            InitializeGraph();

            model.CreateAndBindIndexSet(this);

            if(dataSource.backend != null)
            {
                backend = dataSource.backend;
                modelAssemblyName = dataSource.modelAssemblyName;
            }

            oldToNewMap = new Dictionary<IGraphElement, IGraphElement>();

            for(int i = 0; i < dataSource.nodesByTypeHeads.Length; i++)
            {
                for(LGSPNode head = dataSource.nodesByTypeHeads[i], node = head.lgspTypePrev; node != head; node = node.lgspTypePrev)
                {
                    LGSPNode newNode = (LGSPNode) node.Clone();
                    AddNodeWithoutEvents(newNode, node.lgspType.TypeID);
                    oldToNewMap[node] = newNode;
                }
            }

            for(int i = 0; i < dataSource.edgesByTypeHeads.Length; i++)
            {
                for(LGSPEdge head = dataSource.edgesByTypeHeads[i], edge = head.lgspTypePrev; edge != head; edge = edge.lgspTypePrev)
                {
                    LGSPEdge newEdge = (LGSPEdge) edge.Clone((INode) oldToNewMap[edge.lgspSource], (INode) oldToNewMap[edge.lgspTarget]);
                    AddEdgeWithoutEvents(newEdge, newEdge.lgspType.TypeID);
                    oldToNewMap[edge] = newEdge;
                }
            }

            /* TODO: remove when cloning of graph variables was implemented
             * foreach(KeyValuePair<IGraphElement, LinkedList<Variable>> kvp in dataSource.ElementMap)
            {
                IGraphElement newElem = oldToNewMap[kvp.Key];
                foreach(Variable var in kvp.Value)
                    SetVariableValue(var.Name, newElem);
            }*/

            model.FillIndexSetAsClone(this, dataSource, oldToNewMap);

            statistics = new LGSPGraphStatistics(this.Model);
            statistics.Copy(dataSource);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Does action-backend dependent stuff.
        /// </summary>
        /// <param name="args">Any kind of parameters for the stuff to do</param>
        public override void Custom(params object[] args)
        {
            if(args.Length == 0) goto invalidCommand;

            switch((String) args[0])
            {
                case "gen_searchplan":
                {
                    if(graph.statistics.edgeCounts == null)
                        throw new ArgumentException("Graph not analyzed yet!\nPlease execute 'custom graph analyze'!");
                    LGSPAction[] oldActions;
                    if(args.Length == 1)
                    {
                        oldActions = new LGSPAction[actions.Count];
                        int i = 0;
                        foreach(LGSPAction action in actions.Values)
                        {
                            oldActions[i] = action;
                            ++i;
                        }
                    }
                    else
                    {
                        oldActions = new LGSPAction[args.Length - 1];
                        for(int i = 0; i < oldActions.Length; i++)
                        {
                            oldActions[i] = (LGSPAction)GetAction((String)args[i + 1]);
                            if(oldActions[i] == null)
                                throw new ArgumentException("'" + (String)args[i + 1] + "' is not the name of an action!\n"
                                    + "Please use 'show actions' to get a list of the available names.");
                        }
                    }

                    int startticks = Environment.TickCount;
                    matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC;
                    matcherGenerator.InlineIndependents = InlineIndependents;
                    matcherGenerator.Profile = Profile;
                    LGSPAction[] newActions = matcherGenerator.GenerateActions(graph, modelAssemblyName,
                        actionsAssemblyName, oldActions);
                    int stopticks = Environment.TickCount;
                    Console.Write("Searchplans for actions ");
                    for(int i = 0; i < oldActions.Length; i++)
                    {
                        actions[oldActions[i].Name] = newActions[i];
                        if(i != 0) Console.Write(", ");
                        Console.Write("'" + oldActions[i].Name + "'");
                    }
                    Console.WriteLine(" generated in " + (stopticks - startticks) + " ms.");
                    return;
                }

                case "dump_sourcecode":
                    if(args.Length != 2)
                        throw new ArgumentException("Usage: dump_sourcecode <bool>\n"
                                + "If <bool> == true, C# files will be dumped for new searchplans.");

                    if(!bool.TryParse((String) args[1], out matcherGenerator.DumpDynSourceCode))
                        throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\"");
                    return;

                case "dump_searchplan":
                    if(args.Length != 2)
                        throw new ArgumentException("Usage: dump_searchplan <bool>\n"
                                + "If <bool> == true, VCG and TXT files will be dumped for new searchplans.");

                    if(!bool.TryParse((String) args[1], out matcherGenerator.DumpSearchPlan))
                        throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\"");
                    return;

                case "explain":
                {
                    if(args.Length != 2)
                        throw new ArgumentException("Usage: explain <name>\n"
                                + "Explains the searchplan of the given action.");

                    LGSPAction action = (LGSPAction)GetAction((String)args[1]);
                    if(action == null)
                        throw new ArgumentException("'" + (String)args[1] + "' is not the name of an action!\n"
                            + "Please use 'show actions' to get a list of the available names.");

                    if(action.patternGraph.schedules[0] == null)
                    {
                        LGSPGraphStatistics graphStatistics = null;
                        if(StatisticsPath != null)
                        {
                            Console.WriteLine("static search plans from " + StatisticsPath);
                            graphStatistics = new LGSPGraphStatistics(graph.Model);
                            graphStatistics.Parse(StatisticsPath);
                        }
                        else
                            Console.WriteLine("static search plans");
                        LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model);
                        matcherGen.FillInStaticSearchPlans(graphStatistics, InlineIndependents, action);
                    }
                    SourceBuilder sb = new SourceBuilder();
                    foreach(KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern
                        in action.rulePattern.patternGraph.usedSubpatterns)
                    {
                        usedSubpattern.Key.patternGraph.Explain(sb, graph.Model);
                    }
                    action.patternGraph.Explain(sb, graph.Model);
                    Console.WriteLine(sb.ToString());
                    return;
                }
            }

invalidCommand:
            throw new ArgumentException("Possible commands:\n"
                + "- gen_searchplan:  Generates a new searchplan for a given action\n"
                + "     depending on a previous graph analysis\n"
                + "- explain: explains the searchplan in use for a given action\n"
                + "- dump_sourcecode: Sets dumping of C# files for new searchplans\n"
                + "- dump_searchplan: Sets dumping of VCG and TXT files of new\n"
                + "     searchplans (with some intermediate steps)");
        }
Exemplo n.º 3
0
        /// <summary>
        /// Constructs an LGSPGraph object without initializing it.
        /// </summary>
        /// <param name="grname">The name for the graph.</param>
        protected LGSPGraph(String grname)
        {
            graphID = graphIDSource;
            ++graphIDSource;
            
            name = grname;

            statistics = new LGSPGraphStatistics(this.Model);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Do the static search planning again so we can explain the search plan
        /// </summary>
        public void FillInStaticSearchPlans(LGSPGraphStatistics graphStatistics, bool inlineIndependents, params LGSPAction[] actions)
        {
            if(actions.Length == 0) throw new ArgumentException("No actions provided!");

            // use domain of dictionary as set with rulepatterns of the subpatterns of the actions, get them from pattern graph
            Dictionary<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPatterns 
                = new Dictionary<LGSPMatchingPattern, LGSPMatchingPattern>();
            foreach(LGSPAction action in actions)
            {
                foreach(KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern 
                    in action.rulePattern.patternGraph.usedSubpatterns)
                {
                    subpatternMatchingPatterns[usedSubpattern.Key] = usedSubpattern.Value;
                }
            }

            // build search plans for the subpatterns
            foreach(KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPattern in subpatternMatchingPatterns)
            {
                LGSPMatchingPattern smp = subpatternMatchingPattern.Key;

                LGSPGrGen.GenerateScheduledSearchPlans(smp.patternGraph, graphStatistics, 
                    this, true, false, null);

                MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(smp.patternGraph);

                ParallelizeAsNeeded(smp);
            }

            // build search plans code for actions
            foreach(LGSPAction action in actions)
            {
                LGSPGrGen.GenerateScheduledSearchPlans(action.rulePattern.patternGraph, graphStatistics, 
                    this, false, false, null);

                MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(action.rulePattern.patternGraph);

                ParallelizeAsNeeded(action.rulePattern);
            }
        }
Exemplo n.º 7
0
        /// <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());
        }
Exemplo n.º 8
0
        /// <summary>
        /// Generates scheduled search plans needed for matcher code generation for action compilation
        /// out of static schedule information given by rulePattern elements, 
        /// or out of statistics stemming from loading previously serialized statistics 
        /// utilizing code of the lgsp matcher generator.
        /// The scheduled search plans are added to the main and the nested pattern graphs.
        /// </summary>
        internal static void GenerateScheduledSearchPlans(PatternGraph patternGraph, LGSPGraphStatistics graphStatistics, 
            LGSPMatcherGenerator matcherGen,
            bool isSubpatternLike, bool isNegativeOrIndependent,
            ScheduledSearchPlan nestingScheduledSearchPlan)
        {
            for(int i=0; i<patternGraph.schedules.Length; ++i)
            {
                patternGraph.AdaptToMaybeNull(i);
                if(matcherGen.Profile)
                    LGSPMatcherGenerator.SetNeedForProfiling(patternGraph);
                PlanGraph planGraph;
                if(graphStatistics != null)
                    planGraph = matcherGen.GeneratePlanGraph(graphStatistics, patternGraph, 
                        isNegativeOrIndependent, isSubpatternLike,
                        LGSPMatcherGenerator.ExtractOwnElements(nestingScheduledSearchPlan, patternGraph));
                else
                    planGraph = GenerateStaticPlanGraph(patternGraph,
                        isNegativeOrIndependent, isSubpatternLike, matcherGen.InlineIndependents,
                        LGSPMatcherGenerator.ExtractOwnElements(nestingScheduledSearchPlan, patternGraph));
                matcherGen.MarkMinimumSpanningArborescence(planGraph, patternGraph.name);
                SearchPlanGraph searchPlanGraph = matcherGen.GenerateSearchPlanGraph(planGraph);
                ScheduledSearchPlan scheduledSearchPlan = matcherGen.ScheduleSearchPlan(
                    searchPlanGraph, patternGraph, isNegativeOrIndependent);
                matcherGen.AppendHomomorphyInformation(scheduledSearchPlan);
                patternGraph.schedules[i] = scheduledSearchPlan;
                patternGraph.RevertMaybeNullAdaption(i);

                foreach(PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined)
                {
                    GenerateScheduledSearchPlans(neg, graphStatistics, matcherGen, 
                        isSubpatternLike, true, null);
                }

                foreach(PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined)
                {
                    GenerateScheduledSearchPlans(idpt, graphStatistics, matcherGen,
                        isSubpatternLike, true, patternGraph.schedules[i]);
                }

                foreach(Alternative alt in patternGraph.alternativesPlusInlined)
                {
                    foreach(PatternGraph altCase in alt.alternativeCases)
                    {
                        GenerateScheduledSearchPlans(altCase, graphStatistics, matcherGen, 
                            true, false, null);
                    }
                }

                foreach(Iterated iter in patternGraph.iteratedsPlusInlined)
                {
                    GenerateScheduledSearchPlans(iter.iteratedPattern, graphStatistics, matcherGen, 
                        true, false, null);
                }
            }
        }
Exemplo n.º 9
0
        private void GenerateAndInsertMatcherSourceCode(IGraphModel model, String actionsName, String unitName,
            string externalActionsExtensionFilename, LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns, 
            LGSPSequenceGenerator seqGen, bool isAutoGeneratedFilterExisting, bool isExternalFilterFunctionExisting,
            LGSPGraphStatistics graphStatistics, string statisticsPath,
            SourceBuilder externalSource, SourceBuilder source)
        {
            // analyze the matching patterns, inline the subpatterns when expected to be benefitial
            // the analyzer must be run before the matcher generation
            AnalyzeAndInlineMatchingPatterns((flags & ProcessSpecFlags.Noinline) == 0, ruleAndMatchingPatterns);

            LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(model);
            if((flags & ProcessSpecFlags.KeepGeneratedFiles) != 0) matcherGen.CommentSourceCode = true;
            if((flags & ProcessSpecFlags.LazyNIC) != 0) matcherGen.LazyNegativeIndependentConditionEvaluation = true;
            if((flags & ProcessSpecFlags.Noinline) != 0) matcherGen.InlineIndependents = false;
            if((flags & ProcessSpecFlags.Profile) != 0) matcherGen.Profile = true;

            foreach(LGSPMatchingPattern matchingPattern in ruleAndMatchingPatterns.RulesAndSubpatterns)
            {
                GenerateScheduledSearchPlans(matchingPattern.patternGraph, graphStatistics, 
                    matcherGen, !(matchingPattern is LGSPRulePattern), false, null);

                matcherGen.MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(matchingPattern.patternGraph);

                matcherGen.ParallelizeAsNeeded(matchingPattern);

                matcherGen.GenerateActionAndMatcher(source, matchingPattern, true);
            }

            GenerateDefinedSequencesAndFiltersAndFilterStubs(externalActionsExtensionFilename, 
                isAutoGeneratedFilterExisting, isExternalFilterFunctionExisting,
                ruleAndMatchingPatterns, seqGen, externalSource, source);

            // the actions class referencing the generated stuff is generated now into 
            // a source builder which is appended at the end of the other generated stuff
            SourceBuilder endSource = GenerateActionsClass(model, actionsName, unitName,
                statisticsPath, ruleAndMatchingPatterns, 
                matcherGen.LazyNegativeIndependentConditionEvaluation,
                matcherGen.InlineIndependents,
                matcherGen.Profile);
            source.Append(endSource.ToString());
            source.Append("}");
        }
Exemplo n.º 10
0
        private ErrorType GenerateActionsSourceCode(CompileConfiguration cc, IGraphModel model,
            String statisticsPath, out String actionsOutputSource)
        {
            ///////////////////////////////////////////////
            // compile the intermediate action files generated by the java frontend
            // to gain access via reflection to their content needed for matcher code generation
            // and collect that content

            actionsOutputSource = null;

            Assembly initialAssembly;
            ErrorType result = CompileIntermediateActions(cc.modelAssemblyName, cc.actionsFilename, 
                out initialAssembly);
            if(result != ErrorType.NoError)
                return result;

            Dictionary<String, Type> actionTypes;
            Dictionary<String, Type> proceduresTypes;
            LGSPRuleAndMatchingPatterns ruleAndMatchingPatterns;
            CollectActionTypes(initialAssembly, out actionTypes, out proceduresTypes, out ruleAndMatchingPatterns);

            Dictionary<String, List<IFilter>> rulesToFilters;
            Dictionary<String, List<String>> filterFunctionsToInputTypes;
            Dictionary<String, List<String>> rulesToInputTypes;
            Dictionary<String, List<String>> rulesToOutputTypes;
            Dictionary<String, List<String>> sequencesToInputTypes;
            Dictionary<String, List<String>> sequencesToOutputTypes;
            Dictionary<String, List<String>> proceduresToInputTypes;
            Dictionary<String, List<String>> proceduresToOutputTypes;
            Dictionary<String, bool> proceduresToIsExternal;
            Dictionary<String, List<String>> functionsToInputTypes;
            Dictionary<String, String> functionsToOutputType;
            Dictionary<String, bool> functionsToIsExternal;
            Dictionary<String, List<String>> rulesToTopLevelEntities;
            Dictionary<String, List<String>> rulesToTopLevelEntityTypes;
            CollectActionParameterTypes(ruleAndMatchingPatterns, model,
                out rulesToFilters, out filterFunctionsToInputTypes,
                out rulesToInputTypes, out rulesToOutputTypes,
                out rulesToTopLevelEntities, out rulesToTopLevelEntityTypes,
                out sequencesToInputTypes, out sequencesToOutputTypes,
                out proceduresToInputTypes, out proceduresToOutputTypes, out proceduresToIsExternal,
                out functionsToInputTypes, out functionsToOutputType, out functionsToIsExternal);

            LGSPSequenceGenerator seqGen = new LGSPSequenceGenerator(this, model,
                rulesToFilters, filterFunctionsToInputTypes,
                rulesToInputTypes, rulesToOutputTypes,
                rulesToTopLevelEntities, rulesToTopLevelEntityTypes,
                sequencesToInputTypes, sequencesToOutputTypes,
                proceduresToInputTypes, proceduresToOutputTypes, proceduresToIsExternal,
                functionsToInputTypes, functionsToOutputType, functionsToIsExternal);

            ///////////////////////////////////////////////
            // generate external extension source if needed (cause there are external action extension)

            bool isAutoGeneratedFilterExisting;
            bool isExternalFilterFunctionExisting;
            bool isExternalSequenceExisting;
            DetermineWhetherExternalActionsFileIsNeeded(ruleAndMatchingPatterns,
                out isAutoGeneratedFilterExisting, out isExternalFilterFunctionExisting, out isExternalSequenceExisting);

            SourceBuilder externalSource = null;
            if(isAutoGeneratedFilterExisting || isExternalFilterFunctionExisting || isExternalSequenceExisting)
            {
                EmitExternalActionsFileHeader(cc, model, isExternalFilterFunctionExisting || isExternalSequenceExisting,
                    ref externalSource);
            }

            ///////////////////////////////////////////////
            // take action intermediate file until action insertion point as base for action file 

            SourceBuilder source = new SourceBuilder((flags & ProcessSpecFlags.KeepGeneratedFiles) != 0);
            source.Indent();
            source.Indent();

            bool actionPointFound;
            String actionsNamespace;
            result = CopyIntermediateCodeInsertingSequencesCode(cc.actionsFilename, 
                actionTypes, proceduresTypes,
                seqGen, source, out actionPointFound, out actionsNamespace);
            if(result != ErrorType.NoError)
                return result;

            if(!actionPointFound)
            {
                Console.Error.WriteLine("Illegal actions C# input source code: Actions insertion point not found!");
                return ErrorType.GrGenJavaError;
            }

            source.Unindent();
            source.Append("\n");

            ///////////////////////////////////////////////
            // generate and insert the matcher source code into the action file
            // already filled with the content of the action intermediate file until the action insertion point

            String unitName;
            int lastDot = actionsNamespace.LastIndexOf(".");
            if(lastDot == -1) unitName = "";
            else unitName = actionsNamespace.Substring(lastDot + 8);  // skip ".Action_"

            LGSPGraphStatistics graphStatistics = null;
            if(statisticsPath != null)
            {
                Console.WriteLine("Reading graph statistics from {0}", statisticsPath);
                graphStatistics = new LGSPGraphStatistics(model);
                graphStatistics.Parse(statisticsPath);
            }

            GenerateAndInsertMatcherSourceCode(model, cc.actionsName, unitName,
                cc.externalActionsExtensionFilename, ruleAndMatchingPatterns, seqGen,
                isAutoGeneratedFilterExisting, isExternalFilterFunctionExisting, 
                graphStatistics, statisticsPath,
                externalSource, source);

            actionsOutputSource = WriteSourceAndExternalSource(externalSource, source,
                cc.actionsOutputFilename, cc.externalActionsExtensionOutputFilename);
            return ErrorType.NoError;
        }