Gentoo Archives: gentoo-portage-dev

From: Brian Dolbec <dolsen@g.o>
To: gentoo-portage-dev@l.g.o
Subject: Re: [gentoo-portage-dev] [PATCH] portdbapi.cp_list: cache repo associations (bug 650814)
Date: Sun, 15 Jul 2018 04:42:14
Message-Id: 20180714214210.710b7623@professor-x
In Reply to: [gentoo-portage-dev] [PATCH] portdbapi.cp_list: cache repo associations (bug 650814) by Zac Medico
1 On Sat, 14 Jul 2018 21:05:39 -0700
2 Zac Medico <zmedico@g.o> wrote:
3
4 > Make portdbapi.cp_list return _pkg_str instances that have a 'repo'
5 > attribute (bindbapi.cp_list already does this), with results
6 > in ascending order by (pkg.version, repo.priority). Optimize
7 > portdbapi.findname2 to use the 'repo' attribute to enable cached
8 > results for files previously found by the portdbapi.cp_list
9 > method, avoiding filesystem access when possible. Optimize the
10 > depgraph._iter_match_pkgs_atom method by elimination of the repo
11 > loop, since portdbapi.cp_list now returns separate items when the
12 > same package version is found in multiple repos.
13 >
14 > Bug: https://bugs.gentoo.org/650814
15 > ---
16 > pym/_emerge/depgraph.py | 12 +++---------
17 > pym/portage/dbapi/porttree.py | 41
18 > +++++++++++++++++++++++++++++------------ 2 files changed, 32
19 > insertions(+), 21 deletions(-)
20 >
21 > diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
22 > index 42857c1a5..b63d4f242 100644
23 > --- a/pym/_emerge/depgraph.py
24 > +++ b/pym/_emerge/depgraph.py
25 > @@ -5613,10 +5613,6 @@ class depgraph(object):
26 > if cp_list:
27 > atom_set =
28 > InternalPackageSet(initial_atoms=(atom,), allow_repo=True)
29 > - if atom.repo is None and hasattr(db,
30 > "getRepositories"):
31 > - repo_list =
32 > db.getRepositories(catpkg=atom_exp.cp)
33 > - else:
34 > - repo_list = [atom.repo]
35 >
36 > # descending order
37 > cp_list.reverse()
38 > @@ -5624,13 +5620,11 @@ class depgraph(object):
39 > # Call match_from_list on one cpv at
40 > a time, in order # to avoid unnecessary match_from_list comparisons on
41 > # versions that are never yielded
42 > from this method.
43 > - if not match_from_list(atom_exp,
44 > [cpv]):
45 > - continue
46 > - for repo in repo_list:
47 > -
48 > + if match_from_list(atom_exp, [cpv]):
49 > try:
50 > pkg = self._pkg(cpv,
51 > pkg_type, root_config,
52 > -
53 > installed=installed, onlydeps=onlydeps, myrepo=repo)
54 > +
55 > installed=installed, onlydeps=onlydeps,
56 > +
57 > myrepo=getattr(cpv, 'repo', None)) except
58 > portage.exception.PackageNotFound: pass
59 > else:
60 > diff --git a/pym/portage/dbapi/porttree.py
61 > b/pym/portage/dbapi/porttree.py index 3e36024ff..f6076ee2b 100644
62 > --- a/pym/portage/dbapi/porttree.py
63 > +++ b/pym/portage/dbapi/porttree.py
64 > @@ -459,6 +459,9 @@ class portdbapi(dbapi):
65 > mytree = self.treemap.get(myrepo)
66 > if mytree is None:
67 > return (None, 0)
68 > + elif mytree is not None:
69 > + # myrepo enables cached results when
70 > available
71 > + myrepo =
72 > self.repositories.location_map.get(mytree)
73 > mysplit = mycpv.split("/")
74 > psplit = pkgsplit(mysplit[1])
75 > @@ -495,6 +498,14 @@ class portdbapi(dbapi):
76 > relative_path = mysplit[0] + _os.sep + psplit[0] +
77 > _os.sep + \ mysplit[1] + ".ebuild"
78 >
79 > + # There is no need to access the filesystem when the
80 > package
81 > + # comes from this db and the package repo attribute
82 > corresponds
83 > + # to the desired repo, since the file was previously
84 > found by
85 > + # the cp_list method.
86 > + if (myrepo is not None and myrepo == getattr(mycpv,
87 > 'repo', None)
88 > + and self is getattr(mycpv, '_db', None)):
89 > + return (mytree + _os.sep + relative_path,
90 > mytree) +
91 > for x in mytrees:
92 > filename = x + _os.sep + relative_path
93 > if _os.access(_unicode_encode(filename,
94 > @@ -950,18 +961,23 @@ class portdbapi(dbapi):
95 > return cachelist[:]
96 > mysplit = mycp.split("/")
97 > invalid_category = mysplit[0] not in self._categories
98 > - d={}
99 > + # Process repos in ascending order by repo.priority,
100 > so that
101 > + # stable sort by version produces results ordered by
102 > + # (pkg.version, repo.priority).
103 > if mytree is not None:
104 > if isinstance(mytree, basestring):
105 > - mytrees = [mytree]
106 > + repos =
107 > [self.repositories.get_repo_for_location(mytree)] else:
108 > # assume it's iterable
109 > - mytrees = mytree
110 > + repos =
111 > [self.repositories.get_repo_for_location(location)
112 > + for location in mytree]
113 > elif self._better_cache is None:
114 > - mytrees = self.porttrees
115 > + repos = list(self.repositories)
116 > else:
117 > - mytrees = [repo.location for repo in
118 > self._better_cache[mycp]]
119 > - for oroot in mytrees:
120 > + repos = reversed(self._better_cache[mycp])
121 > + mylist = []
122 > + for repo in repos:
123 > + oroot = repo.location
124 > try:
125 > file_list =
126 > os.listdir(os.path.join(oroot, mycp)) except OSError:
127 > @@ -986,16 +1002,17 @@ class portdbapi(dbapi):
128 > writemsg(_("\nInvalid
129 > ebuild version: %s\n") % \ os.path.join(oroot, mycp, x),
130 > noiselevel=-1) continue
131 > -
132 > d[_pkg_str(mysplit[0]+"/"+pf, db=self)] = None
133 > - if invalid_category and d:
134 > +
135 > mylist.append(_pkg_str(mysplit[0]+"/"+pf, db=self, repo=repo.name))
136 > + if invalid_category and mylist:
137 > writemsg(_("\n!!! '%s' has a category that
138 > is not listed in " \ "%setc/portage/categories\n") % \
139 > (mycp,
140 > self.settings["PORTAGE_CONFIGROOT"]), noiselevel=-1) mylist = []
141 > - else:
142 > - mylist = list(d)
143 > - # Always sort in ascending order here since it's
144 > handy
145 > - # and the result can be easily cached and reused.
146 > + # Always sort in ascending order here since it's
147 > handy and
148 > + # the result can be easily cached and reused. Since
149 > mylist
150 > + # is initially in ascending order by repo.priority,
151 > stable
152 > + # sort by version produces results in ascending
153 > order by
154 > + # (pkg.version, repo.priority).
155 > self._cpv_sort_ascending(mylist)
156 > if self.frozen and mytree is None:
157 > cachelist = mylist[:]
158
159 looks fine
160
161 --
162 Brian Dolbec <dolsen>

Replies