diff options
author | David Kalnischkies <david@kalnischkies.de> | 2020-06-19 18:49:11 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2020-07-02 18:57:11 +0200 |
commit | 1f910d94add8f20ebfa5999a7795e678a4af0826 (patch) | |
tree | 7404454d1641db86bf12f067ba13e6d772577595 /apt-pkg/algorithms.cc | |
parent | cfd0172fb0eeb15b2e2427c0e11b2ec65f501839 (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/algorithms.cc')
-rw-r--r-- | apt-pkg/algorithms.cc | 49 |
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 |