From f870bd44522d195199987b0e073d495eed060495 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 5 Feb 2025 20:11:35 +0100 Subject: solver3: Defer version selection where possible If a dependency can be satisfied by all versions of a package, add the package to the clause instead of the version object. This works only if there are no providers for the package: Providers are quite hard to enumerate over and make sure that all versions of a package satisfy the provider dependency. Implement arbitrary selection between packages and versions for the CompareProviders class: We pick the best version for each package and then pit them against each other. --- apt-pkg/solver3.cc | 32 ++++++++++++++++++++------------ apt-pkg/solver3.h | 2 ++ 2 files changed, 22 insertions(+), 12 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index ed9beb828..ed781df13 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -527,23 +527,31 @@ APT::Solver::Clause APT::Solver::TranslateOrGroup(pkgCache::DepIterator start, p do { auto begin = clause.solutions.size(); - auto all = start.AllTargets(); - for (auto tgt = all; *tgt; ++tgt) + if (DeferVersionSelection && not start.IsNegative() && start.TargetPkg().ProvidesList().end() && start.IsSatisfied(start.TargetPkg())) { - pkgCache::VerIterator tgti(cache, *tgt); - if (unlikely(debug >= 3)) - std::cerr << "Adding work to item " << reason.toString(cache) << " -> " << tgti.ParentPkg().FullName() << "=" << tgti.VerStr() << (clause.negative ? " (negative)" : "") << "\n"; - clause.solutions.push_back(Var(pkgCache::VerIterator(cache, *tgt))); + clause.solutions.push_back(Var(start.TargetPkg())); } - delete[] all; + else + { + auto all = start.AllTargets(); + + for (auto tgt = all; *tgt; ++tgt) + { + pkgCache::VerIterator tgti(cache, *tgt); - // If we are fixing the policy, we need to sort each alternative in an or group separately - // FIXME: This is not really true, though, we should fix the CompareProviders to ignore the - // installed state - if (FixPolicyBroken) - std::stable_sort(clause.solutions.begin() + begin, clause.solutions.end(), CompareProviders3{cache, policy, TgtPkg, *this}); + if (unlikely(debug >= 3)) + std::cerr << "Adding work to item " << reason.toString(cache) << " -> " << tgti.ParentPkg().FullName() << "=" << tgti.VerStr() << (clause.negative ? " (negative)" : "") << "\n"; + clause.solutions.push_back(Var(pkgCache::VerIterator(cache, *tgt))); + } + delete[] all; + // If we are fixing the policy, we need to sort each alternative in an or group separately + // FIXME: This is not really true, though, we should fix the CompareProviders to ignore the + // installed state + if (FixPolicyBroken) + std::stable_sort(clause.solutions.begin() + begin, clause.solutions.end(), CompareProviders3{cache, policy, TgtPkg, *this}); + } if (start == end) break; ++start; diff --git a/apt-pkg/solver3.h b/apt-pkg/solver3.h index 65cd9f017..e43e1065c 100644 --- a/apt-pkg/solver3.h +++ b/apt-pkg/solver3.h @@ -228,6 +228,8 @@ class Solver bool StrictPinning{_config->FindB("APT::Solver::Strict-Pinning", true)}; // \brief If set, we install missing recommends and pick new best packages. bool FixPolicyBroken{_config->FindB("APT::Get::Fix-Policy-Broken")}; + // \brief If set, we use strict pinning. + bool DeferVersionSelection{_config->FindB("APT::Solver::Defer-Version-Selection", true)}; // \brief Discover a variable, translating the underlying dependencies to the SAT presentation void Discover(Var var); -- cgit v1.2.3-70-g09d2