summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-04-10 06:08:07 +0000
committerZac Medico <zmedico@gentoo.org>2008-04-10 06:08:07 +0000
commitef5d506f68d7363dbccf3a7d94071e29460f380c (patch)
tree8dc0b40aad6452c9d5409ee9297820c8addd3ec0 /bin
parent85924d4d4464684b73bd33ce8eb310a89c66d4b6 (diff)
downloadportage-ef5d506f68d7363dbccf3a7d94071e29460f380c.tar.gz
portage-ef5d506f68d7363dbccf3a7d94071e29460f380c.tar.bz2
portage-ef5d506f68d7363dbccf3a7d94071e29460f380c.zip
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
Diffstat (limited to 'bin')
-rwxr-xr-xbin/emerge121
1 files changed, 103 insertions, 18 deletions
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):