Hi!

As already announced on IRC I still have a pile of patches that were waiting for the 4.0.x branch to open.

These two switch to using generators instead of lists for the Depsolve.check* family. This allows us to restart the checking when ever the transaction is changed. This will allow us to further simplify the logic of the depsolver as we can be sure that the problem we are currently trying to solve still exists.

Comments?

Florian
>From 53003ca0e358f59867bdd73146198e1ce23524dd Mon Sep 17 00:00:00 2001
From: Florian Festi <[EMAIL PROTECTED]>
Date: Mon, 18 Feb 2008 13:56:19 +0100
Subject: [PATCH] Make Depsolve.check* generators instead of returning lists

---
 yum/depsolve.py |   22 +++++-----------------
 1 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/yum/depsolve.py b/yum/depsolve.py
index a08f481..640ab79 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -762,7 +762,6 @@ class Depsolve(object):
             oldreqs.extend(oldpo.returnPrco('requires'))
         oldreqs = set(oldreqs)
 
-        ret = []
         for req in txmbr_reqs:
             if req[0].startswith('rpmlib('):
                 continue
@@ -774,8 +773,7 @@ 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:
-                ret.append( (txmbr.po, (req[0], flags[req[1]], version_tuple_to_string(req[2]))) )
-                continue
+                yield (txmbr.po, (req[0], flags[req[1]], version_tuple_to_string(req[2])))
 
             #Add relationship
             for po in provs:
@@ -785,8 +783,6 @@ class Depsolve(object):
                     pkgtup=po.pkgtup, output_states=TS_INSTALL_STATES):
                     member.relatedto.append((txmbr.po, 'dependson'))
 
-        return ret
-
     def _checkRemove(self, txmbr):
         po = txmbr.po
         provs = po.returnPrco('provides')
@@ -797,7 +793,6 @@ class Depsolve(object):
         for newpo in txmbr.updated_by:
             for p in newpo.provides:
                 newpoprovs[p] = 1
-        ret = []
         
         # iterate over the provides of the package being removed
         # and see what's actually going away
@@ -809,13 +804,11 @@ class Depsolve(object):
             for pkg, hits in self.tsInfo.getRequires(*prov).iteritems():
                 for rn, rf, rv in hits:
                     if not self.tsInfo.getProvides(rn, rf, rv):
-                        ret.append( (pkg, (rn, flags[rf], version_tuple_to_string(rv))) )
-        return ret
+                        yield (pkg, (rn, flags[rf], version_tuple_to_string(rv)))
 
     def _checkFileRequires(self):
         fileRequires = set()
         reverselookup = {}
-        ret = []
 
         # generate list of file requirement in rpmdb
         if self.installedFileRequires is None:
@@ -862,13 +855,9 @@ class Depsolve(object):
         for filename in fileRequires:
             if not self.tsInfo.getOldProvides(filename) and not self.tsInfo.getNewProvides(filename):
                 for po in reverselookup[filename]:
-                    ret.append( (po, (filename, 0, '')) )
-
-        return ret
-
+                    yield (po, (filename, 0, ''))
 
     def _checkConflicts(self):
-        ret = [ ]
         for po in self.rpmdb.returnPackages():
             if self.tsInfo.getMembersWithState(po.pkgtup, output_states=TS_REMOVE_STATES):
                 continue
@@ -877,7 +866,7 @@ class Depsolve(object):
                 for conflicting_po in self.tsInfo.getNewProvides(r, f, v):
                     if conflicting_po.pkgtup[0] == po.pkgtup[0] and conflicting_po.pkgtup[2:] == po.pkgtup[2:]:
                         continue
-                    ret.append( (po, (r, flags[f], version_tuple_to_string(v)), conflicting_po) )
+                    yield (po, (r, flags[f], version_tuple_to_string(v)), conflicting_po)
         for txmbr in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
             po = txmbr.po
             for conflict in txmbr.po.returnPrco('conflicts'):
@@ -885,8 +874,7 @@ class Depsolve(object):
                 for conflicting_po in self.tsInfo.getProvides(r, f, v):
                     if conflicting_po.pkgtup[0] == po.pkgtup[0] and conflicting_po.pkgtup[2:] == po.pkgtup[2:]:
                         continue
-                    ret.append( (po, (r, flags[f], version_tuple_to_string(v)), conflicting_po) )
-        return ret
+                    yield (po, (r, flags[f], version_tuple_to_string(v)), conflicting_po)
 
 
     def isPackageInstalled(self, pkgname):
-- 
1.5.4.1

>From 013d529249b98d88209bc366af0f72b407e5acdf Mon Sep 17 00:00:00 2001
From: Florian Festi <[EMAIL PROTECTED]>
Date: Mon, 18 Feb 2008 14:21:07 +0100
Subject: [PATCH] Restart .check* every time the tsInfo got modified to only resolve problems that still exist

---
 yum/depsolve.py |   50 +++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/yum/depsolve.py b/yum/depsolve.py
index 640ab79..dac4225 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -655,10 +655,17 @@ class Depsolve(object):
             # check global FileRequires
             if CheckRemoves:
                 CheckRemoves = False
-                for po, dep in self._checkFileRequires():
-                    (checkdep, missing, errormsgs) = self._processReq(po, dep)
-                    CheckDeps |= checkdep
-                    errors += errormsgs
+                filerequires = self._checkFileRequires()
+                while True:
+                    for po, dep in filerequires:
+                        (checkdep, missing, errormsgs) = self._processReq(po, dep)
+                        CheckDeps |= checkdep
+                        errors += errormsgs
+                        if CheckDeps:
+                            filerequires = self._checkFileRequires()
+                            break
+                    else:
+                        break # end while loop if for loop ran through
 
                 if CheckDeps:
                     if self.dsCallback: self.dsCallback.restartLoop()
@@ -668,10 +675,17 @@ class Depsolve(object):
             # check Conflicts
             if CheckInstalls:
                 CheckInstalls = False
-                for conflict in self._checkConflicts():
-                    (checkdep, errormsgs) = self._processConflict(*conflict)
-                    CheckDeps |= checkdep
-                    errors += errormsgs
+                conflicts = self._checkConflicts()
+                while True:
+                    for conflict in conflicts:
+                        (checkdep, errormsgs) = self._processConflict(*conflict)
+                        CheckDeps |= checkdep
+                        errors += errormsgs
+                        if checkdep:
+                            conflicts = self._checkConflicts()
+                            break
+                    else:
+                        break # end while loop if for loop ran through
 
                 if CheckDeps:
                     if self.dsCallback: self.dsCallback.restartLoop()
@@ -737,11 +751,21 @@ class Depsolve(object):
                 CheckRemoves = True
 
             missing_in_pkg = False
-            for po, dep in thisneeds:
-                (checkdep, missing, errormsgs) = self._processReq(po, dep)
-                CheckDeps |= checkdep
-                errors += errormsgs
-                missing_in_pkg |= missing
+
+            while True:
+                for po, dep in thisneeds:
+                    (checkdep, missing, errormsgs) = self._processReq(po, dep)
+                    CheckDeps |= checkdep
+                    errors += errormsgs
+                    missing_in_pkg |= missing
+                    if checkdep:
+                        if (txmbr.output_state in TS_INSTALL_STATES) == (txmbr.po.state != None):
+                            thisneeds = self._checkInstall(txmbr)
+                        else:
+                            thisneeds = self._checkRemove(txmbr)
+                        break
+                else:
+                    break
 
             if not missing_in_pkg:
                 self.tsInfo.markAsResolved(txmbr)
-- 
1.5.4.1

_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel

Reply via email to