diff options
| author | Daniel Shaw <t-dansha@microsoft.com> | 2017-07-12 17:40:41 -0700 |
|---|---|---|
| committer | Daniel Shaw <t-dansha@microsoft.com> | 2017-07-14 13:21:25 -0700 |
| commit | 336e25218a73f9b54120e3c35b3d28e6426deeb1 (patch) | |
| tree | 72e2f0fce405def2dcc47b686d4ab7baa5b9afcc /toolsrc/include | |
| parent | 7944f9f7779ebbc0923efd27cff268ac23b1c312 (diff) | |
| download | vcpkg-336e25218a73f9b54120e3c35b3d28e6426deeb1.tar.gz vcpkg-336e25218a73f9b54120e3c35b3d28e6426deeb1.zip | |
feature packages graph traversal
Diffstat (limited to 'toolsrc/include')
| -rw-r--r-- | toolsrc/include/BinaryParagraph.h | 4 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Dependencies.h | 89 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Graphs.h | 93 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Util.h | 1 |
4 files changed, 186 insertions, 1 deletions
diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h index 1c2edf790..4adde5e36 100644 --- a/toolsrc/include/BinaryParagraph.h +++ b/toolsrc/include/BinaryParagraph.h @@ -25,8 +25,10 @@ namespace vcpkg std::string version; std::string description; std::string maintainer; + std::string feature; + std::vector<std::string> default_features; std::vector<std::string> depends; }; void serialize(const BinaryParagraph& pgh, std::string& out_str); -} +}
\ No newline at end of file diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index c8e15de27..92523a654 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -2,6 +2,7 @@ #include "PackageSpec.h" #include "StatusParagraphs.h" #include "VcpkgPaths.h" +#include "vcpkg_Graphs.h" #include "vcpkg_optional.h" #include <vector> @@ -23,6 +24,45 @@ namespace vcpkg::Dependencies Optional<StatusParagraph> status_paragraph; Optional<BinaryParagraph> binary_paragraph; Optional<SourceParagraph> source_paragraph; + Optional<const SourceControlFile*> source_control_file; + }; + + struct ClusterNode + { + std::vector<StatusParagraph> status_paragraphs; + Optional<const SourceControlFile*> source_paragraph; + }; +} + +namespace vcpkg::Dependencies +{ + struct FeatureSpec + { + PackageSpec spec; + std::string feature_name; + }; + + struct FeatureNodeEdges + { + std::vector<FeatureSpec> dotted; + std::vector<FeatureSpec> dashed; + bool plus = false; + }; + std::vector<FeatureSpec> to_feature_specs(const std::vector<std::string> depends, + const std::unordered_map<std::string, PackageSpec> str_to_spec); + struct Cluster + { + ClusterNode cluster_node; + std::unordered_map<std::string, FeatureNodeEdges> edges; + std::unordered_set<std::string> tracked_nodes; + std::unordered_set<std::string> original_nodes; + bool minus = false; + bool zero = true; + Cluster() = default; + + private: + Cluster(const Cluster&) = delete; + Cluster& operator=(const Cluster&) = delete; }; enum class InstallPlanType @@ -39,6 +79,10 @@ namespace vcpkg::Dependencies InstallPlanAction(); InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + std::unordered_set<std::string> features, + const RequestType& request_type); InstallPlanAction(const InstallPlanAction&) = delete; InstallPlanAction(InstallPlanAction&&) = default; InstallPlanAction& operator=(const InstallPlanAction&) = delete; @@ -48,6 +92,7 @@ namespace vcpkg::Dependencies AnyParagraph any_paragraph; InstallPlanType plan_type; RequestType request_type; + std::unordered_set<std::string> feature_list; }; enum class RemovePlanType @@ -73,6 +118,12 @@ namespace vcpkg::Dependencies RequestType request_type; }; + struct AnyAction + { + Optional<InstallPlanAction> install_plan; + Optional<RemovePlanAction> remove_plan; + }; + enum class ExportPlanType { UNKNOWN, @@ -125,3 +176,41 @@ namespace vcpkg::Dependencies const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db); } + +template<> +struct std::hash<vcpkg::Dependencies::Cluster> +{ + size_t operator()(const vcpkg::Dependencies::Cluster& value) const + { + size_t hash = 17; + if (auto source = value.cluster_node.source_paragraph.get()) + { + hash = hash * 31 + std::hash<std::string>()((*source)->core_paragraph->name); + } + else if (!value.cluster_node.status_paragraphs.empty()) + { + auto start = *value.cluster_node.status_paragraphs.begin(); + hash = hash * 31 + std::hash<std::string>()(start.package.displayname()); + } + + return hash; + } +}; + +namespace vcpkg::Dependencies +{ + struct GraphPlan + { + Graphs::Graph<Cluster*> remove_graph; + Graphs::Graph<Cluster*> install_graph; + }; + bool mark_plus(const std::string& feature, + Cluster& cluster, + std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster, + GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, std::unordered_map<PackageSpec, Cluster>& pkg_to_cluster, GraphPlan& graph_plan); + + std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<PackageSpec, SourceControlFile>& map, + const std::vector<FullPackageSpec>& specs, + const StatusParagraphs& status_db); +} 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; + }; } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 1bd1bcc4a..671997e7e 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -1,5 +1,6 @@ #pragma once +#include <map> #include <utility> #include <vector> |
