public void Initialize(Memory <byte> nodeStatesWorkBuffer, int nodeCount) { int workBufferSize = GetWorkBufferSize(nodeCount); Debug.Assert(nodeStatesWorkBuffer.Length >= workBufferSize); _nodeCount = nodeCount; int edgeMatrixWorkBufferSize = EdgeMatrix.GetWorkBufferSize(nodeCount); _discovered.Initialize(nodeStatesWorkBuffer.Slice(0, edgeMatrixWorkBufferSize), nodeCount); _finished.Initialize(nodeStatesWorkBuffer.Slice(edgeMatrixWorkBufferSize, edgeMatrixWorkBufferSize), nodeCount); nodeStatesWorkBuffer = nodeStatesWorkBuffer.Slice(edgeMatrixWorkBufferSize * 2); _resultArray = SpanMemoryManager <int> .Cast(nodeStatesWorkBuffer.Slice(0, sizeof(int) * nodeCount)); nodeStatesWorkBuffer = nodeStatesWorkBuffer.Slice(sizeof(int) * nodeCount); Memory <int> stackWorkBuffer = SpanMemoryManager <int> .Cast(nodeStatesWorkBuffer.Slice(0, Stack.CalcBufferSize(nodeCount *nodeCount))); _stack.Reset(stackWorkBuffer, nodeCount * nodeCount); }
public NodeStates() { _stack = new Stack(); _discovered = new EdgeMatrix(); _finished = new EdgeMatrix(); }
public static int GetWorkBufferSize(int nodeCount) { return(Stack.CalcBufferSize(nodeCount * nodeCount) + 0xC * nodeCount + 2 * EdgeMatrix.GetWorkBufferSize(nodeCount)); }
public bool Sort(EdgeMatrix edgeMatrix) { Reset(); if (_nodeCount <= 0) { return(true); } for (int i = 0; i < _nodeCount; i++) { if (GetState(i) == NodeState.Unknown) { _stack.Push(i); } while (_stack.GetCurrentCount() > 0) { int topIndex = _stack.Top(); NodeState topState = GetState(topIndex); if (topState == NodeState.Discovered) { SetState(topIndex, NodeState.Finished); PushTsortResult(topIndex); _stack.Pop(); } else if (topState == NodeState.Finished) { _stack.Pop(); } else { if (topState == NodeState.Unknown) { SetState(topIndex, NodeState.Discovered); } for (int j = 0; j < edgeMatrix.GetNodeCount(); j++) { if (edgeMatrix.Connected(topIndex, j)) { NodeState jState = GetState(j); if (jState == NodeState.Unknown) { _stack.Push(j); } // Found a loop, reset and propagate rejection. else if (jState == NodeState.Discovered) { Reset(); return(false); } } } } } } return(true); }