|
|
|
@ -47,7 +47,7 @@ namespace CriticalPathAnalyzer.Server.Tool {
|
|
|
|
|
ILogicLogger logger = CriticalPathAnalyzerServer.LoggerInstance;
|
|
|
|
|
response = null;
|
|
|
|
|
|
|
|
|
|
logger.Info("Trace start");
|
|
|
|
|
logger.Info($"Trace start from {start} to {end}");
|
|
|
|
|
|
|
|
|
|
// Validate, that the peg is actually existing:
|
|
|
|
|
if (!PegExists(start) || !PegExists(end)) {
|
|
|
|
@ -57,7 +57,7 @@ namespace CriticalPathAnalyzer.Server.Tool {
|
|
|
|
|
|
|
|
|
|
var clusterNodes = new List<ClusterNode>();
|
|
|
|
|
var clusterToNodeMapping = new Dictionary<Cluster, int>(); // Cluster / index of node
|
|
|
|
|
var queue = new Queue<(Cluster, int)>();
|
|
|
|
|
var queue = new Queue<ClusterNode>();
|
|
|
|
|
|
|
|
|
|
// An input peg, only has a single cluster.
|
|
|
|
|
// An output peg however can be connected to multiple clusters.
|
|
|
|
@ -65,90 +65,97 @@ namespace CriticalPathAnalyzer.Server.Tool {
|
|
|
|
|
var collectedClusters = new HashSet<Cluster>();
|
|
|
|
|
CollectMainClusters(start, collectedClusters);
|
|
|
|
|
|
|
|
|
|
foreach (Cluster cluster in collectedClusters) {
|
|
|
|
|
queue.Enqueue((cluster, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Info($"collected {collectedClusters.Count} main clusters");
|
|
|
|
|
|
|
|
|
|
int iters = 0;
|
|
|
|
|
while (queue.TryDequeue(out (Cluster, int) item)) {
|
|
|
|
|
iters++;
|
|
|
|
|
if (iters > 100000) {
|
|
|
|
|
logger.Error("Infinite iterations");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(Cluster cluster, int time) = item;
|
|
|
|
|
|
|
|
|
|
logger.Warn(">> cluster iter <<");
|
|
|
|
|
|
|
|
|
|
if (clusterToNodeMapping.ContainsKey(cluster)) {
|
|
|
|
|
logger.Info("already mapped, continuing");
|
|
|
|
|
foreach (Cluster startingCluster in collectedClusters) {
|
|
|
|
|
// ignore already mapped clusters
|
|
|
|
|
if (clusterToNodeMapping.ContainsKey(startingCluster)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Collect clusters that get powered by the original cluster using relays or fast buffers
|
|
|
|
|
// var nextClusters = new HashSet<Cluster>();
|
|
|
|
|
// var twoWayConnectedClusters = new HashSet<Cluster>();
|
|
|
|
|
//
|
|
|
|
|
// GetLinkedClusters(cluster, nextClusters, twoWayConnectedClusters, GetFollowers);
|
|
|
|
|
|
|
|
|
|
// logger.Info($"collected {nextClusters.Count} one way linked clusters");
|
|
|
|
|
// logger.Info($"collected {twoWayConnectedClusters.Count} two way linked clusters");
|
|
|
|
|
|
|
|
|
|
int index = clusterNodes.Count;
|
|
|
|
|
var node = new ClusterNode() {
|
|
|
|
|
Index = index,
|
|
|
|
|
Clusters = new List<Cluster>() {startingCluster},
|
|
|
|
|
Time = 0,
|
|
|
|
|
PrevNodeIndex = null,
|
|
|
|
|
NextNodes = new Dictionary<int, int>(),
|
|
|
|
|
};
|
|
|
|
|
clusterNodes.Add(node);
|
|
|
|
|
foreach (Cluster cluster in node.Clusters) {
|
|
|
|
|
clusterToNodeMapping.Add(cluster, index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// foreach (Cluster connectedCluster in twoWayConnectedClusters) {
|
|
|
|
|
// if (!clusterToNodeMapping.TryAdd(connectedCluster, index)) {
|
|
|
|
|
// // already been here
|
|
|
|
|
// logger.Error("Adding already mapped cluster");
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
queue.Enqueue(node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// foreach (Cluster connectedCluster in nextClusters) {
|
|
|
|
|
// var nextClusters = new HashSet<Cluster>();
|
|
|
|
|
// var twoWayConnectedClusters = new HashSet<Cluster>();
|
|
|
|
|
// GetLinkedClusters(connectedCluster, nextClusters, twoWayConnectedClusters, GetFollowers);
|
|
|
|
|
// }
|
|
|
|
|
logger.Info($"collected {collectedClusters.Count} main clusters");
|
|
|
|
|
|
|
|
|
|
clusterToNodeMapping.Add(cluster, index);
|
|
|
|
|
int iters = 0;
|
|
|
|
|
while (queue.TryDequeue(out ClusterNode node)) {
|
|
|
|
|
iters++;
|
|
|
|
|
if (iters > 1000) {
|
|
|
|
|
logger.Error("Infinite iterations");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clusterNodes.Add(new ClusterNode() {
|
|
|
|
|
Index = index,
|
|
|
|
|
Clusters = new List<Cluster>() {cluster},
|
|
|
|
|
Time = index,
|
|
|
|
|
PrevNodeStateId = null,
|
|
|
|
|
NextNodes = new Dictionary<int, int>(),
|
|
|
|
|
});
|
|
|
|
|
logger.Warn(">> cluster node iter <<");
|
|
|
|
|
|
|
|
|
|
// var perimeterComponents = new HashSet<ComponentAddress>();
|
|
|
|
|
var collectedNextClusters = new HashSet<Cluster>();
|
|
|
|
|
foreach (InputPeg inputPeg in cluster.ConnectedInputs) {
|
|
|
|
|
if (inputPeg.LogicComponent == null) {
|
|
|
|
|
// These are regular pegs, they are not attached to any logic component, skip them
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
foreach (Cluster cluster in node.Clusters) {
|
|
|
|
|
foreach (InputPeg inputPeg in cluster.ConnectedInputs) {
|
|
|
|
|
if (inputPeg.LogicComponent == null) {
|
|
|
|
|
// These are regular pegs, they are not attached to any logic component, skip them
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// perimeterComponents.Add(inputPeg.LogicComponent.Address);
|
|
|
|
|
// perimeterComponents.Add(inputPeg.LogicComponent.Address);
|
|
|
|
|
|
|
|
|
|
foreach (IOutputPeg outputPeg in inputPeg.LogicComponent.Outputs) {
|
|
|
|
|
CollectMainClusters(outputPeg.Address, collectedNextClusters);
|
|
|
|
|
foreach (IOutputPeg outputPeg in inputPeg.LogicComponent.Outputs) {
|
|
|
|
|
CollectMainClusters(outputPeg.Address, collectedNextClusters);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (Cluster nextCluster in collectedNextClusters) {
|
|
|
|
|
queue.Enqueue((nextCluster, time + 1));
|
|
|
|
|
}
|
|
|
|
|
// ignore already mapped clusters
|
|
|
|
|
if (clusterToNodeMapping.TryGetValue(nextCluster, out int nextNodeIndex)) {
|
|
|
|
|
// only add the link, don't propagate
|
|
|
|
|
int timeDelay = 1;
|
|
|
|
|
node.NextNodes.Add(nextNodeIndex, 1);
|
|
|
|
|
} else {
|
|
|
|
|
// var nextClusters = new HashSet<Cluster>();
|
|
|
|
|
// var twoWayConnectedClusters = new HashSet<Cluster>();
|
|
|
|
|
// GetLinkedClusters(cluster, nextClusters, twoWayConnectedClusters, GetFollowers);
|
|
|
|
|
int timeDelay = 1;
|
|
|
|
|
nextNodeIndex = clusterNodes.Count;
|
|
|
|
|
var nextNode = new ClusterNode() {
|
|
|
|
|
Index = nextNodeIndex,
|
|
|
|
|
Clusters = new List<Cluster>() {nextCluster},
|
|
|
|
|
Time = node.Time + timeDelay,
|
|
|
|
|
PrevNodeIndex = node.Index,
|
|
|
|
|
NextNodes = new Dictionary<int, int>(),
|
|
|
|
|
};
|
|
|
|
|
node.NextNodes.Add(nextNodeIndex, timeDelay);
|
|
|
|
|
|
|
|
|
|
clusterNodes.Add(nextNode);
|
|
|
|
|
|
|
|
|
|
foreach (Cluster nextNodeCluster in nextNode.Clusters) {
|
|
|
|
|
clusterToNodeMapping.Add(nextNodeCluster, nextNodeIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.Info("collected perimeter components");
|
|
|
|
|
queue.Enqueue(nextNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Collect information about each cluster:
|
|
|
|
|
response = new AnalyzePathResponse() {
|
|
|
|
|
RequestGuid = requestGuid,
|
|
|
|
|
Clusters = clusterNodes.SelectMany(node => node.Clusters.Select(cluster => CollectClusterInformation(cluster, node.Time))).ToList(),
|
|
|
|
|
Clusters = clusterNodes.SelectMany(node =>
|
|
|
|
|
node.Clusters.Select(cluster => CollectClusterInformation(cluster, node.Time))).ToList(),
|
|
|
|
|
// PerimeterComponents = perimeterComponents.ToList(),
|
|
|
|
|
// NextClusters = collectedNextClusters.Select(CollectClusterInformation).ToList(),
|
|
|
|
|
};
|
|
|
|
|