Hi!

This patch keeps the indexes of the PackageSack in sync with the packages in the sack. This solves a corruption of the indexes when adding packages between searches.

The patch dramatically increases the performance for
Add packages - Search - Add package - Search   scenarios

It dramatically reduces performance for
Add packages - Search - Remove most packages - Search   scenarios

This can be avoided using the new .clearIndexes() method if the situation is known in advance.


Patch will be needed for searching in localinstall packages. As the code handling them will move away from cli.py and call patterns of 3rd party code is unknown this patch is needed to avoid difficult to spot bugs related to the outdated indexes.

Florian Festi
Index: yum/packageSack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/packageSack.py,v
retrieving revision 1.29
diff -u -r1.29 packageSack.py
--- yum/packageSack.py	4 Mar 2007 21:45:16 -0000	1.29
+++ yum/packageSack.py	13 Jun 2007 07:33:38 -0000
@@ -504,7 +504,7 @@
 
     def _delFromListOfDict(self, dict, key, data):
         if not dict.has_key(key):
-            dict[key] = []
+            return
         try:
             dict[key].remove(data)
         except ValueError:
@@ -525,13 +525,23 @@
                 self._addToDictAsList(self.pkgsByRepo, repoid, obj)
         else:
             self._addToDictAsList(self.pkgsByRepo, repoid, obj)
-
+        if self.indexesBuilt:
+            self._addPackageToIndex(obj)
 
     def buildIndexes(self):
         """builds the useful indexes for searching/querying the packageSack
            This should be called after all the necessary packages have been 
            added/deleted"""
+
+        self.clearIndexes()
         
+        for repoid in self.pkgsByRepo.keys():
+            for obj in self.pkgsByRepo[repoid]:
+                self._addPackageToIndex(obj)
+        self.indexesBuilt = 1
+
+
+    def clearIndexes(self):
         # blank out the indexes
         self.obsoletes = {}
         self.requires = {}
@@ -540,36 +550,50 @@
         self.filenames = {}
         self.nevra = {}
         self.pkgsByID = {}
+
+        self.indexesBuilt = 0
         
-        for repoid in self.pkgsByRepo.keys():
-            for obj in self.pkgsByRepo[repoid]:
-            # store the things provided just on name, not the whole require+version
-            # this lets us reduce the set of pkgs to search when we're trying to depSolve
-                for (n, fl, (e,v,r)) in obj.returnPrco('obsoletes'):
-                    self._addToDictAsList(self.obsoletes, n, obj)
-                for (n, fl, (e,v,r)) in obj.returnPrco('requires'):
-                    self._addToDictAsList(self.requires, n, obj)
-                for (n, fl, (e,v,r)) in obj.returnPrco('provides'):
-                    self._addToDictAsList(self.provides, n, obj)
-                for (n, fl, (e,v,r)) in obj.returnPrco('conflicts'):
-                    self._addToDictAsList(self.conflicts, n, obj)
-                for ftype in obj.returnFileTypes():
-                    for file in obj.returnFileEntries(ftype):
-                        self._addToDictAsList(self.filenames, file, obj)
-                self._addToDictAsList(self.pkgsByID, obj.id, obj)
-                (name, arch, epoch, ver, rel) = obj.pkgtup
-                self._addToDictAsList(self.nevra, (name, epoch, ver, rel, arch), obj)
-                self._addToDictAsList(self.nevra, (name, None, None, None, None), obj)
-        
-        self.indexesBuilt = 1
-        
+    def _addPackageToIndex(self, obj):
+        # store the things provided just on name, not the whole require+version
+        # this lets us reduce the set of pkgs to search when we're trying to depSolve
+        for (n, fl, (e,v,r)) in obj.returnPrco('obsoletes'):
+            self._addToDictAsList(self.obsoletes, n, obj)
+        for (n, fl, (e,v,r)) in obj.returnPrco('requires'):
+            self._addToDictAsList(self.requires, n, obj)
+        for (n, fl, (e,v,r)) in obj.returnPrco('provides'):
+            self._addToDictAsList(self.provides, n, obj)
+        for (n, fl, (e,v,r)) in obj.returnPrco('conflicts'):
+            self._addToDictAsList(self.conflicts, n, obj)
+        for ftype in obj.returnFileTypes():
+            for file in obj.returnFileEntries(ftype):
+                self._addToDictAsList(self.filenames, file, obj)
+        self._addToDictAsList(self.pkgsByID, obj.id, obj)
+        (name, arch, epoch, ver, rel) = obj.pkgtup
+        self._addToDictAsList(self.nevra, (name, epoch, ver, rel, arch), obj)
+        self._addToDictAsList(self.nevra, (name, None, None, None, None), obj)
 
+    def _delPackageFromIndex(self, obj):
+        for (n, fl, (e,v,r)) in obj.returnPrco('obsoletes'):
+            self._delFromListOfDict(self.obsoletes, n, obj)
+        for (n, fl, (e,v,r)) in obj.returnPrco('requires'):
+            self._delFromListOfDict(self.requires, n, obj)
+        for (n, fl, (e,v,r)) in obj.returnPrco('provides'):
+            self._delFromListOfDict(self.provides, n, obj)
+        for (n, fl, (e,v,r)) in obj.returnPrco('conflicts'):
+            self._delFromListOfDict(self.conflicts, n, obj)
+        for ftype in obj.returnFileTypes():
+            for file in obj.returnFileEntries(ftype):
+                self._delFromListOfDict(self.filenames, file, obj)
+        self._delFromListOfDict(self.pkgsByID, obj.id, obj)
+        (name, arch, epoch, ver, rel) = obj.pkgtup
+        self._delFromListOfDict(self.nevra, (name, epoch, ver, rel, arch), obj)
+        self._delFromListOfDict(self.nevra, (name, None, None, None, None), obj)
         
     def delPackage(self, obj):
         """delete a pkgobject"""
         self._delFromListOfDict(self.pkgsByRepo, obj.repoid, obj)
-        if self.indexesBuilt: # if we've built indexes, delete it b/c we've just deleted something
-            self.indexesBuilt = 0
+        if self.indexesBuilt: 
+            self._delPackageFromIndex(obj)
         
     def returnPackages(self, repoid=None):
         """return list of all packages, takes optional repoid"""
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel

Reply via email to