| 748 | } |
| 749 | |
| 750 | void cmGlobalFastbuildGenerator::TopologicalSort( |
| 751 | std::vector<FastbuildTargetPtrT>& nodes) |
| 752 | { |
| 753 | std::unordered_map<std::string, int> inDegree; |
| 754 | std::unordered_map<std::string, std::set<std::string>> reverseDeps; |
| 755 | std::unordered_map<std::string, std::size_t> originalIndex; |
| 756 | |
| 757 | // Track original positions |
| 758 | for (std::size_t i = 0; i < nodes.size(); ++i) { |
| 759 | auto const& node = nodes[i]; |
| 760 | inDegree[node->Name] = 0; |
| 761 | originalIndex[node->Name] = i; |
| 762 | } |
| 763 | |
| 764 | // Build reverse dependency graph and in-degree map |
| 765 | for (auto const& node : nodes) { |
| 766 | for (auto const& dep : node->PreBuildDependencies) { |
| 767 | if (inDegree.count(dep.Name)) { |
| 768 | reverseDeps[dep.Name].insert(node->Name); |
| 769 | ++inDegree[node->Name]; |
| 770 | } |
| 771 | } |
| 772 | } |
| 773 | |
| 774 | // Min-heap based on original position |
| 775 | auto const cmp = [&](std::string const& a, std::string const& b) { |
| 776 | return originalIndex[a] > originalIndex[b]; |
| 777 | }; |
| 778 | std::priority_queue<std::string, std::vector<std::string>, decltype(cmp)> |
| 779 | zeroInDegree(cmp); |
| 780 | |
| 781 | for (auto const& val : inDegree) { |
| 782 | auto const& degree = val.second; |
| 783 | auto const& name = val.first; |
| 784 | if (degree == 0) { |
| 785 | zeroInDegree.push(name); |
| 786 | } |
| 787 | } |
| 788 | |
| 789 | std::vector<std::string> sorted; |
| 790 | while (!zeroInDegree.empty()) { |
| 791 | std::string node = zeroInDegree.top(); |
| 792 | zeroInDegree.pop(); |
| 793 | sorted.push_back(node); |
| 794 | for (auto const& dep : reverseDeps[node]) { |
| 795 | if (--inDegree[dep] == 0) { |
| 796 | zeroInDegree.push(dep); |
| 797 | } |
| 798 | } |
| 799 | } |
| 800 | |
| 801 | if (sorted.size() != nodes.size()) { |
| 802 | cmSystemTools::Error("Failed to sort (Cyclic dependency)"); |
| 803 | cmSystemTools::Error(cmStrCat("Sorted size: ", sorted.size())); |
| 804 | cmSystemTools::Error(cmStrCat("nodes size: ", nodes.size())); |
| 805 | for (auto const& node : nodes) { |
| 806 | cmSystemTools::Error("Node: " + node->Name); |
| 807 | for (auto const& dep : reverseDeps[node->Name]) { |
nothing calls this directly
no test coverage detected