summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2020-06-19 18:49:11 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2020-07-02 18:57:11 +0200
commit1f910d94add8f20ebfa5999a7795e678a4af0826 (patch)
tree7404454d1641db86bf12f067ba13e6d772577595 /apt-pkg
parentcfd0172fb0eeb15b2e2427c0e11b2ec65f501839 (diff)
Add dependency points in the resolver also to providers
We were traditionally adding points for some dependency types to the real package, but we should also do it for providers of that package to help the resolver especially if the real package is for some reason not tagged for removal yet/anymore. While at it we ensure that the points are only attributed once for each package as especially with versioned provides a package can nowadays provide another many times and would hence acquire a lot of points.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc49
1 files changed, 40 insertions, 9 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index cba772d41..cd09a6944 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -517,18 +517,37 @@ void pkgProblemResolver::MakeScores()
Score += PrioInstalledAndNotObsolete;
// propagate score points along dependencies
- for (pkgCache::DepIterator D = InstVer.DependsList(); D.end() == false; ++D)
+ for (pkgCache::DepIterator D = InstVer.DependsList(); not D.end(); ++D)
{
if (DepMap[D->Type] == 0)
continue;
pkgCache::PkgIterator const T = D.TargetPkg();
- if (D->Version != 0)
+ if (not D.IsIgnorable(T))
{
- pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
- if (IV.end() == true || D.IsSatisfied(IV) == false)
+ if (D->Version != 0)
+ {
+ pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache);
+ if (IV.end() || not D.IsSatisfied(IV))
+ continue;
+ }
+ Scores[T->ID] += DepMap[D->Type];
+ }
+
+ std::vector<map_id_t> providers;
+ for (auto Prv = T.ProvidesList(); not Prv.end(); ++Prv)
+ {
+ if (D.IsIgnorable(Prv))
+ continue;
+ auto const PV = Prv.OwnerVer();
+ auto const PP = PV.ParentPkg();
+ if (PV != Cache[PP].InstVerIter(Cache) || not D.IsSatisfied(Prv))
continue;
+ providers.push_back(PP->ID);
}
- Scores[T->ID] += DepMap[D->Type];
+ std::sort(providers.begin(), providers.end());
+ providers.erase(std::unique(providers.begin(), providers.end()), providers.end());
+ for (auto const prv : providers)
+ Scores[prv] += DepMap[D->Type];
}
}
@@ -564,13 +583,25 @@ void pkgProblemResolver::MakeScores()
provide important packages extremely important */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
{
- for (pkgCache::PrvIterator P = I.ProvidesList(); P.end() == false; ++P)
+ auto const transfer = abs(Scores[I->ID] - OldScores[I->ID]);
+ if (transfer == 0)
+ continue;
+
+ std::vector<map_id_t> providers;
+ for (auto Prv = I.ProvidesList(); not Prv.end(); ++Prv)
{
- // Only do it once per package
- if ((pkgCache::Version *)P.OwnerVer() != Cache[P.OwnerPkg()].InstallVer)
+ if (Prv.IsMultiArchImplicit())
+ continue;
+ auto const PV = Prv.OwnerVer();
+ auto const PP = PV.ParentPkg();
+ if (PV != Cache[PP].InstVerIter(Cache))
continue;
- Scores[P.OwnerPkg()->ID] += abs(Scores[I->ID] - OldScores[I->ID]);
+ providers.push_back(PP->ID);
}
+ std::sort(providers.begin(), providers.end());
+ providers.erase(std::unique(providers.begin(), providers.end()), providers.end());
+ for (auto const prv : providers)
+ Scores[prv] += transfer;
}
/* Protected things are pushed really high up. This number should put them