1 |
commit: 0903cf2a1544d970b286a3e7e1f3276daa4eab9c |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun May 13 07:32:04 2012 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun May 13 07:32:04 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=0903cf2a |
7 |
|
8 |
depgraph: minimize match_from_list operations |
9 |
|
10 |
In _iter_match_pkgs, call match_from_list on one cpv at a time, in |
11 |
order to avoid unnecessary match_from_list comparisons on versions that |
12 |
are never yielded from this method. |
13 |
|
14 |
--- |
15 |
pym/_emerge/depgraph.py | 122 ++++++++++++++++++++++++---------------------- |
16 |
1 files changed, 64 insertions(+), 58 deletions(-) |
17 |
|
18 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
19 |
index 4d3b04c..5152d5c 100644 |
20 |
--- a/pym/_emerge/depgraph.py |
21 |
+++ b/pym/_emerge/depgraph.py |
22 |
@@ -18,8 +18,10 @@ from portage import os, OrderedDict |
23 |
from portage import _unicode_decode, _unicode_encode, _encodings |
24 |
from portage.const import PORTAGE_PACKAGE_ATOM, USER_CONFIG_PATH |
25 |
from portage.dbapi import dbapi |
26 |
+from portage.dbapi.dep_expand import dep_expand |
27 |
from portage.dep import Atom, best_match_to_list, extract_affecting_use, \ |
28 |
- check_required_use, human_readable_required_use, _repo_separator |
29 |
+ check_required_use, human_readable_required_use, match_from_list, \ |
30 |
+ _repo_separator |
31 |
from portage.eapi import eapi_has_strong_blocks, eapi_has_required_use |
32 |
from portage.exception import InvalidAtom, InvalidDependString, PortageException |
33 |
from portage.output import colorize, create_color_func, \ |
34 |
@@ -3382,60 +3384,12 @@ class depgraph(object): |
35 |
""" |
36 |
|
37 |
db = root_config.trees[self.pkg_tree_map[pkg_type]].dbapi |
38 |
- |
39 |
- if hasattr(db, "xmatch"): |
40 |
- # For portdbapi we match only against the cpv, in order |
41 |
- # to bypass unnecessary cache access for things like IUSE |
42 |
- # and SLOT. Later, we cache the metadata in a Package |
43 |
- # instance, and use that for further matching. This |
44 |
- # optimization is especially relevant since |
45 |
- # pordbapi.aux_get() does not cache calls that have |
46 |
- # myrepo or mytree arguments. |
47 |
- cpv_list = db.xmatch("match-all-cpv-only", atom) |
48 |
- else: |
49 |
- cpv_list = db.match(atom) |
50 |
- |
51 |
- # USE=multislot can make an installed package appear as if |
52 |
- # it doesn't satisfy a slot dependency. Rebuilding the ebuild |
53 |
- # won't do any good as long as USE=multislot is enabled since |
54 |
- # the newly built package still won't have the expected slot. |
55 |
- # Therefore, assume that such SLOT dependencies are already |
56 |
- # satisfied rather than forcing a rebuild. |
57 |
+ atom_exp = dep_expand(atom, mydb=db, settings=root_config.settings) |
58 |
+ cp_list = db.cp_list(atom_exp.cp) |
59 |
+ matched_something = False |
60 |
installed = pkg_type == 'installed' |
61 |
- if installed and not cpv_list and atom.slot: |
62 |
|
63 |
- if "remove" in self._dynamic_config.myparams: |
64 |
- # We need to search the portdbapi, which is not in our |
65 |
- # normal dbs list, in order to find the real SLOT. |
66 |
- portdb = self._frozen_config.trees[root_config.root]["porttree"].dbapi |
67 |
- db_keys = list(portdb._aux_cache_keys) |
68 |
- dbs = [(portdb, "ebuild", False, False, db_keys)] |
69 |
- else: |
70 |
- dbs = self._dynamic_config._filtered_trees[root_config.root]["dbs"] |
71 |
- |
72 |
- for cpv in db.match(atom.cp): |
73 |
- slot_available = False |
74 |
- for other_db, other_type, other_built, \ |
75 |
- other_installed, other_keys in dbs: |
76 |
- try: |
77 |
- if atom.slot == \ |
78 |
- other_db.aux_get(cpv, ["SLOT"])[0]: |
79 |
- slot_available = True |
80 |
- break |
81 |
- except KeyError: |
82 |
- pass |
83 |
- if not slot_available: |
84 |
- continue |
85 |
- inst_pkg = self._pkg(cpv, "installed", |
86 |
- root_config, installed=installed, myrepo = atom.repo) |
87 |
- # Remove the slot from the atom and verify that |
88 |
- # the package matches the resulting atom. |
89 |
- if portage.match_from_list( |
90 |
- atom.without_slot, [inst_pkg]): |
91 |
- yield inst_pkg |
92 |
- return |
93 |
- |
94 |
- if cpv_list: |
95 |
+ if cp_list: |
96 |
atom_set = InternalPackageSet(initial_atoms=(atom,), |
97 |
allow_repo=True) |
98 |
if atom.repo is None and hasattr(db, "getRepositories"): |
99 |
@@ -3444,8 +3398,13 @@ class depgraph(object): |
100 |
repo_list = [atom.repo] |
101 |
|
102 |
# descending order |
103 |
- cpv_list.reverse() |
104 |
- for cpv in cpv_list: |
105 |
+ cp_list.reverse() |
106 |
+ for cpv in cp_list: |
107 |
+ # Call match_from_list on one cpv at a time, in order |
108 |
+ # to avoid unnecessary match_from_list comparisons on |
109 |
+ # versions that are never yielded from this method. |
110 |
+ if not match_from_list(atom_exp, [cpv]): |
111 |
+ continue |
112 |
for repo in repo_list: |
113 |
|
114 |
try: |
115 |
@@ -3462,14 +3421,61 @@ class depgraph(object): |
116 |
# Make sure that cpv from the current repo satisfies the atom. |
117 |
# This might not be the case if there are several repos with |
118 |
# the same cpv, but different metadata keys, like SLOT. |
119 |
- # Also, for portdbapi, parts of the match that require |
120 |
- # metadata access are deferred until we have cached the |
121 |
- # metadata in a Package instance. |
122 |
+ # Also, parts of the match that require metadata access |
123 |
+ # are deferred until we have cached the metadata in a |
124 |
+ # Package instance. |
125 |
if not atom_set.findAtomForPackage(pkg, |
126 |
modified_use=self._pkg_use_enabled(pkg)): |
127 |
continue |
128 |
+ matched_something = True |
129 |
yield pkg |
130 |
|
131 |
+ # USE=multislot can make an installed package appear as if |
132 |
+ # it doesn't satisfy a slot dependency. Rebuilding the ebuild |
133 |
+ # won't do any good as long as USE=multislot is enabled since |
134 |
+ # the newly built package still won't have the expected slot. |
135 |
+ # Therefore, assume that such SLOT dependencies are already |
136 |
+ # satisfied rather than forcing a rebuild. |
137 |
+ if not matched_something and installed and atom.slot is not None: |
138 |
+ |
139 |
+ if "remove" in self._dynamic_config.myparams: |
140 |
+ # We need to search the portdbapi, which is not in our |
141 |
+ # normal dbs list, in order to find the real SLOT. |
142 |
+ portdb = self._frozen_config.trees[root_config.root]["porttree"].dbapi |
143 |
+ db_keys = list(portdb._aux_cache_keys) |
144 |
+ dbs = [(portdb, "ebuild", False, False, db_keys)] |
145 |
+ else: |
146 |
+ dbs = self._dynamic_config._filtered_trees[root_config.root]["dbs"] |
147 |
+ |
148 |
+ cp_list = db.cp_list(atom_exp.cp) |
149 |
+ if cp_list: |
150 |
+ atom_set = InternalPackageSet( |
151 |
+ initial_atoms=(atom.without_slot,), allow_repo=True) |
152 |
+ atom_exp_without_slot = atom_exp.without_slot |
153 |
+ cp_list.reverse() |
154 |
+ for cpv in cp_list: |
155 |
+ if not match_from_list(atom_exp_without_slot, [cpv]): |
156 |
+ continue |
157 |
+ slot_available = False |
158 |
+ for other_db, other_type, other_built, \ |
159 |
+ other_installed, other_keys in dbs: |
160 |
+ try: |
161 |
+ if atom.slot == \ |
162 |
+ other_db.aux_get(cpv, ["SLOT"])[0]: |
163 |
+ slot_available = True |
164 |
+ break |
165 |
+ except KeyError: |
166 |
+ pass |
167 |
+ if not slot_available: |
168 |
+ continue |
169 |
+ inst_pkg = self._pkg(cpv, "installed", |
170 |
+ root_config, installed=installed, myrepo=atom.repo) |
171 |
+ # Remove the slot from the atom and verify that |
172 |
+ # the package matches the resulting atom. |
173 |
+ if atom_set.findAtomForPackage(inst_pkg): |
174 |
+ yield inst_pkg |
175 |
+ return |
176 |
+ |
177 |
def _select_pkg_highest_available(self, root, atom, onlydeps=False): |
178 |
cache_key = (root, atom, atom.unevaluated_atom, onlydeps) |
179 |
ret = self._dynamic_config._highest_pkg_cache.get(cache_key) |