[Yum-devel] [PATCH 4/9] Cache "conflict packages", store the pkgtups of the packages with conflicts

James Antill james at and.org
Sun Nov 8 20:26:38 UTC 2009


---
 yum/__init__.py |    1 +
 yum/depsolve.py |    3 +-
 yum/rpmsack.py  |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/yum/__init__.py b/yum/__init__.py
index 68a8720..d8efdb7 100644
--- a/yum/__init__.py
+++ b/yum/__init__.py
@@ -1180,6 +1180,7 @@ class YumBase(depsolve.Depsolve):
             if resultobject is not None:
                 ret = resultobject.return_code
             self.history.end(self.rpmdb.simpleVersion(main_only=True)[0], ret)
+        self.rpmdb.returnConflictPackages() # Cache it for next time :o
         self.rpmdb.dropCachedData()
 
     def costExcludePackages(self):
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 4b35cec..42bb196 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -1003,10 +1003,9 @@ class Depsolve(object):
 
         return ret
 
-
     def _checkConflicts(self):
         ret = [ ]
-        for po in self.rpmdb.returnPackages():
+        for po in self.rpmdb.returnConflictPackages():
             if self.tsInfo.getMembersWithState(po.pkgtup, output_states=TS_REMOVE_STATES):
                 continue
             for conflict in po.returnPrco('conflicts'):
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 6d2a831..605cdd0 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -115,6 +115,7 @@ class RPMDBPackageSack(PackageSackBase):
         self._cachedir = cachedir + "/rpmdb-cache/"
         self._have_cached_rpmdbv_data = None
         self._use_cached_file_requires = True
+        self._cached_conflicts_data = None
         self.ts = None
         self.auto_close = False # this forces a self.ts.close() after
                                      # most operations so it doesn't leave
@@ -161,6 +162,7 @@ class RPMDBPackageSack(PackageSackBase):
             'obsoletes' : { },
             }
         self._have_cached_rpmdbv_data = None
+        self._cached_conflicts_data = None
 
     def readOnlyTS(self):
         if not self.ts:
@@ -375,6 +377,76 @@ class RPMDBPackageSack(PackageSackBase):
             pkgobjlist = pkgobjlist[0] + pkgobjlist[1]
         return pkgobjlist
 
+    def _uncached_returnConflictPackages(self):
+        if self._cached_conflicts_data is None:
+            ret = []
+            for pkg in self.returnPackages():
+                if len(pkg.conflicts):
+                    ret.append(pkg)
+            self._cached_conflicts_data = ret
+        return self._cached_conflicts_data
+
+    def _write_conflicts(self, pkgs):
+        if not self.__cache_rpmdb__:
+            return
+
+        conflicts_fname = self._cachedir + '/conflicts'
+        rpmdbv = self.simpleVersion(main_only=True)[0]
+        fo = open(conflicts_fname + '.tmp', 'w')
+        fo.write("%s\n" % rpmdbv)
+        fo.write("%u\n" % len(pkgs))
+        for pkg in sorted(pkgs):
+            for var in pkg.pkgtup:
+                fo.write("%s\n" % var)
+        fo.close()
+        os.rename(conflicts_fname + '.tmp', conflicts_fname)
+
+    def _read_conflicts(self):
+        if not self.__cache_rpmdb__:
+            return None
+
+        def _read_str(fo):
+            return fo.readline()[:-1]
+
+        conflict_fname = self._cachedir + '/conflicts'
+        if not os.path.exists(conflict_fname):
+            return None
+
+        fo = open(conflict_fname)
+        frpmdbv = fo.readline()
+        rpmdbv = self.simpleVersion(main_only=True)[0]
+        if not frpmdbv or rpmdbv != frpmdbv[:-1]:
+            return None
+
+        ret = []
+        try:
+            # Read the conflicts...
+            pkgtups_num = int(_read_str(fo))
+            while pkgtups_num > 0:
+                pkgtups_num -= 1
+
+                # n, a, e, v, r
+                pkgtup = (_read_str(fo), _read_str(fo),
+                          _read_str(fo), _read_str(fo), _read_str(fo))
+                int(pkgtup[2]) # Check epoch is valid
+                ret.extend(self.searchPkgTuple(pkgtup))
+            if fo.readline() != '': # Should be EOF
+                return None
+        except ValueError:
+            return None
+
+        self._cached_conflicts_data = ret
+        return self._cached_conflicts_data
+
+    def returnConflictPackages(self):
+        """ Return a list of packages that have conflicts. """
+        pkgs = self._read_conflicts()
+        if pkgs is None:
+            pkgs = self._uncached_returnConflictPackages()
+            self._write_conflicts(pkgs)
+
+        return pkgs
+
     def returnGPGPubkeyPackages(self):
         """ Return packages of the gpg-pubkeys ... hacky. """
         ts = self.readOnlyTS()
-- 
1.6.2.5



More information about the Yum-devel mailing list