aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include/vcpkg_Graphs.h
diff options
context:
space:
mode:
authorDaniel Shaw <danielshaw1212@gmail.com>2017-07-24 16:11:22 -0700
committerGitHub <noreply@github.com>2017-07-24 16:11:22 -0700
commitb277b4dda3a2793fd59a6cca5de96f8bc65f1357 (patch)
tree67299d7ae4d032948d4d65a2f494b61fac025b0a /toolsrc/include/vcpkg_Graphs.h
parent3c841c6128ebfe8e99a372f2907bd985b533a799 (diff)
parent59389ca236b005922cf1101f66c957d2396f6371 (diff)
downloadvcpkg-b277b4dda3a2793fd59a6cca5de96f8bc65f1357.tar.gz
vcpkg-b277b4dda3a2793fd59a6cca5de96f8bc65f1357.zip
Merge pull request #1461 from Microsoft/create_install_tests
feature packages graph algorithm
Diffstat (limited to 'toolsrc/include/vcpkg_Graphs.h')
-rw-r--r--toolsrc/include/vcpkg_Graphs.h93
1 files changed, 93 insertions, 0 deletions
diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h
index 3c8c024c2..13c0a7136 100644
--- a/toolsrc/include/vcpkg_Graphs.h
+++ b/toolsrc/include/vcpkg_Graphs.h
@@ -1,6 +1,7 @@
#pragma once
#include <unordered_map>
+#include <unordered_set>
namespace vcpkg::Graphs
{
@@ -63,4 +64,96 @@ namespace vcpkg::Graphs
return sorted;
}
+
+ template<class V>
+ struct GraphAdjacencyProvider final : AdjacencyProvider<V, V>
+ {
+ const std::unordered_map<V, std::unordered_set<V>>& vertices;
+
+ GraphAdjacencyProvider(const std::unordered_map<V, std::unordered_set<V>>& vertices) : vertices(vertices) {}
+
+ std::vector<V> adjacency_list(const V& vertex) const override
+ {
+ const std::unordered_set<V>& as_set = this->vertices.at(vertex);
+ return std::vector<V>(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy
+ }
+
+ V load_vertex_data(const V& vertex) const override { return vertex; }
+ };
+
+ template<class V>
+ struct Graph
+ {
+ public:
+ void add_vertex(V v) { this->vertices[v]; }
+
+ // TODO: Change with iterators
+ void add_vertices(const std::vector<V>& vs)
+ {
+ for (const V& v : vs)
+ {
+ this->vertices[v];
+ }
+ }
+
+ void add_edge(V u, V v)
+ {
+ this->vertices[v];
+ this->vertices[u].insert(v);
+ }
+
+ std::vector<V> topological_sort() const
+ {
+ GraphAdjacencyProvider<V> adjacency_provider{this->vertices};
+ std::unordered_map<V, int> indegrees = count_indegrees();
+
+ std::vector<V> sorted;
+ sorted.reserve(indegrees.size());
+
+ std::unordered_map<V, ExplorationStatus> exploration_status;
+ exploration_status.reserve(indegrees.size());
+
+ for (auto& pair : indegrees)
+ {
+ if (pair.second == 0) // Starting from vertices with indegree == 0. Not required.
+ {
+ V vertex = pair.first;
+ topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted);
+ }
+ }
+
+ return sorted;
+ }
+
+ std::unordered_map<V, int> count_indegrees() const
+ {
+ std::unordered_map<V, int> indegrees;
+
+ for (auto& pair : this->vertices)
+ {
+ indegrees[pair.first];
+ for (V neighbour : pair.second)
+ {
+ ++indegrees[neighbour];
+ }
+ }
+
+ return indegrees;
+ }
+
+ const std::unordered_map<V, std::unordered_set<V>>& adjacency_list() const { return this->vertices; }
+ std::vector<V> vertex_list() const
+ {
+ // why no &? it returns 0
+ std::vector<V> vertex_list;
+ for (const auto& vertex : this->vertices)
+ {
+ vertex_list.emplace_back(vertex.first);
+ }
+ return vertex_list;
+ }
+
+ private:
+ std::unordered_map<V, std::unordered_set<V>> vertices;
+ };
}