示例#1
0
        // topologically sort the graph to work out calculation order
        public Dictionary <string, int> CalculateWeights()
        {
            var remainingNodes = new SortedSet <int>(Nodes.Select(n => n.ID).Union(KeyNodes.Select(k => k.Value.ID)));
            var markedNodes    = new SortedSet <int>();
            var processors     = Nodes.ToDictionary(n => n.ID, n => RFGraphDefinition.GetFullName(n.GraphName, n.Label));
            var visitOrder     = new List <int>();

            while (remainingNodes.Any())
            {
                var remainingNode = remainingNodes.First();
                Visit(remainingNode, markedNodes, remainingNodes, visitOrder);
            }

            var weights = new Dictionary <string, int>();
            int idx     = 1;

            visitOrder.Reverse();
            foreach (var node in visitOrder)
            {
                if (processors.ContainsKey(node))
                {
                    weights.Add(processors[node], idx++);
                }
            }
            return(weights);
        }
示例#2
0
        public Dictionary <string, SortedSet <string> > CalculateDependencies()
        {
            // for each node list nodes it depends on (i.e. reverse traverse)
            var processors   = Nodes.ToDictionary(n => n.ID, n => RFGraphDefinition.GetFullName(n.GraphName, n.Label));
            var dependencies = new Dictionary <string, SortedSet <string> >();

            foreach (var node in Nodes)
            {
                var visited = new SortedSet <int>();
                var toVisit = new SortedSet <int>(Edges.Where(e => e.DestinationNode == node.ID).Select(e => e.SourceNode));
                while (toVisit.Any())
                {
                    var next = toVisit.First();
                    toVisit.Remove(next);
                    if (!visited.Contains(next))
                    {
                        visited.Add(next);
                        foreach (var source in Edges.Where(e => e.DestinationNode == next).Select(e => e.SourceNode))
                        {
                            if (!visited.Contains(source))
                            {
                                toVisit.Add(source);
                            }
                        }
                    }
                }
                dependencies.Add(processors[node.ID], new SortedSet <string>(visited.Where(v => processors.ContainsKey(v)).Select(v => processors[v])));
            }
            return(dependencies);
        }
示例#3
0
        protected void AddGraph(RFGraphDefinition graphConfig)
        {
            foreach (var graphProcess in graphConfig.Processes.Values)
            {
                var graphProcessName = RFGraphDefinition.GetFullName(graphConfig.GraphName, graphProcess.Name);
                _processes.Add(graphProcessName,
                               new RFEngineProcess(graphProcessName,
                                                   new RFEngineProcessDefinition
                {
                    InstanceParams = i => i.ExtractParam().ConvertTo <RFEngineProcessorGraphInstanceParam>(),
                    Name           = graphProcessName,
                    Description    = graphProcess.Description,
                    Processor      = () => new RFGraphProcess(graphProcess)
                }, _config.KeyDomain));

                // check for missing inputs
                foreach (var p in graphProcess.Processor().CreateDomain().GetType().GetProperties())
                {
                    if (RFReflectionHelpers.IsMandatory(p) && graphProcess.IOMappings.SingleOrDefault(m => m.Property.FullName() == p.FullName()) == null)
                    {
                        throw new RFSystemException(this, "Unmapped mandatory property {0} on processor {1}", p.FullName(), graphProcessName);
                    }
                }

                // auto-react to inputs
                foreach (var ioMapping in graphProcess.IOMappings)
                {
                    var ioBehaviour   = ioMapping.Property.GetCustomAttributes(typeof(RFIOBehaviourAttribute), true).FirstOrDefault() as RFIOBehaviourAttribute;
                    var dateBehaviour = ioMapping.DateBehaviour;
                    if (ioBehaviour != null && ioBehaviour.IOBehaviour == RFIOBehaviour.Input)
                    {
                        switch (dateBehaviour)
                        {
                        case RFDateBehaviour.Range:
                            _reactors.Add(RFGraphReactor.RangeReactor(ioMapping.Key, graphProcessName, _context.GetReadingContext(), ioMapping.RangeUpdateFunc, graphProcess.Processor().MaxInstance));
                            break;

                        case RFDateBehaviour.Exact:
                        case RFDateBehaviour.Latest:
                        case RFDateBehaviour.Previous:
                            _reactors.Add(RFGraphReactor.SimpleReactor(ioMapping.Key, dateBehaviour, graphProcessName, _context.GetReadingContext(), graphProcess.Processor().MaxInstance));
                            break;
                        }
                    }
                }
            }
        }
