summaryrefslogtreecommitdiff
path: root/apt-pkg/solver3.cc
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2025-02-05 20:11:35 +0100
committerJulian Andres Klode <julian.klode@canonical.com>2025-02-14 19:04:56 +0100
commitf870bd44522d195199987b0e073d495eed060495 (patch)
tree95712c5a45e6118e5a3d787b82a735a5c68bc4bf /apt-pkg/solver3.cc
parent50f1335212909962b9bba8db74e8be005a55f4e1 (diff)
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.
Diffstat (limited to 'apt-pkg/solver3.cc')
-rw-r--r--apt-pkg/solver3.cc32
1 files changed, 20 insertions, 12 deletions
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;