1 |
Author: zmedico |
2 |
Date: 2009-07-03 01:29:41 +0000 (Fri, 03 Jul 2009) |
3 |
New Revision: 13760 |
4 |
|
5 |
Modified: |
6 |
main/trunk/pym/_emerge/depgraph.py |
7 |
Log: |
8 |
Add a frozen_config parameter to the depgraph constructor, so that multiple |
9 |
depgraph instances created for backtracking purposes can reuse the same |
10 |
frozen_config instance. |
11 |
|
12 |
|
13 |
Modified: main/trunk/pym/_emerge/depgraph.py |
14 |
=================================================================== |
15 |
--- main/trunk/pym/_emerge/depgraph.py 2009-07-03 00:52:44 UTC (rev 13759) |
16 |
+++ main/trunk/pym/_emerge/depgraph.py 2009-07-03 01:29:41 UTC (rev 13760) |
17 |
@@ -54,7 +54,7 @@ |
18 |
|
19 |
class _frozen_depgraph_config(object): |
20 |
|
21 |
- def __init__(self, settings, trees, myopts, spinner, dynamic_config, depgraph): |
22 |
+ def __init__(self, settings, trees, myopts, spinner): |
23 |
self.settings = settings |
24 |
self.target_root = settings["ROOT"] |
25 |
self.myopts = myopts |
26 |
@@ -69,9 +69,8 @@ |
27 |
self.trees = {} |
28 |
self._trees_orig = trees |
29 |
self.roots = {} |
30 |
- # Contains installed packages and new packages that have been added |
31 |
- # to the graph. |
32 |
- self._graph_trees = {} |
33 |
+ # All Package instances |
34 |
+ self._pkg_cache = {} |
35 |
for myroot in trees: |
36 |
self.trees[myroot] = {} |
37 |
# Create a RootConfig instance that references |
38 |
@@ -84,91 +83,15 @@ |
39 |
self.trees[myroot][tree] = trees[myroot][tree] |
40 |
self.trees[myroot]["vartree"] = \ |
41 |
FakeVartree(trees[myroot]["root_config"], |
42 |
- pkg_cache=dynamic_config._pkg_cache) |
43 |
+ pkg_cache=self._pkg_cache) |
44 |
self.pkgsettings[myroot] = portage.config( |
45 |
clone=self.trees[myroot]["vartree"].settings) |
46 |
- dynamic_config._slot_pkg_map[myroot] = {} |
47 |
- vardb = self.trees[myroot]["vartree"].dbapi |
48 |
- preload_installed_pkgs = "--nodeps" not in self.myopts and \ |
49 |
- "--buildpkgonly" not in self.myopts |
50 |
- # This fakedbapi instance will model the state that the vdb will |
51 |
- # have after new packages have been installed. |
52 |
- fakedb = PackageVirtualDbapi(vardb.settings) |
53 |
- if preload_installed_pkgs: |
54 |
- for pkg in vardb: |
55 |
- self.spinner.update() |
56 |
- # This triggers metadata updates via FakeVartree. |
57 |
- vardb.aux_get(pkg.cpv, []) |
58 |
- fakedb.cpv_inject(pkg) |
59 |
|
60 |
- # Now that the vardb state is cached in our FakeVartree, |
61 |
- # we won't be needing the real vartree cache for awhile. |
62 |
- # To make some room on the heap, clear the vardbapi |
63 |
- # caches. |
64 |
- trees[myroot]["vartree"].dbapi._clear_cache() |
65 |
- gc.collect() |
66 |
- |
67 |
- dynamic_config.mydbapi[myroot] = fakedb |
68 |
- def graph_tree(): |
69 |
- pass |
70 |
- graph_tree.dbapi = fakedb |
71 |
- self._graph_trees[myroot] = {} |
72 |
- dynamic_config._filtered_trees[myroot] = {} |
73 |
- # Substitute the graph tree for the vartree in dep_check() since we |
74 |
- # want atom selections to be consistent with package selections |
75 |
- # have already been made. |
76 |
- self._graph_trees[myroot]["porttree"] = graph_tree |
77 |
- self._graph_trees[myroot]["vartree"] = graph_tree |
78 |
- def filtered_tree(): |
79 |
- pass |
80 |
- filtered_tree.dbapi = _dep_check_composite_db(depgraph, myroot) |
81 |
- dynamic_config._filtered_trees[myroot]["porttree"] = filtered_tree |
82 |
- dynamic_config._visible_pkgs[myroot] = PackageVirtualDbapi(vardb.settings) |
83 |
- |
84 |
- # Passing in graph_tree as the vartree here could lead to better |
85 |
- # atom selections in some cases by causing atoms for packages that |
86 |
- # have been added to the graph to be preferred over other choices. |
87 |
- # However, it can trigger atom selections that result in |
88 |
- # unresolvable direct circular dependencies. For example, this |
89 |
- # happens with gwydion-dylan which depends on either itself or |
90 |
- # gwydion-dylan-bin. In case gwydion-dylan is not yet installed, |
91 |
- # gwydion-dylan-bin needs to be selected in order to avoid a |
92 |
- # an unresolvable direct circular dependency. |
93 |
- # |
94 |
- # To solve the problem described above, pass in "graph_db" so that |
95 |
- # packages that have been added to the graph are distinguishable |
96 |
- # from other available packages and installed packages. Also, pass |
97 |
- # the parent package into self._select_atoms() calls so that |
98 |
- # unresolvable direct circular dependencies can be detected and |
99 |
- # avoided when possible. |
100 |
- dynamic_config._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi |
101 |
- dynamic_config._filtered_trees[myroot]["vartree"] = self.trees[myroot]["vartree"] |
102 |
- |
103 |
- dbs = [] |
104 |
- portdb = self.trees[myroot]["porttree"].dbapi |
105 |
- bindb = self.trees[myroot]["bintree"].dbapi |
106 |
- vardb = self.trees[myroot]["vartree"].dbapi |
107 |
- # (db, pkg_type, built, installed, db_keys) |
108 |
- if "--usepkgonly" not in self.myopts: |
109 |
- db_keys = list(portdb._aux_cache_keys) |
110 |
- dbs.append((portdb, "ebuild", False, False, db_keys)) |
111 |
- if "--usepkg" in self.myopts: |
112 |
- db_keys = list(bindb._aux_cache_keys) |
113 |
- dbs.append((bindb, "binary", True, False, db_keys)) |
114 |
- db_keys = list(trees[myroot]["vartree"].dbapi._aux_cache_keys) |
115 |
- dbs.append((vardb, "installed", True, True, db_keys)) |
116 |
- dynamic_config._filtered_trees[myroot]["dbs"] = dbs |
117 |
- if "--usepkg" in self.myopts: |
118 |
- self.trees[myroot]["bintree"].populate( |
119 |
- "--getbinpkg" in self.myopts, |
120 |
- "--getbinpkgonly" in self.myopts) |
121 |
- del trees |
122 |
- |
123 |
self._required_set_names = set(["system", "world"]) |
124 |
|
125 |
class _dynamic_depgraph_config(object): |
126 |
|
127 |
- def __init__(self, myparams): |
128 |
+ def __init__(self, depgraph, myparams): |
129 |
self.myparams = myparams |
130 |
# Maps slot atom to package for each Package added to the graph. |
131 |
self._slot_pkg_map = {} |
132 |
@@ -178,11 +101,12 @@ |
133 |
# Contains a filtered view of preferred packages that are selected |
134 |
# from available repositories. |
135 |
self._filtered_trees = {} |
136 |
+ # Contains installed packages and new packages that have been added |
137 |
+ # to the graph. |
138 |
+ self._graph_trees = {} |
139 |
# Caches visible packages returned from _select_package, for use in |
140 |
# depgraph._iter_atoms_for_pkg() SLOT logic. |
141 |
self._visible_pkgs = {} |
142 |
- # All Package instances |
143 |
- self._pkg_cache = {} |
144 |
#contains the args created by select_files |
145 |
self._initial_arg_list = [] |
146 |
self.digraph = portage.digraph() |
147 |
@@ -232,18 +156,102 @@ |
148 |
self._ignored_deps = [] |
149 |
self._highest_pkg_cache = {} |
150 |
|
151 |
+ for myroot in depgraph._frozen_config.trees: |
152 |
+ self._slot_pkg_map[myroot] = {} |
153 |
+ vardb = depgraph._frozen_config.trees[myroot]["vartree"].dbapi |
154 |
+ preload_installed_pkgs = \ |
155 |
+ "--nodeps" not in depgraph._frozen_config.myopts and \ |
156 |
+ "--buildpkgonly" not in depgraph._frozen_config.myopts |
157 |
+ # This fakedbapi instance will model the state that the vdb will |
158 |
+ # have after new packages have been installed. |
159 |
+ fakedb = PackageVirtualDbapi(vardb.settings) |
160 |
+ if preload_installed_pkgs: |
161 |
+ for pkg in vardb: |
162 |
+ depgraph._frozen_config.spinner.update() |
163 |
+ # This triggers metadata updates via FakeVartree. |
164 |
+ vardb.aux_get(pkg.cpv, []) |
165 |
+ fakedb.cpv_inject(pkg) |
166 |
|
167 |
+ # Now that the vardb state is cached in our FakeVartree, |
168 |
+ # we won't be needing the real vartree cache for awhile. |
169 |
+ # To make some room on the heap, clear the vardbapi |
170 |
+ # caches. |
171 |
+ depgraph._frozen_config._trees_orig[myroot |
172 |
+ ]["vartree"].dbapi._clear_cache() |
173 |
+ gc.collect() |
174 |
+ |
175 |
+ self.mydbapi[myroot] = fakedb |
176 |
+ def graph_tree(): |
177 |
+ pass |
178 |
+ graph_tree.dbapi = fakedb |
179 |
+ self._graph_trees[myroot] = {} |
180 |
+ self._filtered_trees[myroot] = {} |
181 |
+ # Substitute the graph tree for the vartree in dep_check() since we |
182 |
+ # want atom selections to be consistent with package selections |
183 |
+ # have already been made. |
184 |
+ self._graph_trees[myroot]["porttree"] = graph_tree |
185 |
+ self._graph_trees[myroot]["vartree"] = graph_tree |
186 |
+ def filtered_tree(): |
187 |
+ pass |
188 |
+ filtered_tree.dbapi = _dep_check_composite_db(depgraph, myroot) |
189 |
+ self._filtered_trees[myroot]["porttree"] = filtered_tree |
190 |
+ self._visible_pkgs[myroot] = PackageVirtualDbapi(vardb.settings) |
191 |
+ |
192 |
+ # Passing in graph_tree as the vartree here could lead to better |
193 |
+ # atom selections in some cases by causing atoms for packages that |
194 |
+ # have been added to the graph to be preferred over other choices. |
195 |
+ # However, it can trigger atom selections that result in |
196 |
+ # unresolvable direct circular dependencies. For example, this |
197 |
+ # happens with gwydion-dylan which depends on either itself or |
198 |
+ # gwydion-dylan-bin. In case gwydion-dylan is not yet installed, |
199 |
+ # gwydion-dylan-bin needs to be selected in order to avoid a |
200 |
+ # an unresolvable direct circular dependency. |
201 |
+ # |
202 |
+ # To solve the problem described above, pass in "graph_db" so that |
203 |
+ # packages that have been added to the graph are distinguishable |
204 |
+ # from other available packages and installed packages. Also, pass |
205 |
+ # the parent package into self._select_atoms() calls so that |
206 |
+ # unresolvable direct circular dependencies can be detected and |
207 |
+ # avoided when possible. |
208 |
+ self._filtered_trees[myroot]["graph_db"] = graph_tree.dbapi |
209 |
+ self._filtered_trees[myroot]["vartree"] = \ |
210 |
+ depgraph._frozen_config.trees[myroot]["vartree"] |
211 |
+ |
212 |
+ dbs = [] |
213 |
+ portdb = depgraph._frozen_config.trees[myroot]["porttree"].dbapi |
214 |
+ bindb = depgraph._frozen_config.trees[myroot]["bintree"].dbapi |
215 |
+ vardb = depgraph._frozen_config.trees[myroot]["vartree"].dbapi |
216 |
+ # (db, pkg_type, built, installed, db_keys) |
217 |
+ if "--usepkgonly" not in depgraph._frozen_config.myopts: |
218 |
+ db_keys = list(portdb._aux_cache_keys) |
219 |
+ dbs.append((portdb, "ebuild", False, False, db_keys)) |
220 |
+ if "--usepkg" in depgraph._frozen_config.myopts: |
221 |
+ db_keys = list(bindb._aux_cache_keys) |
222 |
+ dbs.append((bindb, "binary", True, False, db_keys)) |
223 |
+ db_keys = list(depgraph._frozen_config._trees_orig[myroot |
224 |
+ ]["vartree"].dbapi._aux_cache_keys) |
225 |
+ dbs.append((vardb, "installed", True, True, db_keys)) |
226 |
+ self._filtered_trees[myroot]["dbs"] = dbs |
227 |
+ if "--usepkg" in depgraph._frozen_config.myopts: |
228 |
+ depgraph._frozen_config._trees_orig[myroot |
229 |
+ ]["bintree"].populate( |
230 |
+ "--getbinpkg" in self.myopts, |
231 |
+ "--getbinpkgonly" in self.myopts) |
232 |
+ |
233 |
class depgraph(object): |
234 |
|
235 |
pkg_tree_map = RootConfig.pkg_tree_map |
236 |
|
237 |
_dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"] |
238 |
|
239 |
- def __init__(self, settings, trees, myopts, myparams, spinner): |
240 |
- self._dynamic_config = _dynamic_depgraph_config(myparams) |
241 |
- self._frozen_config = _frozen_depgraph_config(settings, trees, \ |
242 |
- myopts, spinner, self._dynamic_config, self) |
243 |
- |
244 |
+ def __init__(self, settings, trees, myopts, myparams, spinner, |
245 |
+ frozen_config=None): |
246 |
+ if frozen_config is None: |
247 |
+ frozen_config = _frozen_depgraph_config(settings, trees, |
248 |
+ myopts, spinner) |
249 |
+ self._frozen_config = frozen_config |
250 |
+ self._dynamic_config = _dynamic_depgraph_config(self, myparams) |
251 |
+ |
252 |
self._select_atoms = self._select_atoms_highest_available |
253 |
self._select_package = self._select_pkg_highest_available |
254 |
|
255 |
@@ -1611,7 +1619,7 @@ |
256 |
added to the graph or those that are installed and have |
257 |
not been scheduled for replacement. |
258 |
""" |
259 |
- kwargs["trees"] = self._frozen_config._graph_trees |
260 |
+ kwargs["trees"] = self._dynamic_config._graph_trees |
261 |
return self._select_atoms_highest_available(*pargs, **kwargs) |
262 |
|
263 |
def _select_atoms_highest_available(self, root, depstring, |
264 |
@@ -2141,7 +2149,7 @@ |
265 |
those that are installed and have not been scheduled for |
266 |
replacement. |
267 |
""" |
268 |
- graph_db = self._frozen_config._graph_trees[root]["porttree"].dbapi |
269 |
+ graph_db = self._dynamic_config._graph_trees[root]["porttree"].dbapi |
270 |
matches = graph_db.match_pkgs(atom) |
271 |
if not matches: |
272 |
return None, None |
273 |
@@ -2249,7 +2257,7 @@ |
274 |
operation = "merge" |
275 |
if installed or onlydeps: |
276 |
operation = "nomerge" |
277 |
- pkg = self._dynamic_config._pkg_cache.get( |
278 |
+ pkg = self._frozen_config._pkg_cache.get( |
279 |
(type_name, root_config.root, cpv, operation)) |
280 |
if pkg is None and onlydeps and not installed: |
281 |
# Maybe it already got pulled in as a "merge" node. |
282 |
@@ -2268,7 +2276,7 @@ |
283 |
pkg = Package(built=(type_name != "ebuild"), cpv=cpv, |
284 |
installed=installed, metadata=metadata, |
285 |
root_config=root_config, type_name=type_name) |
286 |
- self._dynamic_config._pkg_cache[pkg] = pkg |
287 |
+ self._frozen_config._pkg_cache[pkg] = pkg |
288 |
return pkg |
289 |
|
290 |
def _validate_blockers(self): |
291 |
@@ -2370,7 +2378,7 @@ |
292 |
try: |
293 |
success, atoms = portage.dep_check(depstr, |
294 |
final_db, pkgsettings, myuse=pkg.use.enabled, |
295 |
- trees=self._frozen_config._graph_trees, myroot=myroot) |
296 |
+ trees=self._dynamic_config._graph_trees, myroot=myroot) |
297 |
except Exception, e: |
298 |
if isinstance(e, SystemExit): |
299 |
raise |
300 |
@@ -2549,7 +2557,6 @@ |
301 |
operation="uninstall", |
302 |
root_config=inst_pkg.root_config, |
303 |
type_name=inst_pkg.type_name) |
304 |
- self._dynamic_config._pkg_cache[uninst_task] = uninst_task |
305 |
# Enforce correct merge order with a hard dep. |
306 |
self._dynamic_config.digraph.addnode(uninst_task, inst_task, |
307 |
priority=BlockerDepPriority.instance) |