internal PeriodTraverseState( DelayGraphVertex vertex, int delayReturned, Queue <DelayGraphEdge> unfinishedEdges, int maxAmongOutgoingEdges) { Vertex = vertex; DelayReturned = delayReturned; UnfinishedEdges = unfinishedEdges; MaxAmongOutgoingEdges = maxAmongOutgoingEdges; StateWaitingOn = null; }
private int TraverseForwardCalculatingPeriodIterative2( DelayGraphVertex startingVertex, out bool foundCycle) { Stack <PeriodTraverseState> stack = new Stack <PeriodTraverseState>(); stack.Push(new PeriodTraverseState(startingVertex)); PeriodTraverseState currentState = null; foundCycle = false; while (stack.Any()) { currentState = stack.Peek(); int alreadyComputedDelay = 0; if (ComputedDelays.TryGetValue(currentState.Vertex, out alreadyComputedDelay)) // put in for reconvergent paths { currentState.DelayReturned = alreadyComputedDelay; stack.Pop(); continue; } if (currentState.StateWaitingOn == null) // this state is used here just to tell if we are coming along here b/c we need to attend to unfinished business where we might have already set 'visited' { if (Visiting.Contains(currentState.Vertex)) // stop recursing if we're going along a loop, but still add up the delays of the loop { currentState.DelayReturned = 0; foundCycle = true; stack.Pop(); continue; } Visiting.Add(currentState.Vertex); } if (currentState.UnfinishedEdges == null) { IEnumerable <DelayGraphEdge> foundOutgoingEdges; if (Graph.TryGetOutEdges(currentState.Vertex, out foundOutgoingEdges)) { currentState.UnfinishedEdges = new Queue <DelayGraphEdge>(foundOutgoingEdges); } } bool done = true; while (currentState.UnfinishedEdges != null && currentState.UnfinishedEdges.Any()) { var outEdge = currentState.UnfinishedEdges.Peek(); int delayOnThisPath; if (Registered(outEdge.Target)) // stop recursing when we hit a register { delayOnThisPath = outEdge.Delay; } else if (Visiting.Contains(outEdge.Target)) { // found a cycle foundCycle = true; delayOnThisPath = outEdge.Delay; } else { if (currentState.StateWaitingOn == null) { currentState.StateWaitingOn = new PeriodTraverseState(outEdge.Target); stack.Push(currentState.StateWaitingOn); done = false; // need to process what we just pushed break; } else { delayOnThisPath = outEdge.Delay + currentState.StateWaitingOn.DelayReturned; currentState.StateWaitingOn = null; } } currentState.UnfinishedEdges.Dequeue(); currentState.MaxAmongOutgoingEdges = Math.Max(currentState.MaxAmongOutgoingEdges, delayOnThisPath); } if (done) { ComputedDelays[currentState.Vertex] = currentState.MaxAmongOutgoingEdges; currentState.DelayReturned = currentState.MaxAmongOutgoingEdges; Visiting.Remove(currentState.Vertex); stack.Pop(); } } return(currentState.DelayReturned); }