summaryrefslogtreecommitdiff
path: root/apt/cache.py
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2009-04-15 14:16:28 +0200
committerJulian Andres Klode <jak@debian.org>2009-04-15 14:16:28 +0200
commit2b867aebe32d59b7450f3a7fb22390e0dd9f8cc7 (patch)
tree49d4d5ec7e109dfe55d51ffd2061c96ec18bd5da /apt/cache.py
parent3caa05aa8e295d338be4bfbe7fdd2e825a59d947 (diff)
downloadpython-apt-2b867aebe32d59b7450f3a7fb22390e0dd9f8cc7.tar.gz
* apt/cache.py: Use set() and WeakValueDictionary() for holding packages.
Only create Package objects when they are requested, do not keep them in a dict. Saves 10MB for 25,000 packages on my machine. The set holds the names of all packages which have at least one version, and the WeakValueDictionary() holds weak references to created Package objects. This way accessing the same package two times should return the same object, kept by the WeakValueDictionary().
Diffstat (limited to 'apt/cache.py')
-rw-r--r--apt/cache.py38
1 files changed, 23 insertions, 15 deletions
diff --git a/apt/cache.py b/apt/cache.py
index cc425ccb..d13010af 100644
--- a/apt/cache.py
+++ b/apt/cache.py
@@ -20,6 +20,7 @@
# USA
import os
+import weakref
import apt_pkg
from apt import Package
@@ -80,7 +81,8 @@ class Cache(object):
self._records = apt_pkg.GetPkgRecords(self._cache)
self._list = apt_pkg.GetPkgSourceList()
self._list.ReadMainList()
- self._dict = {}
+ self._set = set()
+ self._weakref = weakref.WeakValueDictionary()
progress.Op = "Building data structures"
i=last=0
@@ -91,7 +93,7 @@ class Cache(object):
last=i
# drop stuff with no versions (cruft)
if len(pkg.VersionList) > 0:
- self._dict[pkg.Name] = Package(self, pkg)
+ self._set.add(pkg.Name)
i += 1
@@ -100,30 +102,36 @@ class Cache(object):
def __getitem__(self, key):
""" look like a dictionary (get key) """
- return self._dict[key]
+ try:
+ return self._weakref[key]
+ except KeyError:
+ if key in self._set:
+ pkg = self._weakref[key] = Package(self, self._cache[key])
+ return pkg
+ else:
+ raise KeyError('The cache has no package named %r' % key)
def __iter__(self):
- for pkgname in self._dict.keys():
- yield self._dict[pkgname]
+ for pkgname in self._set:
+ yield self[pkgname]
raise StopIteration
def has_key(self, key):
- return (key in self._dict)
+ return (key in self._set)
def __contains__(self, key):
- return (key in self._dict)
+ return (key in self._set)
def __len__(self):
- return len(self._dict)
+ return len(self._set)
def keys(self):
- return self._dict.keys()
+ return list(self._set)
def getChanges(self):
""" Get the marked changes """
changes = []
- for name in self._dict.keys():
- p = self._dict[name]
+ for p in self:
if p.markedUpgrade or p.markedInstall or p.markedDelete or \
p.markedDowngrade or p.markedReinstall:
changes.append(p)
@@ -348,7 +356,7 @@ class FilteredCache(object):
return len(self._filtered)
def __getitem__(self, key):
- return self.cache._dict[key]
+ return self.cache[key]
def __iter__(self):
for pkgname in self._filtered:
@@ -366,10 +374,10 @@ class FilteredCache(object):
def _reapplyFilter(self):
" internal helper to refilter "
self._filtered = {}
- for pkg in self.cache._dict.keys():
+ for pkg in self.cache:
for f in self._filters:
- if f.apply(self.cache._dict[pkg]):
- self._filtered[pkg] = 1
+ if f.apply(pkg):
+ self._filtered[pkg.name] = 1
break
def setFilter(self, filter):