[Yum-devel] [PATCH 3/9] Cache checkFileRequires data
James Antill
james at and.org
Sun Nov 8 20:26:37 UTC 2009
---
yum/depsolve.py | 73 +++++++++++++++++++++--------
yum/rpmsack.py | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 189 insertions(+), 20 deletions(-)
diff --git a/yum/depsolve.py b/yum/depsolve.py
index 7871e98..4b35cec 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -923,26 +923,21 @@ class Depsolve(object):
# generate list of file requirement in rpmdb
if self.installedFileRequires is None:
- self.installedFileRequires = {}
- self.installedUnresolvedFileRequires = set()
- resolved = set()
- for pkg in self.rpmdb.returnPackages():
- for name, flag, evr in pkg.requires:
- if not name.startswith('/'):
- continue
- self.installedFileRequires.setdefault(pkg, []).append(name)
- if name not in resolved:
- dep = self.rpmdb.getProvides(name, flag, evr)
- resolved.add(name)
- if not dep:
- self.installedUnresolvedFileRequires.add(name)
+ self.installedFileRequires, \
+ self.installedUnresolvedFileRequires, \
+ self.installedFileProviders = self.rpmdb._get_file_requires()
# get file requirements from packages not deleted
- for po, files in self.installedFileRequires.iteritems():
- if not self._tsInfo.getMembersWithState(po.pkgtup, output_states=TS_REMOVE_STATES):
+ todel = []
+ for pkgtup, files in self.installedFileRequires.iteritems():
+ if self._tsInfo.getMembersWithState(pkgtup, output_states=TS_REMOVE_STATES):
+ todel.append(pkgtup)
+ else:
fileRequires.update(files)
for filename in files:
- reverselookup.setdefault(filename, []).append(po)
+ reverselookup.setdefault(filename, []).append(pkgtup)
+ for pkgtup in todel:
+ del self.installedFileRequires[pkgtup]
fileRequires -= self.installedUnresolvedFileRequires
@@ -950,6 +945,8 @@ class Depsolve(object):
for txmbr in self._tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
for name, flag, evr in txmbr.po.requires:
if name.startswith('/'):
+ pt = txmbr.po.pkgtup
+ self.installedFileRequires.setdefault(pt, []).append(name)
# check if file requires was already unresolved in update
if name in self.installedUnresolvedFileRequires:
already_broken = False
@@ -960,13 +957,49 @@ class Depsolve(object):
if already_broken:
continue
fileRequires.add(name)
- reverselookup.setdefault(name, []).append(txmbr.po)
+ reverselookup.setdefault(name, []).append(txmbr.po.pkgtup)
+
+ todel = []
+ for fname in self.installedFileProviders:
+ niFP_fname = []
+ for pkgtup in self.installedFileProviders[fname]:
+ if self._tsInfo.getMembersWithState(pkgtup, output_states=TS_REMOVE_STATES):
+ continue
+ niFP_fname.append(pkgtup)
+
+ if not niFP_fname:
+ todel.append(fname)
+ continue
+
+ self.installedFileProviders[fname] = niFP_fname
+ for fname in todel:
+ del self.installedFileProviders[fname]
# check the file requires
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, '')) )
+ nprov = self.tsInfo.getNewProvides(filename)
+ if nprov:
+ pkgtups = [po.pkgtup for po in nprov]
+ self.installedFileProviders[filename] = pkgtups
+ continue
+
+ if filename in self.installedFileProviders:
+ continue
+
+ oprov = self.tsInfo.getOldProvides(filename)
+ if oprov:
+ pkgtups = [po.pkgtup for po in oprov]
+ self.installedFileProviders[filename] = pkgtups
+ continue
+
+ for pkgtup in reverselookup[filename]:
+ po = self.getInstalledPackageObject(pkgtup)
+ ret.append( (po, (filename, 0, '')) )
+
+ self.rpmdb._write_file_requires(self.installedFileRequires,
+ self.installedUnresolvedFileRequires,
+ self.installedFileProviders,
+ ret)
return ret
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index b0f2094..6d2a831 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -114,6 +114,7 @@ class RPMDBPackageSack(PackageSackBase):
cachedir = misc.getCacheDir()
self._cachedir = cachedir + "/rpmdb-cache/"
self._have_cached_rpmdbv_data = None
+ self._use_cached_file_requires = True
self.ts = None
self.auto_close = False # this forces a self.ts.close() after
# most operations so it doesn't leave
@@ -384,6 +385,141 @@ class RPMDBPackageSack(PackageSackBase):
ret.append(self._makePackageObject(hdr, mi.instance()))
return ret
+ def _read_file_requires(self):
+ def _read_str(fo):
+ return fo.readline()[:-1]
+
+ assert self.__cache_rpmdb__
+ if not os.path.exists(self._cachedir + '/file-requires'):
+ return None, None
+
+ rpmdbv = self.simpleVersion(main_only=True)[0]
+ fo = open(self._cachedir + '/file-requires')
+ frpmdbv = fo.readline()
+ if not frpmdbv or rpmdbv != frpmdbv[:-1]:
+ return None, None
+
+ iFR = {}
+ iFP = {}
+ try:
+ # Read the requires...
+ 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
+
+ files_num = int(_read_str(fo))
+ while files_num > 0:
+ files_num -= 1
+
+ fname = _read_str(fo)
+
+ iFR.setdefault(pkgtup, []).append(fname)
+
+ # Read the provides...
+ files_num = int(_read_str(fo))
+ while files_num > 0:
+ files_num -= 1
+ fname = _read_str(fo)
+ 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
+
+ iFP.setdefault(fname, []).append(pkgtup)
+
+ if fo.readline() != '': # Should be EOF
+ return None, None
+ except ValueError:
+ return None, None
+
+ 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:
+ 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()
+ for pkg in self.returnPackages():
+ for name, flag, evr in pkg.requires:
+ if not name.startswith('/'):
+ continue
+ installedFileRequires.setdefault(pkg.pkgtup, []).append(name)
+ if name not in resolved:
+ dep = self.getProvides(name, flag, evr)
+ resolved.add(name)
+ 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):
+ 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')
+ fo.write("%u\n" % len(installedFileRequires))
+ for pkgtup in sorted(installedFileRequires):
+ for var in pkgtup:
+ fo.write("%s\n" % var)
+ filenames = set(installedFileRequires[pkgtup])
+ fo.write("%u\n" % len(filenames))
+ for fname in sorted(filenames):
+ fo.write("%s\n" % fname)
+
+ fo.write("%u\n" % len(installedFileProvides))
+ for fname in sorted(installedFileProvides):
+ fo.write("%s\n" % fname)
+
+ pkgtups = set(installedFileProvides[fname])
+ fo.write("%u\n" % len(pkgtups))
+ for pkgtup in sorted(pkgtups):
+ 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. """
if self._have_cached_rpmdbv_data is not None:
--
1.6.2.5
More information about the Yum-devel
mailing list