[Yum-devel] [PATCH] Add a simple "how many packages does this provider require" test.
James Antill
james at and.org
Tue Apr 20 22:17:53 UTC 2010
This only goes one level deep, in theory it can screw up where:
pkgA => pkgX
pkgX => pkgC
pkgX => pkgD
pkgX => pkgE
pkgB => pkgY
pkgB => pkgZ
...with this patch we'd pick "pkgA" because it had "less" requirements,
even though it actually requires 1 more thing. However, real world
result on F12:
% yum install @core @base gdm
[...]
Resolving: desktop-notification-daemon
kdebase-runtime => 38 things
xfce4-notifyd => 4 things
notification-daemon => 1 thing
...all were "equal" before this patch, so we're left with "shortest
name".
---
yum/depsolve.py | 40 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 39 insertions(+), 1 deletions(-)
diff --git a/yum/depsolve.py b/yum/depsolve.py
index a9e4d55..5eb2f92 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -859,7 +859,11 @@ class Depsolve(object):
self.verbose_logger.log(logginglevels.DEBUG_2, _("looking for %s as a requirement of %s"), req, txmbr)
provs = self.tsInfo.getProvides(*req)
- if not provs:
+ # The self provides should mostly be caught before here now, but
+ # at least config() crack still turns up, it's not that
+ # expensive to just do it, and we really don't want "false positive"
+ # requires for compare_providers().
+ if not provs and not txmbr.po.inPrcoRange('provides', req):
ret.append( (txmbr.po, self._prco_req2req(req)) )
continue
@@ -1228,6 +1232,7 @@ class Depsolve(object):
if res == po:
pkgresults[po] += 5
+ # End of O(N*N): for nextpo in pkgs:
if _common_sourcerpm(po, reqpo):
self.verbose_logger.log(logginglevels.DEBUG_4,
_('common sourcerpm %s and %s' % (po, reqpo)))
@@ -1243,7 +1248,40 @@ class Depsolve(object):
_('common prefix of %s between %s and %s' % (cpl, po, reqpo)))
pkgresults[po] += cpl*2
+
+ # If we have more than one "best", see what would happen if we picked
+ # each package ... ie. what things do they require that _aren't_ already
+ # installed/to-be-installed. In theory this can screw up due to:
+ # pkgA => requires pkgX
+ # pkgB => requires pkgY, requires pkgZ
+ # ...but pkgX requires 666 other things. Going recursive is
+ # "non-trivial" though, python != prolog. This seems to do "better"
+ # from simple testing though.
+ bestnum = max(pkgresults.values())
+ rec_depsolve = {}
+ for po in pkgs:
+ if pkgresults[po] != bestnum:
+ continue
+ rec_depsolve[po] = 0
+ if len(rec_depsolve) > 1:
+ for po in rec_depsolve:
+ # FIXME: Can't str() this to something usable...
+ fake_txmbr = misc.GenericHolder()
+ fake_txmbr.po = po
+ fake_txmbr.name = po.name
+ fake_txmbr.updates = []
+ rec_depsolve[po] = self._checkInstall(fake_txmbr)
+
+ # We don't want to decide to use a "shortest first", if something else
+ # has told us to pick something else. But we want to pick between
+ # multiple "best" packages. So we just give a bump to those packages
+ # which are already winning.
+ bestnum = max(pkgresults.values())
+ for po in pkgs:
+ if pkgresults[po] != bestnum:
+ continue
+ pkgresults[po] += 1000
pkgresults[po] += (len(po.name)*-1)
bestorder = sorted(pkgresults.items(),
--
1.6.6.1
More information about the Yum-devel
mailing list