Recursion logic and performance tuning
-
I have a uni assignment where I need to recursively process a large number of nodes in a dependency graph in order to calculate the ripple impact. I have come up with a solution that I think is correct, however I'm seeking confirmation of whether my logic is correct, and if so, is there any way to make it faster (and yes, I could post this to the forum for this uni subject, but since we'll be put in groups based on how well we do individually I'm reluctant to do so since I could be heading down the right track). First some background info:
Fan-Out metric is the number of classes that a particular class relies
on. Fan-In metric is the number of classes that make use of a given class.
The ripple impact measure counts the total number of classes that might
have an impact when any single class is changed. Based on the dependency
graph above, if we were to modify “E”, the ripple will impact B directly,
since B has an impact this will impact A as well. In short any change made
to ‘E’ can have a potential ripple impact on B and A.The nodes in the dependency graph that have a Fan-Out of Zero are known as
a Sink node. Nodes that have a Fan-In of zero are known as Source nodes.In the dependency graph shown, we can extract the following information:
• A: Fan-out = 1 [B], Fan-In = 0, Impact-Ripple = 0
• B: Fan-Out = 3 [D, E, F], Fan-In = 1 [A], Impact-Ripple = 1 [A]
• C: Fan-Out = 1 [D], Fan-In = 1 [F], Impact-Ripple = 4 [F, D, B, A]
• D: Fan-Out = 1 [F], Fan-In = 2 [C, B], Impact-Ripple = 4 [B,A,C, F]
• E: Fan-Out = 0, Fan-In = 1, Impact-Ripple = 2 [B,A]
• F: Fan-Out = 1, Fan-In = 2, Impact-Ripple = 4 [B,D,A,C]
• Sink nodes: E, Source nodes: ASo in order to calculate the ripple impact you need to recurse through a node's fan-in nodes and add them to a list unless you either a) run into a source node or b) find a node you've already processed. Here's what I have so far:
public class Node
{
...public List<Node> FanIn
{
get
{
return this.fanIn;
}
}public HashSet<Node> Ripple
{
get
{
HashSet<Node> rippleSet = new HashSet<Node>();// add this node for easy cycle checking so we don't // process ourself twice rippleSet.Add(this); // call our recursive function this.CalcRipple(rippleSet); // remember to remove us so we don't skew the result