示例#4
0
        protected RFGraphProcessDefinition AddIOMapping <S>(Expression <Func <S, object> > property, RFCatalogKey key, RFIOBehaviour expectedBehvaiour, Func <RFGraphInstance, List <RFDate> > rangeRequestFunc = null,
                                                            Func <RFGraphInstance, RFDate> rangeUpdateFunc = null) where S : RFGraphProcessorDomain
        {
            var processor = Processor();
            var domain    = processor.CreateDomain();

            if (domain.GetType() != typeof(S))
            {
                throw new RFLogicException(this, "IO Domain Type mismatch on processor {0}: {1} vs {2}", RFGraphDefinition.GetFullName(GraphName, Name),
                                           domain.GetType().Name, typeof(S).Name);
            }

            var propertyInfo = property.GetProperty <S>();
            var ioBehaviour  = RFReflectionHelpers.GetIOBehaviour(propertyInfo);

            if (ioBehaviour != expectedBehvaiour)
            {
                throw new RFLogicException(this, "Inconsistent IO direction {0} on property {1}, expected {2}.", ioBehaviour, propertyInfo.FullName(), expectedBehvaiour);
            }
            var dateBehaviour = RFReflectionHelpers.GetDateBehaviour(propertyInfo);

            if (dateBehaviour == RFDateBehaviour.Range && (rangeRequestFunc == null || rangeUpdateFunc == null))
            {
                throw new RFLogicException(this, "Range input doesn't have range functions specified on property {0}.", propertyInfo.FullName());
            }
            IOMappings.Add(new RFGraphIOMapping {
                Key = key, Property = propertyInfo, RangeRequestFunc = rangeRequestFunc, RangeUpdateFunc = rangeUpdateFunc, DateBehaviour = dateBehaviour
            });
            return(this);
        }
示例#5
0
        public static RFGraphMap MapGraphs(IEnumerable <RFGraphDefinition> graphs, bool forPresentation = true)
        {
            var map = new RFGraphMap();

            foreach (var graph in graphs)
            {
                foreach (var process in graph.Processes)
                {
                    var name        = RFGraphDefinition.GetFullName(graph.GraphName, process.Value.Name);
                    var processNode = new RFGraphMapNode(map)
                    {
                        Label       = process.Value.Name,
                        GraphName   = graph.GraphName,
                        NodeType    = RFGraphMapNodeType.Processor,
                        FullType    = process.Value.Processor().GetType().Name,
                        Description = process.Value.Description
                    };
                    map.Nodes.Add(processNode);
                    foreach (var ioMapping in process.Value.IOMappings)
                    {
                        if (ioMapping.PropertyName == "Status")
                        {
                            continue;
                        }

                        var ioBehaviour   = RFReflectionHelpers.GetIOBehaviour(ioMapping.Property);
                        var dateBehaviour = ioMapping.DateBehaviour; //RFReflectionHelpers.GetDateBehaviour(ioMapping.Property);
                        if (!forPresentation)
                        {
                            // for graph sort we are only interested in exact date inputs and
                            // outputs, which should result in acycylical graph
                            if (ioBehaviour == RFIOBehaviour.State)
                            {
                                continue;
                            }
                            if (dateBehaviour != RFDateBehaviour.Exact && dateBehaviour != RFDateBehaviour.Range && dateBehaviour != RFDateBehaviour.Latest)
                            {
                                continue;
                            }
                        }
                        if (ioMapping.Key != null)
                        {
                            var rawKeyString = KeyLabel(ioMapping.Key.CreateForInstance(null));
                            var keyLabel     = forPresentation ? graph.GraphName + rawKeyString : rawKeyString;
                            if (!map.KeyNodes.ContainsKey(keyLabel))
                            {
                                map.KeyNodes.Add(keyLabel, new RFGraphMapNode(map)
                                {
                                    Label       = rawKeyString,
                                    RawKey      = rawKeyString,
                                    NodeType    = RFGraphMapNodeType.Key,
                                    GraphName   = graph.GraphName,
                                    FullType    = ioMapping.Key.CreateForInstance(null).GetType().Name,
                                    Description = ""
                                });
                            }
                            var keyNode = map.KeyNodes[keyLabel];
                            if (ioBehaviour == RFIOBehaviour.Input || ioBehaviour == RFIOBehaviour.State)
                            {
                                map.Edges.Add(new RFGraphMapEdge
                                {
                                    SourceNode      = keyNode.ID,
                                    DestinationNode = processNode.ID,
                                    Label           = ioMapping.PropertyName,
                                    EdgeType        = ioBehaviour == RFIOBehaviour.Input ? RFGraphMapEdgeType.Input : RFGraphMapEdgeType.State
                                });
                                keyNode.Description += string.Format("{0} to {1} ({2})<br/>", ioBehaviour, processNode.Label, ioMapping.PropertyName);
                            }
                            if (ioBehaviour == RFIOBehaviour.Output)
                            {
                                map.Edges.Add(new RFGraphMapEdge
                                {
                                    SourceNode      = processNode.ID,
                                    DestinationNode = keyNode.ID,
                                    Label           = ioMapping.PropertyName,
                                    EdgeType        = RFGraphMapEdgeType.Output
                                });
                                keyNode.Description += string.Format("{0} of {1} ({2})<br/>", ioBehaviour, processNode.Label, ioMapping.PropertyName);
                            }
                        }
                        else
                        {
                            // unbound item? check for other domain properties?
                        }
                    }
                }
            }
            return(map);
        }
示例#6
0
 public override string FriendlyString()
 {
     return(RFGraphDefinition.GetFullName(GraphName, ProcessName));
 }