|
|
@ -13,7 +13,6 @@ namespace CriticalPathAnalyzer.Server {
|
|
|
|
// Reflection/Delegate access helpers:
|
|
|
|
// Reflection/Delegate access helpers:
|
|
|
|
private static readonly Func<InputPeg, Cluster> GetCluster;
|
|
|
|
private static readonly Func<InputPeg, Cluster> GetCluster;
|
|
|
|
private static readonly Func<Cluster, ClusterLinker> GetLinker;
|
|
|
|
private static readonly Func<Cluster, ClusterLinker> GetLinker;
|
|
|
|
private static readonly Func<ClusterLinker, List<ClusterLinker>> GetLeaders;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly Func<ClusterLinker, List<ClusterLinker>> GetFollowers;
|
|
|
|
private static readonly Func<ClusterLinker, List<ClusterLinker>> GetFollowers;
|
|
|
|
|
|
|
|
|
|
|
@ -28,9 +27,6 @@ namespace CriticalPathAnalyzer.Server {
|
|
|
|
GetLinker = Delegator.createFieldGetter<Cluster, ClusterLinker>(
|
|
|
|
GetLinker = Delegator.createFieldGetter<Cluster, ClusterLinker>(
|
|
|
|
Fields.getPrivate(typeof(Cluster), "Linker")
|
|
|
|
Fields.getPrivate(typeof(Cluster), "Linker")
|
|
|
|
);
|
|
|
|
);
|
|
|
|
GetLeaders = Delegator.createFieldGetter<ClusterLinker, List<ClusterLinker>>(
|
|
|
|
|
|
|
|
Fields.getPrivate(typeof(ClusterLinker), "LinkedLeaders")
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
GetFollowers = Delegator.createFieldGetter<ClusterLinker, List<ClusterLinker>>(
|
|
|
|
GetFollowers = Delegator.createFieldGetter<ClusterLinker, List<ClusterLinker>>(
|
|
|
|
Fields.getPrivate(typeof(ClusterLinker), "LinkedFollowers")
|
|
|
|
Fields.getPrivate(typeof(ClusterLinker), "LinkedFollowers")
|
|
|
|
);
|
|
|
|
);
|
|
|
@ -62,55 +58,23 @@ namespace CriticalPathAnalyzer.Server {
|
|
|
|
return false; // Whoops, cannot collect the primary clusters, probably probing an output peg.
|
|
|
|
return false; // Whoops, cannot collect the primary clusters, probably probing an output peg.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Collect clusters that get powered by the original cluster or will power it.
|
|
|
|
// Collect clusters that get powered by the original cluster by fast buffers
|
|
|
|
var collectedSources = new HashSet<Cluster>();
|
|
|
|
|
|
|
|
var collectedDrains = new HashSet<Cluster>();
|
|
|
|
var collectedDrains = new HashSet<Cluster>();
|
|
|
|
foreach (Cluster cluster in primaryClusters) {
|
|
|
|
foreach (Cluster cluster in primaryClusters) {
|
|
|
|
CollectClusters(cluster, collectedSources, GetLeaders);
|
|
|
|
|
|
|
|
CollectClusters(cluster, collectedDrains, GetFollowers);
|
|
|
|
CollectClusters(cluster, collectedDrains, GetFollowers);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Cluster cluster in primaryClusters) {
|
|
|
|
foreach (Cluster cluster in primaryClusters) {
|
|
|
|
collectedSources.Remove(cluster);
|
|
|
|
|
|
|
|
collectedDrains.Remove(cluster);
|
|
|
|
collectedDrains.Remove(cluster);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Collect and filter clusters that are both source and drain:
|
|
|
|
|
|
|
|
var collectedEquals = new HashSet<Cluster>();
|
|
|
|
|
|
|
|
foreach (Cluster collectedSource in collectedSources) {
|
|
|
|
|
|
|
|
if (collectedDrains.Remove(collectedSource)) {
|
|
|
|
|
|
|
|
collectedEquals.Add(collectedSource);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Cluster collectedEqual in collectedEquals) {
|
|
|
|
|
|
|
|
collectedSources.Remove(collectedEqual);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Collect information about each cluster:
|
|
|
|
//Collect information about each cluster:
|
|
|
|
response = new AnalyzePathResponse() {
|
|
|
|
response = new AnalyzePathResponse() {
|
|
|
|
RequestGuid = requestGuid,
|
|
|
|
RequestGuid = requestGuid,
|
|
|
|
SelectedClusters = new List<ClusterDetails>(),
|
|
|
|
Clusters = new List<ClusterDetails>(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
foreach (Cluster cluster in primaryClusters) {
|
|
|
|
response.Clusters.AddRange(primaryClusters.Select(CollectClusterInformation));
|
|
|
|
response.SelectedClusters.Add(CollectClusterInformation(cluster));
|
|
|
|
response.Clusters.AddRange(collectedDrains.Select(CollectClusterInformation));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// response.sourcingClusters = new List<ClusterDetails>();
|
|
|
|
|
|
|
|
// foreach (var cluster in collectedSources) {
|
|
|
|
|
|
|
|
// response.sourcingClusters.Add(CollectClusterInformation(cluster));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// response.connectedClusters = new List<ClusterDetails>();
|
|
|
|
|
|
|
|
// foreach (var cluster in collectedEquals) {
|
|
|
|
|
|
|
|
// response.connectedClusters.Add(CollectClusterInformation(cluster));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// response.drainingClusters = new List<ClusterDetails>();
|
|
|
|
|
|
|
|
// foreach (var cluster in collectedDrains) {
|
|
|
|
|
|
|
|
// response.drainingClusters.Add(CollectClusterInformation(cluster));
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -189,7 +153,7 @@ namespace CriticalPathAnalyzer.Server {
|
|
|
|
|
|
|
|
|
|
|
|
clustersToProcess.Enqueue(startingLinker);
|
|
|
|
clustersToProcess.Enqueue(startingLinker);
|
|
|
|
// While the starting cluster is no source, the algorithm needs to skip it when encountered.
|
|
|
|
// While the starting cluster is no source, the algorithm needs to skip it when encountered.
|
|
|
|
collectedClusters.Add(startingPoint);
|
|
|
|
// collectedClusters.Add(startingPoint);
|
|
|
|
while (clustersToProcess.TryDequeue(out ClusterLinker linkerToCheck)) {
|
|
|
|
while (clustersToProcess.TryDequeue(out ClusterLinker linkerToCheck)) {
|
|
|
|
List<ClusterLinker> listOfLinkedLinkers = linkedLinkerGetter(linkerToCheck); // Is never null.
|
|
|
|
List<ClusterLinker> listOfLinkedLinkers = linkedLinkerGetter(linkerToCheck); // Is never null.
|
|
|
|
foreach (ClusterLinker linkedLinker in listOfLinkedLinkers) {
|
|
|
|
foreach (ClusterLinker linkedLinker in listOfLinkedLinkers) {
|
|
|
@ -216,7 +180,7 @@ namespace CriticalPathAnalyzer.Server {
|
|
|
|
foreach (InputPeg peg in inputPegs) {
|
|
|
|
foreach (InputPeg peg in inputPegs) {
|
|
|
|
details.Pegs.Add(peg.Address);
|
|
|
|
details.Pegs.Add(peg.Address);
|
|
|
|
if (peg.SecretLinks != null && peg.SecretLinks.Any()) {
|
|
|
|
if (peg.SecretLinks != null && peg.SecretLinks.Any()) {
|
|
|
|
// Highlight this component somehow.
|
|
|
|
// Socket
|
|
|
|
details.ConnectingComponents.Add(peg.Address.ComponentAddress);
|
|
|
|
details.ConnectingComponents.Add(peg.Address.ComponentAddress);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -224,6 +188,7 @@ namespace CriticalPathAnalyzer.Server {
|
|
|
|
|| (peg.OneWayPhasicLinksFollowers != null && peg.OneWayPhasicLinksFollowers.Any())
|
|
|
|
|| (peg.OneWayPhasicLinksFollowers != null && peg.OneWayPhasicLinksFollowers.Any())
|
|
|
|
|| (peg.OneWayPhasicLinksLeaders != null && peg.OneWayPhasicLinksLeaders.Any())
|
|
|
|
|| (peg.OneWayPhasicLinksLeaders != null && peg.OneWayPhasicLinksLeaders.Any())
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
|
|
|
|
// Relay / fast buffer
|
|
|
|
details.LinkingComponents.Add(peg.Address.ComponentAddress);
|
|
|
|
details.LinkingComponents.Add(peg.Address.ComponentAddress);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|