diff options
| author | Julian Andres Klode <jak@debian.org> | 2015-06-10 22:08:29 +0200 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2015-06-10 22:08:29 +0200 |
| commit | 423b06d1a600f3bf8e54817cd087e152e9574b7b (patch) | |
| tree | 57d266f28947afaf9dfbb2691b4581b6fb2f5e76 | |
| parent | 96a2eddb562e361d0fa811dc7dd7d01c80220cf4 (diff) | |
| download | python-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.py | 67 |
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 """ |
