Esempio n. 1
0
 internal PeriodTraverseState(
     DelayGraphVertex vertex,
     int delayReturned,
     Queue <DelayGraphEdge> unfinishedEdges,
     int maxAmongOutgoingEdges)
 {
     Vertex                = vertex;
     DelayReturned         = delayReturned;
     UnfinishedEdges       = unfinishedEdges;
     MaxAmongOutgoingEdges = maxAmongOutgoingEdges;
     StateWaitingOn        = null;
 }
Esempio n. 2
0
        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);
        }