From 04066d484cf68bda8de37c037aad003a44088e8a Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 25 Jun 2008 22:36:19 +0000 Subject: Add a generic portage.cache.mappings.slot_dict_class() function which generates mapping classes that behave similar to a dict but store values as object attributes that are allocated via __slots__. Instances of these objects have a smaller memory footprint than a normal dict object. These classes are used to reduce the memory footprint of the dbapi.aux_get() caches and the Package.metadata attribute. svn path=/main/trunk/; revision=10790 --- pym/_emerge/__init__.py | 101 +++++++----------------------------------------- 1 file changed, 13 insertions(+), 88 deletions(-) (limited to 'pym/_emerge/__init__.py') diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 2f54b6b65..ca76400a3 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -1371,108 +1371,33 @@ class Package(Task): return True return False -class _PackageMetadataWrapper(object): +_all_metadata_keys = set(x for x in portage.auxdbkeys \ + if not x.startswith("UNUSED_")) +_all_metadata_keys.discard("CDEPEND") +_all_metadata_keys.update(Package.metadata_keys) + +from portage.cache.mappings import slot_dict_class +_PackageMetadataWrapperBase = slot_dict_class(_all_metadata_keys) + +class _PackageMetadataWrapper(_PackageMetadataWrapperBase): """ Detect metadata updates and synchronize Package attributes. """ - _keys = set(x for x in portage.auxdbkeys \ - if not x.startswith("UNUSED_")) - _keys.discard("CDEPEND") - _keys.update(Package.metadata_keys) - _keys = tuple(sorted(_keys)) - __slots__ = ("__weakref__", "_pkg") + tuple("_val_" + k for k in _keys) + + __slots__ = ("_pkg",) _wrapped_keys = frozenset( ["COUNTER", "INHERITED", "IUSE", "SLOT", "USE", "_mtime_"]) def __init__(self, pkg, metadata): + _PackageMetadataWrapperBase.__init__(self) self._pkg = pkg self.update(metadata) - def __iter__(self): - for k, v in self.iteritems(): - yield k - - def __len__(self): - l = 0 - for i in self.iteritems(): - l += 1 - return l - - def keys(self): - return list(self) - - def iteritems(self): - for k in self._keys: - try: - yield (k, getattr(self, "_val_" + k)) - except AttributeError: - pass - - def items(self): - return list(self.iteritems()) - - def itervalues(self): - for k, v in self.itervalues(): - yield v - - def values(self): - return list(self.itervalues()) - - def __delitem__(self, k): - try: - delattr(self, "_val_" + k) - except AttributeError: - raise KeyError(k) - def __setitem__(self, k, v): - setattr(self, "_val_" + k, v) + _PackageMetadataWrapperBase.__setitem__(self, k, v) if k in self._wrapped_keys: getattr(self, "_set_" + k.lower())(k, v) - def update(self, d): - i = getattr(d, "iteritems", None) - if i is None: - i = d - else: - i = i() - for k, v in i: - self[k] = v - - def __getitem__(self, k): - try: - return getattr(self, "_val_" + k) - except AttributeError: - raise KeyError(k) - - def get(self, key, default=None): - try: - return self[key] - except KeyError: - return default - - def __contains__(self, k): - return hasattr(self, "_val_" + k) - - def pop(self, key, *args): - if len(args) > 1: - raise TypeError("pop expected at most 2 arguments, got " + \ - repr(1 + len(args))) - try: - value = self[key] - except KeyError: - if args: - return args[0] - raise - del self[key] - return value - - def clear(self): - for k in self._keys: - try: - delattr(self, "_val_" + k) - except AttributError: - pass - def _set_inherited(self, k, v): if isinstance(v, basestring): v = frozenset(v.split()) -- cgit v1.2.3-1-g7c22