in DataExtraction/SourceGraphExtractionUtils/GraphDataExtractor.cs [631:683]
private static void GetReachableNodes(SourceGraph graph,
int[] edgeTypeToCost,
int startCostBudget,
SyntaxNodeOrToken startNode,
ICollection<SyntaxNodeOrToken> allowedNodes,
Dictionary<SyntaxNodeOrToken, int> result,
Predicate<Edge<SyntaxNodeOrToken, SourceGraphEdge>> followEdge)
{
var todo = new Stack<(SyntaxNodeOrToken node, int budgetLimit)>();
todo.Push((node: startNode, budgetLimit: startCostBudget));
while (todo.Count > 0)
{
var (node, budgetLimit) = todo.Pop();
var (inEdges, outEdges) = graph.GetEdges(node);
foreach (var edge in inEdges.Where(followEdge.Invoke))
{
var partnerNode = edge.Source;
var edgeCost = edgeTypeToCost[(int)edge.Label];
var newNodeBudget = budgetLimit - edgeCost;
if (newNodeBudget > 0 && allowedNodes.Contains(partnerNode))
{
//Check if we've already reached this with lower cost -- if yes, we can skip the visit.
if (result.TryGetValue(partnerNode, out var oldNodeBudget) && oldNodeBudget >= newNodeBudget)
{
continue;
}
result[partnerNode] = newNodeBudget;
todo.Push((node: partnerNode, budgetLimit: newNodeBudget));
}
}
foreach (var edge in outEdges.Where(followEdge.Invoke))
{
var partnerNode = edge.Target;
var edgeCost = edgeTypeToCost[(int)edge.Label];
var newNodeBudget = budgetLimit - edgeCost;
if (newNodeBudget > 0 && allowedNodes.Contains(partnerNode))
{
//Check if we've already reached this with lower cost -- if yes, we can skip the visit.
if (result.TryGetValue(partnerNode, out var oldNodeBudget) && oldNodeBudget >= newNodeBudget)
{
continue;
}
result[partnerNode] = newNodeBudget;
todo.Push((node: partnerNode, budgetLimit: newNodeBudget));
}
}
}
}