public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* [gentoo-portage-dev] [PATCH] portdbapi.cp_list: cache repo associations (bug 650814)
@ 2018-07-15  4:05 99% Zac Medico
  0 siblings, 0 replies; 1+ results
From: Zac Medico @ 2018-07-15  4:05 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

Make portdbapi.cp_list return _pkg_str instances that have a 'repo'
attribute (bindbapi.cp_list already does this), with results
in ascending order by (pkg.version, repo.priority). Optimize
portdbapi.findname2 to use the 'repo' attribute to enable cached
results for files previously found by the portdbapi.cp_list
method, avoiding filesystem access when possible. Optimize the
depgraph._iter_match_pkgs_atom method by elimination of the repo
loop, since portdbapi.cp_list now returns separate items when the
same package version is found in multiple repos.

Bug: https://bugs.gentoo.org/650814
---
 pym/_emerge/depgraph.py       | 12 +++---------
 pym/portage/dbapi/porttree.py | 41 +++++++++++++++++++++++++++++------------
 2 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index 42857c1a5..b63d4f242 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -5613,10 +5613,6 @@ class depgraph(object):
 		if cp_list:
 			atom_set = InternalPackageSet(initial_atoms=(atom,),
 				allow_repo=True)
-			if atom.repo is None and hasattr(db, "getRepositories"):
-				repo_list = db.getRepositories(catpkg=atom_exp.cp)
-			else:
-				repo_list = [atom.repo]
 
 			# descending order
 			cp_list.reverse()
@@ -5624,13 +5620,11 @@ class depgraph(object):
 				# Call match_from_list on one cpv at a time, in order
 				# to avoid unnecessary match_from_list comparisons on
 				# versions that are never yielded from this method.
-				if not match_from_list(atom_exp, [cpv]):
-					continue
-				for repo in repo_list:
-
+				if match_from_list(atom_exp, [cpv]):
 					try:
 						pkg = self._pkg(cpv, pkg_type, root_config,
-							installed=installed, onlydeps=onlydeps, myrepo=repo)
+							installed=installed, onlydeps=onlydeps,
+							myrepo=getattr(cpv, 'repo', None))
 					except portage.exception.PackageNotFound:
 						pass
 					else:
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index 3e36024ff..f6076ee2b 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -459,6 +459,9 @@ class portdbapi(dbapi):
 			mytree = self.treemap.get(myrepo)
 			if mytree is None:
 				return (None, 0)
+		elif mytree is not None:
+			# myrepo enables cached results when available
+			myrepo = self.repositories.location_map.get(mytree)
 
 		mysplit = mycpv.split("/")
 		psplit = pkgsplit(mysplit[1])
@@ -495,6 +498,14 @@ class portdbapi(dbapi):
 		relative_path = mysplit[0] + _os.sep + psplit[0] + _os.sep + \
 			mysplit[1] + ".ebuild"
 
+		# There is no need to access the filesystem when the package
+		# comes from this db and the package repo attribute corresponds
+		# to the desired repo, since the file was previously found by
+		# the cp_list method.
+		if (myrepo is not None and myrepo == getattr(mycpv, 'repo', None)
+			and self is getattr(mycpv, '_db', None)):
+			return (mytree + _os.sep + relative_path, mytree)
+
 		for x in mytrees:
 			filename = x + _os.sep + relative_path
 			if _os.access(_unicode_encode(filename,
@@ -950,18 +961,23 @@ class portdbapi(dbapi):
 				return cachelist[:]
 		mysplit = mycp.split("/")
 		invalid_category = mysplit[0] not in self._categories
-		d={}
+		# Process repos in ascending order by repo.priority, so that
+		# stable sort by version produces results ordered by
+		# (pkg.version, repo.priority).
 		if mytree is not None:
 			if isinstance(mytree, basestring):
-				mytrees = [mytree]
+				repos = [self.repositories.get_repo_for_location(mytree)]
 			else:
 				# assume it's iterable
-				mytrees = mytree
+				repos = [self.repositories.get_repo_for_location(location)
+					for location in mytree]
 		elif self._better_cache is None:
-			mytrees = self.porttrees
+			repos = list(self.repositories)
 		else:
-			mytrees = [repo.location for repo in self._better_cache[mycp]]
-		for oroot in mytrees:
+			repos = reversed(self._better_cache[mycp])
+		mylist = []
+		for repo in repos:
+			oroot = repo.location
 			try:
 				file_list = os.listdir(os.path.join(oroot, mycp))
 			except OSError:
@@ -986,16 +1002,17 @@ class portdbapi(dbapi):
 						writemsg(_("\nInvalid ebuild version: %s\n") % \
 							os.path.join(oroot, mycp, x), noiselevel=-1)
 						continue
-					d[_pkg_str(mysplit[0]+"/"+pf, db=self)] = None
-		if invalid_category and d:
+					mylist.append(_pkg_str(mysplit[0]+"/"+pf, db=self, repo=repo.name))
+		if invalid_category and mylist:
 			writemsg(_("\n!!! '%s' has a category that is not listed in " \
 				"%setc/portage/categories\n") % \
 				(mycp, self.settings["PORTAGE_CONFIGROOT"]), noiselevel=-1)
 			mylist = []
-		else:
-			mylist = list(d)
-		# Always sort in ascending order here since it's handy
-		# and the result can be easily cached and reused.
+		# Always sort in ascending order here since it's handy and
+		# the result can be easily cached and reused. Since mylist
+		# is initially in ascending order by repo.priority, stable
+		# sort by version produces results in ascending order by
+		# (pkg.version, repo.priority).
 		self._cpv_sort_ascending(mylist)
 		if self.frozen and mytree is None:
 			cachelist = mylist[:]
-- 
2.13.6



^ permalink raw reply related	[relevance 99%]

Results 1-1 of 1 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2018-07-15  4:05 99% [gentoo-portage-dev] [PATCH] portdbapi.cp_list: cache repo associations (bug 650814) Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox