/// <summary> /// find and return the maximum cyclic throughput cost /// </summary> /// <param name="sort">topological sorted enumerable of vertices</param> /// <param name="graph">a delay graph</param> /// <param name="registered">a hash set containing registered vertices</param> /// <returns>a value representing maximum throughput cost of all cycles</returns> internal static long FindMaxThroughputCostCore(IEnumerable <DelayGraphVertex> sort, DelayGraph graph, HashSet <DelayGraphVertex> registered) { long maxCycleCost = 0; var table = new WaveFrontDictionary <Dictionary <DelayGraphVertex, long> >(); foreach (var v in sort) { var inEdges = graph.GetForwardInEdges(v); var outEdges = graph.GetForwardOutEdges(v); var feedbackInEdges = graph.GetFeedbackInEdges(v); var feedbackOutEdges = graph.GetFeedbackOutEdges(v); int myRefCount = outEdges.Count(); long cost = GetThroughputCost(v, registered); Dictionary <DelayGraphVertex, long> myData = null; // first, consume predecessor's wavefront data, if any foreach (var e in inEdges) { var p = e.Source; var data = table.Use(p); if (data == null) { continue; } // copy data into myData myData = GetOrMakeMyData(table, v, myRefCount, myData); UpdateMaxData(myData, data); } if (cost > 0 && myData != null) { // incr all costs in myData by cost foreach (var p in myData.Keys.ToList()) { myData[p] += cost; } } if (feedbackInEdges.Any()) { // v is start of cycle - enter v into myData myData = GetOrMakeMyData(table, v, myRefCount, myData); myData[v] = cost; } if (myData == null) { continue; } // update max cycle cost foreach (var e in feedbackOutEdges) { var p = e.Target; long cycleCost; if (myData.TryGetValue(p, out cycleCost) && cycleCost > maxCycleCost) { maxCycleCost = cycleCost; } } } return(maxCycleCost); }