예제 #1
0
        /// <summary>
        /// Collects the roots of the set of graphs that make up the metric type dependencies.
        /// </summary>
        /// <param name="metricType">Type of <see cref="Metric"/> to process.</param>
        /// <param name="roots">List of collected root nodes.</param>
        /// <param name="collectedMetricTypes">Mapping of metric types and their nodes that have been collected so far.</param>
        /// <returns>The <see cref="MetricNode"/> associated with <paramref name="metricType"/>.</returns>
        private static MetricNode CollectMetricTypeGraphs(Type metricType, List <MetricNode> roots, Dictionary <Type, MetricNode> collectedMetricTypes)
        {
            if (collectedMetricTypes.TryGetValue(metricType, out MetricNode metricNode))
            {
                // We've encountered a type that we've processed already.  Ensure that this isn't
                // the result of a cycle in the graph.
                DetectMetricTypeDependencyCycle(metricNode, metricNode);
                return(metricNode);
            }

            List <Type> metricTypeDependencies = GetMetricTypeDependencies(metricType);

            if (!metricTypeDependencies.Any())
            {
                MetricNode root = new MetricNode(metricType);
                roots.Add(root);
                metricNode = root;
                collectedMetricTypes.Add(metricType, metricNode);
            }
            else
            {
                MetricNode node = new MetricNode(metricType);
                collectedMetricTypes.Add(metricType, node);
                foreach (Type dependency in metricTypeDependencies)
                {
                    MetricNode dependencyNode = CollectMetricTypeGraphs(dependency, roots, collectedMetricTypes);
                    dependencyNode.Dependencies.Add(node);
                }

                metricNode = node;
            }

            return(metricNode);
        }
예제 #2
0
        /// <summary>
        /// Sorts the metrics according to their dependencies.
        /// </summary>
        private void SortMetrics()
        {
            this.sortedMetrics = new List <Metric>();
            List <MetricNode>             roots = new List <MetricNode>();
            Dictionary <Type, MetricNode> collectedMetricTypes = new Dictionary <Type, GenFx.GeneticAlgorithm.MetricNode>();

            foreach (Type metricType in this.metrics.Select(m => m.GetType()))
            {
                CollectMetricTypeGraphs(metricType, roots, collectedMetricTypes);
            }

            // Iterate through the nodes in the graphs, breadth first, and add them to the list
            // of sorted metric.  Since we're iterating them in this way, they are inherently sorted.
            Queue <MetricNode> nodesToIterate = new Queue <MetricNode>(roots);

            while (nodesToIterate.Any())
            {
                MetricNode node = nodesToIterate.Dequeue();

                Metric metric = this.metrics.First(m => m.GetType() == node.MetricType);
                this.sortedMetrics.Add(metric);

                foreach (MetricNode dependentNode in node.Dependencies)
                {
                    nodesToIterate.Enqueue(dependentNode);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Detects whether there's a cycle in the metric type dependency graph and throws an exception
        /// if there is.
        /// </summary>
        /// <param name="currentNode">The node to search dependencies of.</param>
        /// <param name="nodeToSearch">The node to search for a match of.</param>
        private static void DetectMetricTypeDependencyCycle(MetricNode currentNode, MetricNode nodeToSearch)
        {
            foreach (MetricNode dependentNode in currentNode.Dependencies)
            {
                if (dependentNode.MetricType == nodeToSearch.MetricType)
                {
                    throw new InvalidOperationException(
                              StringUtil.GetFormattedString(Resources.ErrorMsg_CycleInMetricDependencyGraph, nodeToSearch.MetricType));
                }

                DetectMetricTypeDependencyCycle(dependentNode, nodeToSearch);
            }
        }