From 7f79f44b0c7084a80af541db04c54f3d1e95316c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 18:55:37 -0700 Subject: [PATCH] Rework create_install_plan() --- toolsrc/src/vcpkg_Dependencies.cpp | 96 +++++++++++++++++------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 4c0254ae4c..a2d7dcc7f7 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -6,6 +6,7 @@ #include "StatusParagraphs.h" #include "vcpkg_Files.h" #include "vcpkg_Util.h" +#include "vcpkglib.h" namespace vcpkg::Dependencies { @@ -119,7 +120,7 @@ namespace vcpkg::Dependencies const VcpkgPaths& paths; const StatusParagraphs& status_db; - InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs & s) : paths(p) + InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s) : paths(p) , status_db(s) {} std::vector adjacency_list(const AnyParagraph& p) const override @@ -147,9 +148,9 @@ namespace vcpkg::Dependencies } }; - auto toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); + const std::vector toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); - std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector ret; for (const AnyParagraph& pkg : toposort) { @@ -163,58 +164,69 @@ namespace vcpkg::Dependencies return ret; } + struct SpecAndRemovePlanType + { + PackageSpec spec; + RemovePlanType plan_type; + }; + std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) { - std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - - std::unordered_map was_examined; // Examine = we have checked its immediate (non-recursive) dependencies - Graphs::Graph graph; - graph.add_vertices(specs); - - std::vector examine_stack(specs); - while (!examine_stack.empty()) + struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider { - const PackageSpec spec = examine_stack.back(); - examine_stack.pop_back(); + const StatusParagraphs& status_db; + const std::vector& installed_ports; - if (was_examined.find(spec) != was_examined.end()) + RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector& installed_ports) + : status_db(status_db) + , installed_ports(installed_ports) { } + + std::vector adjacency_list(const SpecAndRemovePlanType& p) const override { - continue; - } - - const StatusParagraphs::const_iterator it = status_db.find_installed(spec); - if (it == status_db.end()) - { - was_examined.emplace(spec, RemovePlanAction(RemovePlanType::NOT_INSTALLED, RequestType::USER_REQUESTED)); - continue; - } - - const std::vector installed_ports = get_installed_ports(status_db); - for (const StatusParagraph* an_installed_package : installed_ports) - { - if (an_installed_package->package.spec.triplet() != spec.triplet()) - continue; - - const std::vector& deps = an_installed_package->package.depends; - if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) + if (p.plan_type == RemovePlanType::NOT_INSTALLED) { - continue; + return {}; } - graph.add_edge(spec, an_installed_package->package.spec); - examine_stack.push_back(an_installed_package->package.spec); + const PackageSpec& spec = p.spec; + std::vector dependents; + for (const StatusParagraph* an_installed_package : installed_ports) + { + if (an_installed_package->package.spec.triplet() != spec.triplet()) + continue; + + const std::vector& deps = an_installed_package->package.depends; + if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) + continue; + + dependents.push_back(an_installed_package->package.spec); + } + + return dependents; } - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - was_examined.emplace(spec, RemovePlanAction(RemovePlanType::REMOVE, request_type)); - } + SpecAndRemovePlanType load_vertex_data(const PackageSpec& spec) const override + { + const StatusParagraphs::const_iterator it = status_db.find_installed(spec); + if (it == status_db.end()) + { + return {spec, RemovePlanType::NOT_INSTALLED}; + } + return { spec, RemovePlanType::REMOVE }; + } + }; + const std::vector& installed_ports = get_installed_ports(status_db); + const std::vector toposort = Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports }); + + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector ret; - - const std::vector pkgs = graph.topological_sort(); - for (const PackageSpec& pkg : pkgs) + for (const SpecAndRemovePlanType& pkg : toposort) { - ret.push_back(PackageSpecWithRemovePlan(pkg, std::move(was_examined[pkg]))); + auto spec = pkg.spec; + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; + RemovePlanAction r(pkg.plan_type, request_type); + ret.push_back(PackageSpecWithRemovePlan(spec, std::move(r))); } return ret; }