Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r10781 - in main/branches/prefix/pym: _emerge portage portage/dbapi
Date: Wed, 25 Jun 2008 09:00:30
Message-Id: E1KBQrY-0004Tq-Dd@stork.gentoo.org
1 Author: grobian
2 Date: 2008-06-25 09:00:23 +0000 (Wed, 25 Jun 2008)
3 New Revision: 10781
4
5 Modified:
6 main/branches/prefix/pym/_emerge/__init__.py
7 main/branches/prefix/pym/portage/__init__.py
8 main/branches/prefix/pym/portage/dbapi/vartree.py
9 main/branches/prefix/pym/portage/dep.py
10 Log:
11 Merged from trunk 10770:10780
12
13 | 10771 | Bug #229233 - Fix Atom -> str breakage in the |
14 | zmedico | depgraph.display_problems() package.provided warning |
15 | | message. |
16
17 | 10772 | Use weakref.WeakValueDictionary to make cached Atom |
18 | zmedico | instances eligible for garbage collection when no strong |
19 | | references remain. |
20
21 | 10773 | If dep calculation time exceeds 20 seconds then |
22 | zmedico | automatically enable "complete" mode since any performance |
23 | | difference is not as likely to be noticed by the user after |
24 | | this much time has passed. |
25
26 | 10774 | Fix spelling of depgraph._complete_threshold. |
27 | zmedico | |
28
29 | 10775 | Bug #229069 - Before deleting the depgraph, break references |
30 | zmedico | pointing to the depgraph from Package instances in the merge |
31 | | list. This helps reduce the heap size a lot. |
32
33 | 10776 | For the Package.metadata attribute, only implement the dict |
34 | zmedico | interface instead of actually inheriting from dict. This |
35 | | slightly decreases the memory footprint by defining |
36 | | __slots__ and storing items as object attributes. |
37
38 | 10777 | Remove the BlockerDB._blocker_cache attribute and just |
39 | zmedico | create new instances on demand instead of taking space on |
40 | | the heap. |
41
42 | 10778 | Make clear_caches() call portage.dircache.clear(). |
43 | zmedico | |
44
45 | 10779 | Use os.listdir() instead of portage.listdir() to avoid |
46 | zmedico | needless caching of directories that only need to be listed |
47 | | once. |
48
49 | 10780 | Implement __contains__, pop() and clear() for |
50 | zmedico | Package.metadata attributes. |
51
52
53 Modified: main/branches/prefix/pym/_emerge/__init__.py
54 ===================================================================
55 --- main/branches/prefix/pym/_emerge/__init__.py 2008-06-25 08:42:02 UTC (rev 10780)
56 +++ main/branches/prefix/pym/_emerge/__init__.py 2008-06-25 09:00:23 UTC (rev 10781)
57 @@ -1312,7 +1312,7 @@
58 def __init__(self, **kwargs):
59 Task.__init__(self, **kwargs)
60 self.root = self.root_config.root
61 - self.metadata = self._metadata_wrapper(self, self.metadata)
62 + self.metadata = _PackageMetadataWrapper(self, self.metadata)
63 self.cp = portage.cpv_getkey(self.cpv)
64 self.slot_atom = portage.dep.Atom("%s:%s" % (self.cp, self.slot))
65 self.category, self.pf = portage.catsplit(self.cpv)
66 @@ -1359,60 +1359,6 @@
67 chain((re.escape(x) for x in all), iuse_implicit)))
68 return object.__getattribute__(self, name)
69
70 - class _metadata_wrapper(dict):
71 - """
72 - Detect metadata updates and synchronize Package attributes.
73 - """
74 - _wrapped_keys = frozenset(
75 - ["COUNTER", "INHERITED", "IUSE", "SLOT", "USE", "_mtime_"])
76 -
77 - def __init__(self, pkg, metadata):
78 - dict.__init__(self)
79 - self._pkg = pkg
80 - i = getattr(metadata, "iteritems", None)
81 - if i is None:
82 - i = metadata
83 - else:
84 - i = i()
85 - for k, v in i:
86 - self[k] = v
87 -
88 - def __setitem__(self, k, v):
89 - dict.__setitem__(self, k, v)
90 - if k in self._wrapped_keys:
91 - getattr(self, "_set_" + k.lower())(k, v)
92 -
93 - def _set_inherited(self, k, v):
94 - if isinstance(v, basestring):
95 - v = frozenset(v.split())
96 - self._pkg.inherited = v
97 -
98 - def _set_iuse(self, k, v):
99 - self._pkg.iuse = self._pkg._iuse(
100 - v.split(), self._pkg.root_config.iuse_implicit)
101 -
102 - def _set_slot(self, k, v):
103 - self._pkg.slot = v
104 -
105 - def _set_use(self, k, v):
106 - self._pkg.use = self._pkg._use(v.split())
107 -
108 - def _set_counter(self, k, v):
109 - if isinstance(v, basestring):
110 - try:
111 - v = int(v.strip())
112 - except ValueError:
113 - v = 0
114 - self._pkg.counter = v
115 -
116 - def _set__mtime_(self, k, v):
117 - if isinstance(v, basestring):
118 - try:
119 - v = float(v.strip())
120 - except ValueError:
121 - v = 0
122 - self._pkg.mtime = v
123 -
124 def _get_hash_key(self):
125 hash_key = getattr(self, "_hash_key", None)
126 if hash_key is None:
127 @@ -1452,6 +1398,135 @@
128 return True
129 return False
130
131 +class _PackageMetadataWrapper(object):
132 + """
133 + Detect metadata updates and synchronize Package attributes.
134 + """
135 + _keys = Package.metadata_keys
136 + __slots__ = ("__weakref__", "_pkg") + tuple("_val_" + k for k in _keys)
137 + _wrapped_keys = frozenset(
138 + ["COUNTER", "INHERITED", "IUSE", "SLOT", "USE", "_mtime_"])
139 +
140 + def __init__(self, pkg, metadata):
141 + self._pkg = pkg
142 + self.update(metadata)
143 +
144 + def __iter__(self):
145 + for k, v in self.iteritems():
146 + yield k
147 +
148 + def __len__(self):
149 + l = 0
150 + for i in self.iteritems():
151 + l += 1
152 + return l
153 +
154 + def keys(self):
155 + return list(self)
156 +
157 + def iteritems(self):
158 + for k in self._keys:
159 + try:
160 + yield (k, getattr(self, "_val_" + k))
161 + except AttributeError:
162 + pass
163 +
164 + def items(self):
165 + return list(self.iteritems())
166 +
167 + def itervalues(self):
168 + for k, v in self.itervalues():
169 + yield v
170 +
171 + def values(self):
172 + return list(self.itervalues())
173 +
174 + def __delitem__(self, k):
175 + try:
176 + delattr(self, "_val_" + k)
177 + except AttributeError:
178 + raise KeyError(k)
179 +
180 + def __setitem__(self, k, v):
181 + setattr(self, "_val_" + k, v)
182 + if k in self._wrapped_keys:
183 + getattr(self, "_set_" + k.lower())(k, v)
184 +
185 + def update(self, d):
186 + i = getattr(d, "iteritems", None)
187 + if i is None:
188 + i = d
189 + else:
190 + i = i()
191 + for k, v in i:
192 + self[k] = v
193 +
194 + def __getitem__(self, k):
195 + try:
196 + return getattr(self, "_val_" + k)
197 + except AttributeError:
198 + raise KeyError(k)
199 +
200 + def get(self, key, default=None):
201 + try:
202 + return self[key]
203 + except KeyError:
204 + return default
205 +
206 + def __contains__(self, k):
207 + return hasattr(self, "_val_" + k)
208 +
209 + def pop(self, key, *args):
210 + if len(args) > 1:
211 + raise TypeError("pop expected at most 2 arguments, got " + \
212 + repr(1 + len(args)))
213 + try:
214 + value = self[key]
215 + except KeyError:
216 + if args:
217 + return args[0]
218 + raise
219 + del self[key]
220 + return value
221 +
222 + def clear(self):
223 + for k in self._keys:
224 + try:
225 + delattr(self, "_val_" + k)
226 + except AttributError:
227 + pass
228 +
229 + def _set_inherited(self, k, v):
230 + if isinstance(v, basestring):
231 + v = frozenset(v.split())
232 + self._pkg.inherited = v
233 +
234 + def _set_iuse(self, k, v):
235 + self._pkg.iuse = self._pkg._iuse(
236 + v.split(), self._pkg.root_config.iuse_implicit)
237 +
238 + def _set_slot(self, k, v):
239 + self._pkg.slot = v
240 +
241 + def _set_use(self, k, v):
242 + self._pkg.use = self._pkg._use(v.split())
243 +
244 + def _set_counter(self, k, v):
245 + if isinstance(v, basestring):
246 + try:
247 + v = int(v.strip())
248 + except ValueError:
249 + v = 0
250 + self._pkg.counter = v
251 +
252 + def _set__mtime_(self, k, v):
253 + if isinstance(v, basestring):
254 + try:
255 + v = float(v.strip())
256 + except ValueError:
257 + v = 0
258 + self._pkg.mtime = v
259 +
260 class DependencyArg(object):
261 def __init__(self, arg=None, root_config=None):
262 self.arg = arg
263 @@ -1657,15 +1732,14 @@
264 self._root_config = root_config
265 self._vartree = root_config.trees["vartree"]
266 self._portdb = root_config.trees["porttree"].dbapi
267 - self._blocker_cache = \
268 - BlockerCache(self._vartree.root, self._vartree.dbapi)
269 +
270 self._dep_check_trees = { self._vartree.root : {
271 "porttree" : self._vartree,
272 "vartree" : self._vartree,
273 }}
274
275 def findInstalledBlockers(self, new_pkg, acquire_lock=0):
276 - blocker_cache = self._blocker_cache
277 + blocker_cache = BlockerCache(self._vartree.root, self._vartree.dbapi)
278 dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
279 dep_check_trees = self._dep_check_trees
280 settings = self._vartree.settings
281 @@ -1714,7 +1788,7 @@
282 blocker_parents = digraph()
283 blocker_atoms = []
284 for pkg in installed_pkgs:
285 - for blocker_atom in self._blocker_cache[pkg.cpv].atoms:
286 + for blocker_atom in blocker_cache[pkg.cpv].atoms:
287 blocker_atom = blocker_atom[1:]
288 blocker_atoms.append(blocker_atom)
289 blocker_parents.add(blocker_atom, pkg)
290 @@ -1801,6 +1875,15 @@
291 self._cp_map = {}
292 self._cpv_map = {}
293
294 + def clear(self):
295 + """
296 + Remove all packages.
297 + """
298 + if self._cpv_map:
299 + self._clear_cache()
300 + self._cp_map.clear()
301 + self._cpv_map.clear()
302 +
303 def copy(self):
304 obj = PackageVirtualDbapi(self.settings)
305 obj._match_cache = self._match_cache.copy()
306 @@ -1908,7 +1991,14 @@
307
308 _dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
309
310 + # If dep calculation time exceeds this value then automatically
311 + # enable "complete" mode since any performance difference is
312 + # not as likely to be noticed by the user after this much time
313 + # has passed.
314 + _complete_threshold = 20
315 +
316 def __init__(self, settings, trees, myopts, myparams, spinner):
317 + self._creation_time = time.time()
318 self.settings = settings
319 self.target_root = settings["ROOT"]
320 self.myopts = myopts
321 @@ -3409,16 +3499,20 @@
322 intially satisfied.
323
324 Since this method can consume enough time to disturb users, it is
325 - currently only enabled by the --complete-graph option.
326 + currently only enabled by the --complete-graph option, or when
327 + dep calculation time exceeds self._complete_threshold.
328 """
329 - if "complete" not in self.myparams:
330 - # Skip this to avoid consuming enough time to disturb users.
331 - return 1
332 -
333 if "--buildpkgonly" in self.myopts or \
334 "recurse" not in self.myparams:
335 return 1
336
337 + if "complete" not in self.myparams:
338 + if time.time() - self._creation_time > self._complete_threshold:
339 + self.myparams.add("complete")
340 + else:
341 + # Skip this to avoid consuming enough time to disturb users.
342 + return 1
343 +
344 # Put the depgraph into a mode that causes it to only
345 # select packages that have already been added to the
346 # graph or those that are installed and have not been
347 @@ -3860,6 +3954,29 @@
348 retlist.reverse()
349 return retlist
350
351 + def break_refs(self, mergelist):
352 + """
353 + Take a mergelist like that returned from self.altlist() and
354 + break any references that lead back to the depgraph. This is
355 + useful if you want to hold references to packages without
356 + also holding the depgraph on the heap.
357 + """
358 + for node in mergelist:
359 + if not isinstance(node, Package):
360 + continue
361 +
362 + # The visible packages cache has fullfilled it's purpose
363 + # and it's no longer needed, so free the memory.
364 + node.root_config.visible_pkgs.clear()
365 +
366 + if isinstance(node.root_config.trees["vartree"], FakeVartree):
367 + # The FakeVartree references the _package_cache which
368 + # references the depgraph. So that Package instances don't
369 + # hold the depgraph and FakeVartree on the heap, replace
370 + # the FakeVartree reference with the real vartree.
371 + node.root_config.trees["vartree"] = \
372 + self._trees_orig[node.root]["vartree"]
373 +
374 def _resolve_conflicts(self):
375 if not self._complete_graph():
376 raise self._unknown_internal_error()
377 @@ -5249,7 +5366,7 @@
378 refs.sort()
379 ref_string = ", ".join(["'%s'" % name for name in refs])
380 ref_string = " pulled in by " + ref_string
381 - msg.append(" %s%s\n" % (colorize("INFORM", arg), ref_string))
382 + msg.append(" %s%s\n" % (colorize("INFORM", str(arg)), ref_string))
383 msg.append("\n")
384 if "world" in problems_sets:
385 msg.append("This problem can be solved in one of the following ways:\n\n")
386 @@ -8829,6 +8946,7 @@
387 mtimedb.filename = None
388 time.sleep(3) # allow the parent to have first fetch
389 mymergelist = mydepgraph.altlist()
390 + mydepgraph.break_refs(mymergelist)
391 del mydepgraph
392 clear_caches(trees)
393
394 @@ -8872,6 +8990,7 @@
395
396 pkglist = mydepgraph.altlist()
397 mydepgraph.saveNomergeFavorites()
398 + mydepgraph.break_refs(pkglist)
399 del mydepgraph
400 clear_caches(trees)
401
402 @@ -9004,6 +9123,7 @@
403 d["porttree"].dbapi._aux_cache.clear()
404 d["bintree"].dbapi._aux_cache.clear()
405 d["bintree"].dbapi._clear_cache()
406 + portage.dircache.clear()
407 gc.collect()
408
409 def load_emerge_config(trees=None):
410
411 Modified: main/branches/prefix/pym/portage/__init__.py
412 ===================================================================
413 --- main/branches/prefix/pym/portage/__init__.py 2008-06-25 08:42:02 UTC (rev 10780)
414 +++ main/branches/prefix/pym/portage/__init__.py 2008-06-25 09:00:23 UTC (rev 10781)
415 @@ -1956,7 +1956,7 @@
416 pkginternaluse = ""
417 iuse = ""
418 if mydb:
419 - if isinstance(mydb, dict):
420 + if not hasattr(mydb, "aux_get"):
421 slot = mydb["SLOT"]
422 iuse = mydb["IUSE"]
423 else:
424 @@ -2434,7 +2434,7 @@
425 if len(self.virtuals) == 0:
426 self.getvirtuals()
427 # Grab the virtuals this package provides and add them into the tree virtuals.
428 - if isinstance(mydbapi, dict):
429 + if not hasattr(mydbapi, "aux_get"):
430 provides = mydbapi["PROVIDE"]
431 else:
432 provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
433 @@ -2443,7 +2443,7 @@
434 if isinstance(mydbapi, portdbapi):
435 self.setcpv(mycpv, mydb=mydbapi)
436 myuse = self["PORTAGE_USE"]
437 - elif isinstance(mydbapi, dict):
438 + elif not hasattr(mydbapi, "aux_get"):
439 myuse = mydbapi["USE"]
440 else:
441 myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
442
443 Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
444 ===================================================================
445 --- main/branches/prefix/pym/portage/dbapi/vartree.py 2008-06-25 08:42:02 UTC (rev 10780)
446 +++ main/branches/prefix/pym/portage/dbapi/vartree.py 2008-06-25 09:00:23 UTC (rev 10781)
447 @@ -1630,7 +1630,7 @@
448 # name of the dir; the package may have been moved.
449 myebuildpath = None
450 ebuild_phase = "prerm"
451 - mystuff = listdir(self.dbdir, EmptyOnError=1)
452 + mystuff = os.listdir(self.dbdir)
453 for x in mystuff:
454 if x.endswith(".ebuild"):
455 myebuildpath = os.path.join(self.dbdir, self.pkg + ".ebuild")
456 @@ -2665,7 +2665,7 @@
457 return a
458
459 # copy "info" files (like SLOT, CFLAGS, etc.) into the database
460 - for x in listdir(inforoot):
461 + for x in os.listdir(inforoot):
462 self.copyfile(inforoot+"/"+x)
463
464 # write local package counter for recording
465
466 Modified: main/branches/prefix/pym/portage/dep.py
467 ===================================================================
468 --- main/branches/prefix/pym/portage/dep.py 2008-06-25 08:42:02 UTC (rev 10780)
469 +++ main/branches/prefix/pym/portage/dep.py 2008-06-25 09:00:23 UTC (rev 10781)
470 @@ -19,6 +19,7 @@
471 #
472
473 import re, sys, types
474 +import weakref
475 from itertools import chain
476 import portage.exception
477 from portage.exception import InvalidData, InvalidAtom
478 @@ -412,7 +413,7 @@
479 """
480
481 __metaclass__ = _AtomCache
482 - _atoms = {}
483 + _atoms = weakref.WeakValueDictionary()
484
485 _str_methods = ("endswith", "find", "index", "lstrip", "replace",
486 "startswith", "strip", "rindex", "rfind", "rstrip", "__getitem__",
487
488 --
489 gentoo-commits@l.g.o mailing list