Hi!

The attached patch moved most of the whatProvides code into the SqliteSack. An implementation for MetaSack and a yet unused whatRequires method is also provided.

Except being the right place (IMHO) it gives a ~10% speed up. whatProvides returns a list of POs (as most other *Sack methods). I left DepSover.whatProvides alive and returning a PackageSack to avoid breaking interfaces.

I'd suggest considering modifing RpmSack.whatProvides to also return a list of POs insted of a list of NEVRA tuples to have a consistent interface.

Florian
? anaconda.prof.0
Index: rpmUtils/miscutils.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/rpmUtils/miscutils.py,v
retrieving revision 1.21
diff -u -r1.21 miscutils.py
--- rpmUtils/miscutils.py	7 Apr 2007 18:23:15 -0000	1.21
+++ rpmUtils/miscutils.py	25 Apr 2007 16:16:29 -0000
@@ -155,6 +155,68 @@
             return 1
     return 0
 
+def rangeCompare(reqtuple, provtuple):
+    """returns true if the package has a the prco that satisfies 
+    the reqtuple range, assume false."""
+    (reqn, reqf, (reqe, reqv, reqr)) = reqtuple
+    (n, f, (e, v, r)) = provtuple
+    if reqn != n:
+        return 0
+
+    if f is None or reqf is None:
+        return 1
+    
+    # and you thought we were done having fun
+    # if the requested release is left out then we have
+    # to remove release from the package prco to make sure the match
+    # is a success - ie: if the request is EQ foo 1:3.0.0 and we have 
+    # foo 1:3.0.0-15 then we have to drop the 15 so we can match
+    if reqr is None:
+        r = None
+    if reqe is None:
+        e = None
+    if reqv is None: # just for the record if ver is None then we're going to segfault
+        v = None
+
+    # if we just require foo-version, then foo-version-* will match
+    if r is None:
+        reqr = None
+
+    rc = rpmUtils.miscutils.compareEVR((e, v, r), (reqe, reqv, reqr))
+
+    # does not match unless
+    if rc >= 1:
+        if reqf in ['GT', 'GE', 4, 12]:
+            return 1
+        if reqf in ['EQ', 8]:
+            if f in ['LE', 10]:
+                return 1
+    if rc == 0:
+        if reqf in ['GT', 4]:
+            if f in ['GT', 'GE', 4, 12]:
+                return 1
+        if reqf in ['GE', 12]:
+            if f in ['GT', 'GE', 'EQ', 'LE', 4, 12, 8, 10]:
+                return 1
+        if reqf in ['EQ', 8]:
+            if f in ['EQ', 'GE', 'LE', 8, 12, 10]:
+                return 1
+        if reqf in ['LE', 10]:
+            if f in ['EQ', 'LE', 'LT', 'GE', 8, 10, 2, 12]:
+                return 1
+        if reqf in ['LT', 2]:
+            if f in ['LE', 'LT', 10, 2]:
+                return 1
+    if rc <= -1:
+        if reqf in ['GT', 'GE', 'EQ', 4, 12, 8]:
+            if f in ['GT', 'GE', 4, 12]:
+                return 1
+        if reqf in ['LE', 'LT', 10, 2]:
+            return 1
+
+    return 0
+    
+
 ###########
 # Title: Remove duplicates from a sequence
 # Submitter: Tim Peters 
Index: yum/depsolve.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/depsolve.py,v
retrieving revision 1.163
diff -u -r1.163 depsolve.py
--- yum/depsolve.py	24 Apr 2007 21:02:50 -0000	1.163
+++ yum/depsolve.py	25 Apr 2007 16:16:30 -0000
@@ -126,32 +126,8 @@
                     matched = 1
             if not matched:
                 self.doSackFilelistPopulate()
-            
-        pkgs = self.pkgSack.searchProvides(name)
-        
-        
-        if flags == 0:
-            flags = None
-        if type(version) in (types.StringType, types.NoneType, types.UnicodeType):
-            (r_e, r_v, r_r) = rpmUtils.miscutils.stringToVersion(version)
-        elif type(version) in (types.TupleType, types.ListType): # would this ever be a ListType?
-            (r_e, r_v, r_r) = version
-        
-        defSack = ListPackageSack() # holder for items definitely providing this dep
-        
-        for po in pkgs:
-            self.verbose_logger.log(logginglevels.DEBUG_2,
-                'Potential match for %s from %s', name, po)
-            if name[0] == '/' and r_v is None:
-                # file dep add all matches to the defSack
-                defSack.addPackage(po)
-                continue
 
