[yum-git] yum/rpmsack.py
Florian Festi
ffesti at linux.duke.edu
Tue Jan 29 15:19:24 UTC 2008
yum/rpmsack.py | 142 ++++++++++++++++++++++++---------------------------------
1 file changed, 61 insertions(+), 81 deletions(-)
New commits:
commit 32e0bb632f841936571ce3db59a89332c96ea39c
Author: Florian Festi <ffesti at redhat.com>
Date: Mon Dec 10 18:27:54 2007 +0100
Optimize RpmSack
- Create each package only once
- fix wrongly nested file search in .searchProco()
- make _search return pkg objects
- avoid loading all headers if not neccessary
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index c715764..6507fab 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -47,9 +47,11 @@ class RPMDBPackageSack(PackageSackBase):
def __init__(self, root='/'):
self.root = root
self._idx2pkg = {}
- self._header_dict = {}
- self._header_by_name = {}
+ self._name2pkg = {}
+ self._tup2pkg = {}
+ self._completely_loaded = False
self.ts = None
+
self._cache = {
'files' : { },
'provides' : { },
@@ -62,10 +64,7 @@ class RPMDBPackageSack(PackageSackBase):
'''Getter for the pkglist property.
Returns a list of package tuples.
'''
- if len(self._header_dict) == 0 :
- self._make_header_dict()
-
- return self._header_dict.keys()
+ return [po.pkgtup for po in self.returnPackages()]
pkglist = property(_get_pkglist, None)
@@ -99,7 +98,7 @@ class RPMDBPackageSack(PackageSackBase):
if not result.has_key(pkg.pkgid):
result[pkg.pkgid] = pkg
del mi
-
+
fileresults = self.searchFiles(name)
for pkg in fileresults:
if not result.has_key(pkg.pkgid):
@@ -129,7 +128,7 @@ class RPMDBPackageSack(PackageSackBase):
return result
def searchPrco(self, name, prcotype):
-
+
result = self._cache[prcotype].get(name)
if result is not None:
return result
@@ -140,22 +139,14 @@ class RPMDBPackageSack(PackageSackBase):
mi = ts.dbMatch(tag, name)
for hdr in mi:
po = self._makePackageObject(hdr, mi.instance())
- prcotup = (name, None, (None, None, None))
- if po.checkPrco(prcotype, prcotup):
- if not result.has_key(po.pkgid):
- result[po.pkgid] = po
-
- # If it's not a provides or filename, we are done
- if prcotype != 'provides' or name[0] != '/':
- if not result.has_key(po.pkgid):
- result[po.pkgid] = po
- else:
- fileresults = self.searchFiles(name)
- for pkg in fileresults:
- if not result.has_key(pkg.pkgid):
- result[pkg.pkgid] = pkg
-
+ result[po.pkgid] = po
del mi
+
+ # If it's not a provides or filename, we are done
+ if prcotype == 'provides' and name[0] == '/':
+ fileresults = self.searchFiles(name)
+ for pkg in fileresults:
+ result[pkg.pkgid] = pkg
result = result.values()
self._cache[prcotype][name] = result
@@ -186,8 +177,7 @@ class RPMDBPackageSack(PackageSackBase):
(name, arch) = naTup
- allpkg = [ pkgtup
- for (hdr, pkgtup, idx) in self._search(name=name, arch=arch) ]
+ allpkg = [ po.pkgtup for po in self._search(name=name, arch=arch) ]
if not allpkg:
raise Errors.PackageSackError, 'No Package Matching %s' % name
@@ -198,21 +188,22 @@ class RPMDBPackageSack(PackageSackBase):
if not name:
return
- allpkg = [ self._makePackageObject(hdr, idx)
- for (hdr, pkgtup, idx) in self._search(name=name) ]
+ allpkgs = self._search(name=name)
- if not allpkg:
+ if not allpkgs:
raise Errors.PackageSackError, 'No Package Matching %s' % name
- return misc.newestInList(allpkg)
+ return misc.newestInList(allpkgs)
def returnPackages(self, repoid=None, patterns=None):
- return [ self._makePackageObject(hdr, idx)
- for hdr, idx in self._all_packages() ]
+ if not self._completely_loaded:
+ for hdr, idx in self._all_packages():
+ self._makePackageObject(hdr, idx)
+ self._completely_loaded = True
+ return self._idx2pkg.values()
def searchNevra(self, name=None, epoch=None, ver=None, rel=None, arch=None):
- return [ self._makePackageObject(hdr, idx)
- for (hdr, pkgtup, idx) in self._search(name, epoch, ver, rel, arch) ]
+ return self._search(name, epoch, ver, rel, arch)
def excludeArchs(self, archlist):
pass
@@ -248,60 +239,56 @@ class RPMDBPackageSack(PackageSackBase):
del mi
- def _make_header_dict(self):
- """generate a header indexes dict that is pkgtup = index number"""
-
- for (hdr, idx) in self._all_packages():
- pkgtup = self._hdr2pkgTuple(hdr)
- self._header_dict[pkgtup] = (hdr, idx)
- self._header_by_name.setdefault(pkgtup[0], []).append(
- (pkgtup, (hdr, idx)))
-
def _search(self, name=None, epoch=None, ver=None, rel=None, arch=None):
- '''Generator that yield (header, pkgtup, index) for matching packages
+ '''Generator that yields matching packages
'''
- # Create a match closure for what is being searched for
- lookfor = [] # A list of (package_tuple_idx, search_value)
- loc = locals()
- for (i, arg) in enumerate(('name', 'arch', 'epoch', 'ver', 'rel')):
- val = loc[arg]
- if val != None:
- lookfor.append((i, val))
-
- # Find and yield matches
- if not self._header_dict:
- self._make_header_dict()
+ pkgtup = (name, arch, epoch, ver, rel)
+ if self._tup2pkg.has_key(pkgtup):
+ return [self._tup2pkg[pkgtup]]
+ loc = locals()
ret = []
- # We have the full pkgtup, just grab it from the header dict
- if len(lookfor) == 5:
- pkgtup = (name, arch, epoch, ver, rel)
- if self._header_dict.has_key(pkgtup):
- hdr, idx = self._header_dict[pkgtup]
- ret.append( (hdr, pkgtup, idx) )
- else:
+
+ if self._completely_loaded:
if name is not None:
- pkg_list = self._header_by_name.get(name, [ ])
+ pkgs = self._name2pkg.get(name, [])
else:
- pkg_list = self._header_dict.items()
-
- for (pkgtup, (hdr, idx)) in pkg_list:
- ok = True
- for thisindex, val in lookfor:
- if pkgtup[thisindex] != val:
- ok = False
+ pkgs = self.returnPkgs()
+ for po in pkgs:
+ for tag in ('name', 'epoch', 'ver', 'rel', 'arch'):
+ if loc[tag] is not None and loc[tag] != getattr(po, tag):
break
- if ok:
- ret.append( (hdr, pkgtup, idx) )
- return ret
+ else:
+ ret.append(po)
+ return ret
+
+ ts = self.readOnlyTS()
+ if name is not None:
+ mi = ts.dbMatch('name', name)
+ elif arch is not None:
+ mi = ts.dbMatch('arch', arch)
+ else:
+ mi = ts.dbMatch()
+ self._completely_loaded = True
+ for hdr in mi:
+ po = self._makePackageObject(hdr, mi.instance())
+ for tag in ('name', 'epoch', 'ver', 'rel', 'arch'):
+ if loc[tag] is not None and loc[tag] != getattr(po, tag):
+ break
+ else:
+ ret.append(po)
+ return ret
def _makePackageObject(self, hdr, index):
if self._idx2pkg.has_key(index):
return self._idx2pkg[index]
po = YumInstalledPackage(hdr)
po.idx = index
+ po.rpmdb = self
self._idx2pkg[index] = po
+ self._name2pkg.setdefault(po.name, []).append(po)
+ self._tup2pkg[po.pkgtup] = po
return po
def _hdr2pkgTuple(self, hdr):
@@ -353,11 +340,7 @@ class RPMDBPackageSack(PackageSackBase):
def returnTupleByKeyword(self, name=None, arch=None, epoch=None, ver=None, rel=None):
warnings.warn('returnTuplebyKeyword() will go away in a future version of Yum.\n',
DeprecationWarning, stacklevel=2)
-
- out = []
- for hdr, tup, idx in self._search(name=name, arch=arch, epoch=epoch, ver=ver, rel=rel):
- out.append(tup)
- return out
+ return [po.pkgtup for po in self._search(name=name, arch=arch, epoch=epoch, ver=ver, rel=rel)]
def returnHeaderByTuple(self, pkgtuple):
warnings.warn('returnHeaderByTuple() will go away in a future version of Yum.\n',
@@ -385,10 +368,7 @@ class RPMDBPackageSack(PackageSackBase):
if epoch in (None, 0, '(none)', ''):
epoch = '0'
- out = []
- for hdr, tup, idx in self._search(name, epoch, version, release, arch):
- out.append(idx)
- return out
+ return [po.idx for po in self._search(name, epoch, version, release, arch)]
def addDB(self, ts):
# Can't support this now
More information about the Yum-cvs-commits
mailing list