summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2015-06-10 22:08:29 +0200
committerJulian Andres Klode <jak@debian.org>2015-06-10 22:08:29 +0200
commit423b06d1a600f3bf8e54817cd087e152e9574b7b (patch)
tree57d266f28947afaf9dfbb2691b4581b6fb2f5e76
parent96a2eddb562e361d0fa811dc7dd7d01c80220cf4 (diff)
downloadpython-apt-423b06d1a600f3bf8e54817cd087e152e9574b7b.tar.gz
apt/cache.py: Support :all and other special architecture specifies
Remove the _set and _fullnameset that previously stored the names of all packages in the cache. Checking if a package is now a matter of checking whether it is in the low-level cache and has versions (that is, is real). Still keep the _sorted_set around and make keys() manage it, and change everyone using _sorted_set for iteration to use keys().
-rw-r--r--apt/cache.py67
1 files changed, 34 insertions, 33 deletions
diff --git a/apt/cache.py b/apt/cache.py
index c8615caf..e716d9e6 100644
--- a/apt/cache.py
+++ b/apt/cache.py
@@ -27,7 +27,6 @@ import weakref
import apt_pkg
from apt import Package
-from apt_pkg import gettext as _
import apt.progress.text
@@ -73,8 +72,6 @@ class Cache(object):
self._list = None
self._callbacks = {}
self._weakref = weakref.WeakValueDictionary()
- self._set = set()
- self._fullnameset = set()
self._changes_count = -1
self._sorted_set = None
@@ -156,28 +153,11 @@ class Cache(object):
self._records = apt_pkg.PackageRecords(self._cache)
self._list = apt_pkg.SourceList()
self._list.read_main_list()
- self._set.clear()
- self._fullnameset.clear()
self._sorted_set = None
self._weakref.clear()
self._have_multi_arch = len(apt_pkg.get_architectures()) > 1
- progress.op = _("Building data structures")
- i = last = 0
- size = len(self._cache.packages)
- for pkg in self._cache.packages:
- if progress is not None and last + 100 < i:
- progress.update(i / float(size) * 100)
- last = i
- # drop stuff with no versions (cruft)
- if pkg.has_versions:
- self._set.add(pkg.get_fullname(pretty=True))
- if self._have_multi_arch:
- self._fullnameset.add(pkg.get_fullname(pretty=False))
-
- i += 1
-
progress.done()
self._run_callbacks("cache_post_open")
@@ -200,37 +180,58 @@ class Cache(object):
try:
return self._weakref[key]
except KeyError:
- if key in self._set or key in self._fullnameset:
- key = str(key)
- pkg = self._weakref[key] = Package(self, self._cache[key])
- return pkg
- else:
+ key = str(key)
+ try:
+ rawpkg = self._cache[key]
+ except KeyError:
raise KeyError('The cache has no package named %r' % key)
+ # It might be excluded due to not having a version or something
+ if not self.__is_real_pkg(rawpkg):
+ raise KeyError('The cache has no package named %r' % key)
+
+ # Check if we already know the package using the normalized name
+ name = rawpkg.get_fullname(pretty=False)
+ try:
+ return self._weakref[name]
+ except KeyError:
+ pkg = Package(self, rawpkg)
+ self._weakref[key] = self._weakref[name] = pkg
+
+ return pkg
+
def __iter__(self):
# We iterate sorted over package names here. With this we read the
# package lists linearly if we need to access the package records,
# instead of having to do thousands of random seeks; the latter
# is disastrous if we use compressed package indexes, and slower than
# necessary for uncompressed indexes.
- if self._sorted_set is None:
- self._sorted_set = sorted(self._set)
-
- for pkgname in self._sorted_set:
+ for pkgname in self.keys():
yield self[pkgname]
raise StopIteration
+ def __is_real_pkg(self, rawpkg):
+ """Check if the apt_pkg.Package provided is a real package."""
+ return rawpkg.has_versions
+
def has_key(self, key):
- return (key in self._set or key in self._fullnameset)
+ return key in self
def __contains__(self, key):
- return (key in self._set or key in self._fullnameset)
+ try:
+ return self.__is_real_pkg(self._cache[key])
+ except KeyError:
+ return False
def __len__(self):
- return len(self._set)
+ return len(self.keys())
def keys(self):
- return list(self._set)
+ if self._sorted_set is None:
+ self._sorted_set = sorted(p.get_fullname(pretty=True)
+ for p in self._cache.packages
+ if self.__is_real_pkg(p))
+ return list(self._sorted_set) # We need a copy here, caller may modify
def get_changes(self):
""" Get the marked changes """