From: Zac Medico Date: Thu, 10 Apr 2008 06:08:07 +0000 (-0000) Subject: Replace the fakedbapi class that is used to track depgraph state with a X-Git-Tag: v2.1.5~215 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=ef5d506f68d7363dbccf3a7d94071e29460f380c;p=portage.git Replace the fakedbapi class that is used to track depgraph state with a similar PackageVirtualDbapi class that uses Package instances internally. This eliminates some redundancy since the Package instances can be reused elsewhere, unlike the internal data structures used by fakedbapi. (trunk r9786) svn path=/main/branches/2.1.2/; revision=9790 --- diff --git a/bin/emerge b/bin/emerge index e038ab61f..10912b245 100755 --- a/bin/emerge +++ b/bin/emerge @@ -1587,6 +1587,85 @@ class DepcheckCompositeDB(object): metadata = self._cpv_pkg_map[cpv].metadata return [metadata.get(x, "") for x in wants] +class PackageVirtualDbapi(portage.dbapi): + """ + A dbapi-like interface class that represents the state of the installed + package database as new packages are installed, replacing any packages + that previously existed in the same slot. The main difference between + this class and fakedbapi is that this one uses Package instances + internally (passed in via cpv_inject() and cpv_remove() calls). + """ + def __init__(self, settings): + portage.dbapi.__init__(self) + self.settings = settings + self._match_cache = {} + self._cp_map = {} + self._cpv_map = {} + + def _clear_cache(self): + if self._categories is not None: + self._categories = None + if self._match_cache: + self._match_cache = {} + + def match(self, origdep, use_cache=1): + result = self._match_cache.get(origdep) + if result is not None: + return result[:] + result = portage.dbapi.match(self, origdep, use_cache=use_cache) + self._match_cache[origdep] = result + return result[:] + + def cpv_exists(self, cpv): + return cpv in self._cpv_map + + def cp_list(self, mycp, use_cache=1): + cachelist = self._match_cache.get(mycp) + # cp_list() doesn't expand old-style virtuals + if cachelist and cachelist[0].startswith(mycp): + return cachelist[:] + cpv_list = self._cp_map.get(mycp) + if cpv_list is None: + cpv_list = [] + else: + cpv_list = [pkg.cpv for pkg in cpv_list] + self._cpv_sort_ascending(cpv_list) + if not (not cpv_list and mycp.startswith("virtual/")): + self._match_cache[mycp] = cpv_list + return cpv_list[:] + + def cp_all(self): + return list(self._cp_map) + + def cpv_all(self): + return list(self._cpv_map) + + def cpv_inject(self, pkg): + cp_list = self._cp_map.get(pkg.cp) + if cp_list is None: + cp_list = [] + self._cp_map[pkg.cp] = cp_list + for e_pkg in cp_list: + if e_pkg.slot_atom == pkg.slot_atom: + if e_pkg == pkg: + return + self.cpv_remove(e_pkg) + cp_list.append(pkg) + self._cpv_map[pkg.cpv] = pkg + self._clear_cache() + + def cpv_remove(self, pkg): + old_pkg = self._cpv_map.get(pkg.cpv) + if old_pkg != pkg: + raise KeyError(pkg) + self._cp_map[pkg.cp].remove(pkg) + del self._cpv_map[pkg.cpv] + self._clear_cache() + + def aux_get(self, cpv, wants): + metadata = self._cpv_map[cpv].metadata + return [metadata.get(x, "") for x in wants] + class depgraph(object): pkg_tree_map = { @@ -1625,6 +1704,8 @@ class depgraph(object): # Contains installed packages and new packages that have been added # to the graph. self._graph_trees = {} + # All Package instances + self._pkg_cache = {} for myroot in trees: self.trees[myroot] = {} for tree in ("porttree", "bintree"): @@ -1641,19 +1722,22 @@ class depgraph(object): # the FakeVartree instead of the real one. self.roots[myroot] = RootConfig(self.trees[myroot], trees[myroot]["root_config"].setconfig) + preload_installed_pkgs = "--nodeps" not in self.myopts and \ + "--buildpkgonly" not in self.myopts # This fakedbapi instance will model the state that the vdb will # have after new packages have been installed. - fakedb = portage.fakedbapi(settings=self.pkgsettings[myroot]) - self.mydbapi[myroot] = fakedb - if "--nodeps" not in self.myopts and \ - "--buildpkgonly" not in self.myopts: - # --nodeps bypasses this, since it isn't needed in this case - # and the cache pulls might trigger (slow) cache generation. - for pkg in vardb.cpv_all(): + fakedb = PackageVirtualDbapi(vardb.settings) + if preload_installed_pkgs: + for cpv in vardb.cpv_all(): self.spinner.update() - fakedb.cpv_inject(pkg, - metadata=dict(izip(self._mydbapi_keys, - vardb.aux_get(pkg, self._mydbapi_keys)))) + metadata = dict(izip(self._mydbapi_keys, + vardb.aux_get(cpv, self._mydbapi_keys))) + pkg = Package(built=True, cpv=cpv, + installed=True, metadata=metadata, + root=myroot, type_name="installed") + self._pkg_cache[pkg] = pkg + fakedb.cpv_inject(pkg) + self.mydbapi[myroot] = fakedb def graph_tree(): pass graph_tree.dbapi = fakedb @@ -1718,8 +1802,6 @@ class depgraph(object): self._select_package = self._select_pkg_highest_available self._highest_pkg_cache = {} self._installed_pkg_cache = {} - # All Package instances - self._pkg_cache = {} def _show_slot_collision_notice(self): """Show an informational message advising the user to mask one of the @@ -1989,9 +2071,8 @@ class depgraph(object): # function despite collisions. pass else: - self.mydbapi[pkg.root].cpv_inject( - pkg.cpv, metadata=pkg.metadata) self._slot_pkg_map[pkg.root][pkg.slot_atom] = pkg + self.mydbapi[pkg.root].cpv_inject(pkg) self.digraph.addnode(pkg, myparent, priority=priority) @@ -4408,12 +4489,16 @@ class depgraph(object): except KeyError: # It does no exist or it is corrupt. raise portage_exception.PackageNotFound(pkg_key) - fakedb[myroot].cpv_inject(pkg_key, metadata=metadata) if pkg_type == "ebuild": pkgsettings = self.pkgsettings[myroot] - pkgsettings.setcpv(pkg_key, mydb=fakedb[myroot]) - fakedb[myroot].aux_update(pkg_key, - {"USE":pkgsettings["PORTAGE_USE"]}) + pkgsettings.setcpv(pkg_key, mydb=metadata) + metadata["USE"] = pkgsettings["PORTAGE_USE"] + installed = False + built = pkg_type != "ebuild" + pkg = Package(built=built, cpv=pkg_key, installed=installed, + metadata=metadata, root=myroot, type_name=pkg_type) + self._pkg_cache[pkg] = pkg + fakedb[myroot].cpv_inject(pkg) self.spinner.update() class RepoDisplay(object):