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 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'apt-pkg/solver3.cc') 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; -- cgit v1.2.3-70-g09d2