[Yum-devel] [PATCH 7/9] Add transactionCacheFileRequires() and fileRequiresData()

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


 This is the most scarey part of the rpmdb caching. I think it's good.
But it's somewhat complicated, and if we screw it up (it isn't in sync.
with the rpmdb) bad things will likely result.
 We are protected from rpm doing crazy things due to the way
transactionResultVersion() works, so all that matters is that our
logic is right for what is in the transaction.
 Both installedFileRequires and installedFileProviders should always
be updated for the transaction, and thus. be identical to rm'ing the
cache.

 And I've tested it, and it seems to work :).
---
 yum/depsolve.py |   22 +++++++++++------
 yum/rpmsack.py  |   69 ++++++++++++++++++++++++++++--------------------------
 2 files changed, 50 insertions(+), 41 deletions(-)

diff --git a/yum/depsolve.py b/yum/depsolve.py
index c313f1b..be875d0 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -918,6 +918,7 @@ class Depsolve(object):
 
     def _checkFileRequires(self):
         fileRequires = set()
+        nfileRequires = set() # These need to be looked up in the rpmdb.
         reverselookup = {}
         ret = []
 
@@ -925,7 +926,7 @@ class Depsolve(object):
         if self.installedFileRequires is None:
             self.installedFileRequires, \
               self.installedUnresolvedFileRequires, \
-              self.installedFileProviders = self.rpmdb._get_file_requires()
+              self.installedFileProviders = self.rpmdb.fileRequiresData()
 
         # get file requirements from packages not deleted
         todel = []
@@ -956,6 +957,8 @@ class Depsolve(object):
                                 break
                         if already_broken:
                             continue
+                    if name not in fileRequires:
+                        nfileRequires.add(name)
                     fileRequires.add(name)
                     reverselookup.setdefault(name, []).append(txmbr.po.pkgtup)
 
@@ -976,27 +979,30 @@ class Depsolve(object):
             del self.installedFileProviders[fname]
 
         # check the file requires
+        iFP = self.installedFileProviders
         for filename in fileRequires:
             nprov = self.tsInfo.getNewProvides(filename)
             if nprov:
-                pkgtups = [po.pkgtup for po in nprov]
-                self.installedFileProviders[filename] = pkgtups
-                continue
+                iFP.setdefault(filename, []).extend([po.pkgtup for po in nprov])
 
-            if filename in self.installedFileProviders:
+            #  If we've got a result, and we've seen this before (and thus. have
+            # the rpmdb results) ... we are done.
+            if (filename in self.installedFileProviders and
+                filename not in nfileRequires):
                 continue 
 
             oprov = self.tsInfo.getOldProvides(filename)
             if oprov:
-                pkgtups = [po.pkgtup for po in oprov]
-                self.installedFileProviders[filename] = pkgtups
+                iFP.setdefault(filename, []).extend([po.pkgtup for po in oprov])
+
+            if filename in self.installedFileProviders:
                 continue
 
             for pkgtup in reverselookup[filename]:
                 po = self.getInstalledPackageObject(pkgtup)
                 ret.append( (po, (filename, 0, '')) )
 
