[Yum-devel] [PATCH] Speedup repeated calls to .install() with a pattern, via. returnPackages(). Add negative caching to both sqlite and rpmdb. Add pkg names with a '-' in them to pkgnames_loaded in sqlite.
James Antill
james at and.org
Tue Mar 30 20:18:59 UTC 2010
---
yum/rpmsack.py | 17 ++++++++++++++++-
yum/sqlitesack.py | 26 +++++++++++++++++++++++++-
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index 8289cd2..4580150 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -144,6 +144,7 @@ class RPMDBPackageSack(PackageSackBase):
self._name2pkg = {}
self._tup2pkg = {}
self._completely_loaded = False
+ self._pkgmatch_fails = set()
self._simple_pkgtup_list = []
self._get_pro_cache = {}
self._get_req_cache = {}
@@ -189,6 +190,7 @@ class RPMDBPackageSack(PackageSackBase):
self._name2pkg = {}
self._tup2pkg = {}
self._completely_loaded = False
+ self._pkgmatch_fails = set()
self._simple_pkgtup_list = []
self._get_pro_cache = {}
self._get_req_cache = {}
@@ -362,13 +364,14 @@ class RPMDBPackageSack(PackageSackBase):
return misc.newestInList(allpkgs)
@staticmethod
- def _compile_patterns(patterns, ignore_case=False):
+ def _compile_patterns(self, patterns, ignore_case=False):
if not patterns or len(patterns) > constants.PATTERNS_MAX:
return None
ret = []
for pat in patterns:
if not pat:
continue
+
qpat = pat[0]
if qpat in ('?', '*'):
qpat = None
@@ -381,6 +384,7 @@ class RPMDBPackageSack(PackageSackBase):
return ret
@staticmethod
def _match_repattern(repatterns, hdr, ignore_case):
+ """ This is basically parsePackages() but for rpm hdr objects. """
if repatterns is None:
return True
@@ -417,6 +421,16 @@ class RPMDBPackageSack(PackageSackBase):
"""Returns a list of packages. Note that the packages are
always filtered to those matching the patterns/case. repoid is
ignored, and is just here for compatibility with non-rpmdb sacks. """
+ if patterns and not ignore_case:
+ tpats = []
+ for pat in patterns:
+ if pat in self._pkgmatch_fails:
+ continue
+ tpats.append(pat)
+ patterns = tpats
+ if not patterns:
+ return []
+
if not self._completely_loaded:
rpats = self._compile_patterns(patterns, ignore_case)
for hdr, idx in self._all_packages():
@@ -430,6 +444,7 @@ class RPMDBPackageSack(PackageSackBase):
pkgobjlist = [pkg for pkg in pkgobjlist if pkg.name != 'gpg-pubkey']
if patterns:
pkgobjlist = parsePackages(pkgobjlist, patterns, not ignore_case)
+ self._pkgmatch_fails.update(pkgobjlist[2])
pkgobjlist = pkgobjlist[0] + pkgobjlist[1]
return pkgobjlist
diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
index 1d6c764..9a95b7b 100644
--- a/yum/sqlitesack.py
+++ b/yum/sqlitesack.py
@@ -428,6 +428,7 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
self._pkgname2pkgkeys = {}
self._pkgtup2pkgs = {}
self._pkgnames_loaded = set()
+ self._pkgmatch_fails = set()
self._arch_allowed = None
self._pkgExcluder = []
self._pkgExcludeIds = {}
@@ -491,6 +492,7 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
self._key2pkg = {}
self._pkgname2pkgkeys = {}
self._pkgnames_loaded = set()
+ self._pkgmatch_fails = set()
self._pkgtup2pkgs = {}
self._search_cache = {
'provides' : { },
@@ -1228,6 +1230,9 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
user_names = set(names)
names = []
for pkgname in user_names:
+ if pkgname in self._pkgmatch_fails:
+ continue
+
if loaded_all_names or pkgname in self._pkgnames_loaded:
returnList.extend(self._packagesByName(pkgname))
else:
@@ -1502,7 +1507,8 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
'sql_envra', 'sql_nevra']
need_full = False
for pat in patterns:
- if misc.re_full_search_needed(pat):
+ if (misc.re_full_search_needed(pat) and
+ (ignore_case or pat not in self._pkgnames_loaded)):
need_full = True
break
@@ -1536,12 +1542,18 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
pat_sqls = []
pat_data = []
for (pattern, rest) in patterns:
+ if not ignore_case and pattern in self._pkgmatch_fails:
+ continue
+
for field in fields:
if ignore_case:
pat_sqls.append("%s LIKE ?%s" % (field, rest))
else:
pat_sqls.append("%s %s ?" % (field, rest))
pat_data.append(pattern)
+ if patterns and not pat_sqls:
+ return
+
if pat_sqls:
qsql = _FULL_PARSE_QUERY_BEG + " OR ".join(pat_sqls)
else:
@@ -1578,6 +1590,18 @@ class YumSqlitePackageSack(yumRepo.YumPackageSack):
if not need_full and repoid is None:
# Mark all the processed pkgnames as fully loaded
self._pkgnames_loaded.update([po.name for po in returnList])
+ if need_full:
+ for (pat, rest) in patterns:
+ if rest == 'glob':
+ continue
+ assert rest == '='
+ for pkg in returnList:
+ if pkg.name == pat:
+ self._pkgnames_loaded.add(pkg.name)
+ break
+ if not returnList:
+ for (pat, rest) in patterns:
+ self._pkgmatch_fails.add(pat)
return returnList
--
1.6.6.1
More information about the Yum-devel
mailing list