-            if po.checkPrco('provides', (name, flags, (r_e, r_v, r_r))):
-                defSack.addPackage(po)
-                self.verbose_logger.debug('Matched %s to require for %s', po, name)
-        
-        return defSack
+        return ListPackageSack(self.pkgSack.whatProvides(name, flags, version))
         
     def allowedMultipleInstalls(self, po):
         """takes a packageObject, returns 1 or 0 depending on if the package 
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	25 Apr 2007 16:16:30 -0000
@@ -64,6 +64,14 @@
         """return list of pkgobject matching the (n,a,e,v,r) tuple"""
         (n,a,e,v,r) = pkgtup
         return self.searchNevra(name=n, arch=a, epoch=e, ver=v, rel=r)
+
+    def whatProvides(self, name, flags, version):
+        """return list of package providing the name flags, version"""
+        raise NotImplementedError()
+
+    def whatRequires(self, name, flags, version):
+        """return list of package requiring the name flags, version"""
+        raise NotImplementedError()
         
     def searchRequires(self, name):
         """return list of package requiring the name (any evr and flag)"""
@@ -231,6 +239,16 @@
         """return list of pkgobjects matching the nevra requested"""
         return self._computeAggregateListResult("searchNevra", name, epoch, ver, rel, arch)
 
+    def whatProvides(self, name, flags, version):
+        """return list of package providing the name flags, version"""
+        return self._computeAggregateListResult("whatProvides",
+                                                name, flags, version)
+
+    def whatRequires(self, name, flags, version):
+        """return list of package requiring the name flags, version"""
+        return self._computeAggregateListResult("whatRequires",
+                                                name, flags, version)
+
     def searchRequires(self, name):
         """return list of package requiring the name (any evr and flag)"""
         return self._computeAggregateListResult("searchRequires", name)
Index: yum/sqlitesack.py
===================================================================
RCS file: /cvsroot/yum/cvs/yum/yum/sqlitesack.py,v
retrieving revision 1.96
diff -u -r1.96 sqlitesack.py
--- yum/sqlitesack.py	24 Apr 2007 21:13:06 -0000	1.96
+++ yum/sqlitesack.py	25 Apr 2007 16:16:30 -0000
@@ -32,6 +32,7 @@
 import warnings
 
 from sqlutils import executeSQL
+import rpmUtils.miscutils
 
 class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
     def __init__(self, repo, db_obj):
@@ -413,6 +414,62 @@
                 pkgs.append(ob)
         
         return pkgs
+
+
+    def _search(self, prcotype, name, flags, version):
+        if flags == 0:
+            flags = None
+        if type(version) in (str, type(None), unicode):
+            req = (name, flags, rpmUtils.miscutils.stringToVersion(
+                version))
+        elif type(version) in (tuple, list): # would this ever be a list?
+            req = (name, flags, version)
+
+        result = [ ]
+        
+        for (rep,cache) in self.primarydb.items():
+            cur = cache.cursor()
+            executeSQL(cur, "select packages.*, %s.name as n, %s.flags as f, "
+                       "%s.epoch as e, %s.version as v, %s.release as r "
+                       "from %s,packages "
+                       "where %s.name = ? and "
+                       "%s.pkgKey=packages.pkgKey" %
+                       ((prcotype,) * 8),
+                       (name,))
+            for x in cur:
+                val = (x[-5], x[-4], x[-3:])
+                if rpmUtils.miscutils.rangeCompare(req, val):
+                    result.append(self.pc(rep,x))
+                    
+        if prcotype != 'provides' or name[0] != '/':
+            return result
+
+        # If it is a filename, search the primary.xml file info
+        for (rep,cache) in self.primarydb.items():
+            cur = cache.cursor()
+            executeSQL(cur, "select DISTINCT packages.* from files,packages where files.name = ? and files.pkgKey = packages.pkgKey", (name,))
+            for x in cur:
+                if self._excluded(rep,x['pkgId']):
+                    continue
+                result.append(self.pc(rep,x))
+        
+        matched = 0
+        globs = ['.*bin\/.*', '^\/etc\/.*', '^\/usr\/lib\/sendmail$']
+        for thisglob in globs:
+            globc = re.compile(thisglob)
+            if globc.match(name):
+                matched = 1
+
+        if not matched: # if its not in the primary.xml files
+            # search the files.xml file info
+            result.extend(self.searchFiles(name))
+        return result
+
+    def whatProvides(self, name, flags, version):
+        return self._search("provides", name, flags, version)
+
+    def whatRequires(self, name, flags, version):
+        return self._search("requires", name, flags, version)
         
     
     def searchPrco(self, name, prcotype):
_______________________________________________
Yum-devel mailing list
[email protected]
https://lists.dulug.duke.edu/mailman/listinfo/yum-devel

Reply via email to