-        self.rpmdb._write_file_requires(self.installedFileRequires, 
+        self.rpmdb.transactionCacheFileRequires(self.installedFileRequires, 
                                         self.installedUnresolvedFileRequires,
                                         self.installedFileProviders,
                                         ret)
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 51a0356..68655a1 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -114,7 +114,6 @@ class RPMDBPackageSack(PackageSackBase):
             cachedir = misc.getCacheDir()
         self._cachedir = cachedir + "/rpmdb-cache/"
         self._have_cached_rpmdbv_data = None
-        self._use_cached_file_requires = True
         self._cached_conflicts_data = None
         # Store the result of what happens, if a transaction completes.
         self._trans_cache_store = {}
@@ -464,6 +463,10 @@ class RPMDBPackageSack(PackageSackBase):
             pkgs = self._trans_cache_store['conflicts']
             self._write_conflicts_new(pkgs, rpmdbv)
 
+        if 'file-requires' in self._trans_cache_store:
+            data = self._trans_cache_store['file-requires']
+            self._write_file_requires(rpmdbv, data)
+
         self._trans_cache_store = {}
 
     def returnGPGPubkeyPackages(self):
@@ -534,15 +537,12 @@ class RPMDBPackageSack(PackageSackBase):
 
         return iFR, iFP
 
-    def _get_file_requires(self):
-        print "JDBG:", 'BEG: _all_file_requires', self._use_cached_file_requires
-        if self.__cache_rpmdb__ and self._use_cached_file_requires:
+    def fileRequiresData(self):
+        if self.__cache_rpmdb__:
             iFR, iFP = self._read_file_requires()
             if iFR is not None:
-                print "JDBG:", 'CACHE'
                 return iFR, set(), iFP
 
-        print "JDBG:", '** no CACHE'
         installedFileRequires = {}
         installedUnresolvedFileRequires = set()
         resolved = set()
@@ -557,26 +557,41 @@ class RPMDBPackageSack(PackageSackBase):
                     if not dep:
                         installedUnresolvedFileRequires.add(name)
 
-        if self.__cache_rpmdb__:
-            self._write_file_requires(installedFileRequires,
-                                      installedUnresolvedFileRequires,
-                                      {}, [])
-            self._rename_file_requires(self.simpleVersion(main_only=True)[0])
-        return installedFileRequires, installedUnresolvedFileRequires, {}
-
-    def _write_file_requires(self, installedFileRequires,
-                             installedUnresolvedFileRequires,
-                             installedFileProvides,
-                             problems):
+        fileRequires = set()
+        for fnames in installedFileRequires.itervalues():
+            fileRequires.update(fnames)
+        installedFileProviders = {}
+        for fname in fileRequires:
+            pkgtups = [pkg.pkgtup for pkg in self.getProvides(fname)]
+            installedFileProviders[fname] = pkgtups
+
+        return (installedFileRequires, installedUnresolvedFileRequires,
+                installedFileProviders)
+
+    def transactionCacheFileRequires(self, installedFileRequires,
+                                     installedUnresolvedFileRequires,
+                                     installedFileProvides,
+                                     problems):
         if not self.__cache_rpmdb__:
             return
 
-        if not self._use_cached_file_requires:
-            return
         if installedUnresolvedFileRequires or problems:
             return
-        # FIXME: ... real tmp. file
-        fo = open(self._cachedir + '/file-requires.un.tmp', 'w')
+
+        data = (installedFileRequires,
+                installedUnresolvedFileRequires,
+                installedFileProvides)
+
+        self._trans_cache_store['file-requires'] = data
+
+    def _write_file_requires(self, rpmdbversion, data):
+        (installedFileRequires,
+         installedUnresolvedFileRequires,
+         installedFileProvides) = data
+
+        fo = open(self._cachedir + '/file-requires.tmp', 'w')
+        fo.write("%s\n" % rpmdbversion)
+
         fo.write("%u\n" % len(installedFileRequires))
         for pkgtup in sorted(installedFileRequires):
             for var in pkgtup:
@@ -596,20 +611,8 @@ class RPMDBPackageSack(PackageSackBase):
                 for var in pkgtup:
                     fo.write("%s\n" % var)
         fo.close()
-
-    def _rename_file_requires(self, rpmdbversion):
-        if not os.path.exists(self._cachedir + '/file-requires.un.tmp'):
-            return
-
-        rfo = open(self._cachedir + '/file-requires.un.tmp')
-        wfo = open(self._cachedir + '/file-requires.tmp', 'w')
-        wfo.write("%s\n" % rpmdbversion)
-        wfo.write(rfo.read())
-        rfo.close()
-        wfo.close()
         os.rename(self._cachedir + '/file-requires.tmp',
                   self._cachedir + '/file-requires')
-        os.unlink(self._cachedir + '/file-requires.un.tmp')
 
     def _get_cached_simpleVersion_main(self):
         """ Return the cached string of the main rpmdbv. """
-- 
1.6.2.5



More information about the Yum-devel mailing list