[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