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> |