Let's consider a simple graph represented by the following edges, where true indicates a visible node and false indicates a non-visible node:
A (true) -> B (false)
B (false) -> C (true)
C (true) -> D (true)
The expected output of the CompressPaths method for this graph would be a list of EdgeColumn objects representing the following compressed paths:
A -> C
C -> D
Assumptions:
- The path always begins and ends with visible nodes: This is not valid: A (false) -> B(true) or A (true) -> B (false) -> C (false).
In simple words: for each start visible node, I'm finding the nearest visible node and add it them both (start and next) to the final result.
public class EdgeCompression
{
private Dictionary<string, List<Edge>> _edgesMap = new Dictionary<string, List<Edge>>();
public List<Edge> CompressPaths(List<Edge> edges)
{
if (edges == null) throw new ArgumentNullException(nameof(edges));
var result = new List<Edge>();
foreach (var edge in edges)
{
if (!_edgesMap.ContainsKey(edge.StartNode))
{
_edgesMap[edge.StartNode] = new List<Edge>();
}
_edgesMap[edge.StartNode].Add(edge);
}
foreach (var edge in edges)
{
if (edge.StartNodeVisible)
{
FindAndNextVisibleNode(edge.StartNode, edge, result, new HashSet<string>());
}
}
return result;
}
private void FindAndNextVisibleNode(string sourceObjectGUID, Edge edge, List<Edge> result, HashSet<string> visitedNodes)
{
if (!visitedNodes.Add(edge.NextNode)) return;
if (edge.NextNodeVisible)
{
result.Add(new Edge
{
StartNode = sourceObjectGUID,
NextNode = edge.NextNode,
StartNodeVisible = true,
NextNodeVisible = true
});
}
else
{
if (_edgesMap.ContainsKey(edge.NextNode))
{
foreach (var nextEdge in _edgesMap[edge.NextNode])
{
FindAndNextVisibleNode(sourceObjectGUID, nextEdge, result);
}
}
}
}
}
public class Edge
{
public string StartNode { get; set; }
public string NextNode { get; set; }
public bool StartNodeVisible { get; set; }
public bool NextNodeVisible { get; set; }
}
I'm looking for feedback on:
- Any potential performance issues with large datasets.
- Ways to improve the recursion logic, especially concerning handling cycles and preventing infinite recursion (the visited logic).
I've tried to acheive the same result within sql with no success