summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2007-10-26 08:38:16 +0000
committerZac Medico <zmedico@gentoo.org>2007-10-26 08:38:16 +0000
commit806ec9287a1547da737355df79fbe63b2b6cff00 (patch)
treeb76a3dbd1e02e59d6c98cb989fd5964d14f44d5d
parenta2c83b84058aa9aa59be6cee2449e81c70ae02fe (diff)
downloadportage-806ec9287a1547da737355df79fbe63b2b6cff00.tar.gz
portage-806ec9287a1547da737355df79fbe63b2b6cff00.tar.bz2
portage-806ec9287a1547da737355df79fbe63b2b6cff00.zip
Optimize repoman visibility checks to access as little
metadata as possible. (improves performance especially in cases where metadata needs to be generated). This works by starting at the lowest version since that's most likely to have keywords and it returns as soon as the first visible package is found. svn path=/main/trunk/; revision=8309
-rwxr-xr-xbin/repoman4
-rw-r--r--pym/portage/__init__.py8
-rw-r--r--pym/portage/dbapi/porttree.py72
3 files changed, 77 insertions, 7 deletions
diff --git a/bin/repoman b/bin/repoman
index 884931220..a57c30052 100755
--- a/bin/repoman
+++ b/bin/repoman
@@ -1455,10 +1455,10 @@ for x in scanlist:
continue
#we are testing deps for a masked package; give it some lee-way
suffix="masked"
- matchmode="match-all"
+ matchmode = "minimum-all"
else:
suffix=""
- matchmode="match-visible"
+ matchmode = "minimum-visible"
if prof[1] == "dev":
suffix=suffix+"indev"
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py
index cc713c1d2..06878c61c 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -4970,7 +4970,13 @@ def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1):
deplist[mypos] = False
else:
if mode:
- mydep=mydbapi.xmatch(mode,deplist[mypos])
+ x = mydbapi.xmatch(mode, deplist[mypos])
+ if mode.startswith("minimum-"):
+ mydep = []
+ if x:
+ mydep.append(x)
+ else:
+ mydep = x
else:
mydep=mydbapi.match(deplist[mypos],use_cache=use_cache)
if mydep!=None:
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index 05fe2a767..921293818 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -14,7 +14,7 @@ from portage.exception import OperationNotPermitted, PortageException, \
from portage.manifest import Manifest
from portage.output import red
from portage.util import ensure_dirs, writemsg, apply_recursive_permissions
-from portage.versions import pkgsplit, catpkgsplit, best
+from portage.versions import pkgcmp, pkgsplit, catpkgsplit, best
import portage.gpg, portage.checksum
@@ -521,13 +521,27 @@ class portdbapi(dbapi):
mylist = []
else:
mylist = d.keys()
+ # Always sort in ascending order here since it's handy
+ # and the result can be easily cached and reused.
+ if len(mylist) > 1:
+ for i in xrange(len(mylist)):
+ mylist[i] = catpkgsplit(mylist[i])[1:]
+ mylist.sort(pkgcmp)
+ cat = mysplit[0]
+ for i, (pn, ver, rev) in enumerate(mylist):
+ if rev == "r0":
+ cpv = cat + "/" + pn + "-" + ver
+ else:
+ cpv = cat + "/" + pn + "-" + ver + "-" + rev
+ mylist[i] = cpv
if self.frozen and mytree is None:
if not (not mylist and mycp.startswith("virtual/")):
self.xcache["match-all"][mycp] = mylist[:]
return mylist
def freeze(self):
- for x in ["list-visible", "bestmatch-visible", "match-visible", "match-all"]:
+ for x in "bestmatch-visible", "list-visible", "match-all", \
+ "match-visible", "minimum-all", "minimum-visible":
self.xcache[x]={}
self.frozen=1
@@ -550,6 +564,7 @@ class portdbapi(dbapi):
mydep = dep_expand(origdep, mydb=self, settings=self.mysettings)
mykey = dep_getkey(mydep)
+ myslot = dep_getslot(mydep)
if level == "list-visible":
#a list of all visible packages, not called directly (just by xmatch())
#myval = self.visible(self.cp_list(mykey))
@@ -560,6 +575,56 @@ class portdbapi(dbapi):
#get all visible matches (from xmatch()), then choose the best one
myval = best(self.xmatch("match-visible", None, mydep=mydep, mykey=mykey))
+ elif level == "minimum-all":
+ # Find the minimum matching version. This is optimized to
+ # minimize the number of metadata accesses (improves performance
+ # especially in cases where metadata needs to be generated).
+ if mydep == mykey:
+ mylist = self.cp_list(mykey)
+ else:
+ mylist = match_from_list(mydep, self.cp_list(mykey))
+ myval = ""
+ if mylist:
+ if myslot is None:
+ myval = mylist[0]
+ else:
+ for cpv in mylist:
+ try:
+ if self.aux_get(cpv, ["SLOT"])[0] == myslot:
+ myval = cpv
+ break
+ except KeyError:
+ pass # ebuild masked by corruption
+ elif level == "minimum-visible":
+ # Find the minimum matching visible version. This is optimized to
+ # minimize the number of metadata accesses (improves performance
+ # especially in cases where metadata needs to be generated).
+ # This does not implement LICENSE filtering since it's only
+ # intended for use by repoman.
+ if mydep == mykey:
+ mylist = self.cp_list(mykey)
+ else:
+ mylist = match_from_list(mydep, self.cp_list(mykey))
+ myval = ""
+ settings = self.mysettings
+ for cpv in mylist:
+ try:
+ metadata = dict(izip(self._aux_cache_keys,
+ self.aux_get(cpv, self._aux_cache_keys)))
+ except KeyError:
+ # ebuild masked by corruption
+ continue
+ if not eapi_is_supported(metadata["EAPI"]):
+ continue
+ if myslot and myslot != metadata["SLOT"]:
+ continue
+ if settings.getMissingKeywords(cpv, metadata):
+ continue
+ if settings.getMaskAtom(cpv, metadata):
+ continue
+ if settings.getProfileMaskAtom(cpv, metadata):
+ continue
+ myval = cpv
elif level == "bestmatch-list":
#dep match -- find best match but restrict search to sublist
#no point in calling xmatch again since we're not caching list deps
@@ -584,8 +649,7 @@ class portdbapi(dbapi):
else:
print "ERROR: xmatch doesn't handle", level, "query!"
raise KeyError
- myslot = dep_getslot(mydep)
- if myslot is not None:
+ if myslot is not None and isinstance(myval, list):
slotmatches = []
for cpv in myval:
try: