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