private static void GetReachableNodes()

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));
                    }
                }
            }
        }