From 295ab44a3063fb7790d8a558a161fc1bd801f998 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 4 Apr 2025 15:25:01 +0200 Subject: solver3: Consider more upgrades more costly when not upgrading We inadvertently considered more upgrades as a better solution in all cases, but if we are *installing* rather than upgrading, we should count upgrades as a negative. Change the code to accomodate that. This requires a few more tricks: - We remove the keep count check. This does not appear to work correctly and would have prevented the fix. We are already counting all possible changes, so why bother. - We need to subtract the upgrade count from the install count (upgrades are a class of installs) since we now allow comparing solutions with different upgrade counts for install counts. - After comparing the "new install count", we now compare upgrade count too, in the opposite direction of upgrading. To test, we abuse that solver 3.0 does not upgrade all packages in a source package when using the install command. LP: #2105395 --- apt-private/private-install.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'apt-private') diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index 7103c6dc7..7c9a27290 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -983,6 +983,7 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vectorFind("APT::Solver", "internal") == "internal" && (not res || (not Cache->FindPkg("apport").end() && Cache->FindPkg("apport")->CurrentVer))) { + bool isUpgrade = distUpgradeMode || UpgradeMode != APT::Upgrade::ALLOW_EVERYTHING; auto internalBroken = Cache->BrokenCount(); auto internalDel = Cache->DelCount(); auto internalInst = Cache->InstCount(); @@ -1006,6 +1007,11 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vectorSet("APT::Solver", "internal"); _error->RevertToStack(); + + // Cost factors to compare two solutions + auto solver3Cost = std::make_tuple(Cache->DelCount(), isUpgrade ? -Cache->UpgradeCount() : 0, Cache->InstCount() - Cache->UpgradeCount(), Cache->UpgradeCount()); + auto internalCost = std::make_tuple(internalDel, isUpgrade ? -internalUpgrade : 0, internalInst - internalUpgrade, internalUpgrade); + // An error summary for apport. std::string error; if (solver3Res && Cache->BrokenCount()) @@ -1027,7 +1033,7 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, std::vectorDelCount(), -Cache->UpgradeCount(), Cache->KeepCount(), Cache->InstCount()) > std::make_tuple(internalDel, -internalUpgrade, internalKeep, internalInst)) + else if (solver3Cost > internalCost) { error = "Failure: The 3.0 solver produced a worse result"; } -- cgit v1.2.3-70-g09d2