summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2006-02-26 13:10:43 +0000
committerZac Medico <zmedico@gentoo.org>2006-02-26 13:10:43 +0000
commit8edf2787fca77df7e17e25267f0e18d81667bedd (patch)
tree8b1a69220ba970ae89ab09079e2643528705ddf1 /pym
parentaa977dab57512ba535e71066de5bf206fbbafae9 (diff)
downloadportage-8edf2787fca77df7e17e25267f0e18d81667bedd.tar.gz
portage-8edf2787fca77df7e17e25267f0e18d81667bedd.tar.bz2
portage-8edf2787fca77df7e17e25267f0e18d81667bedd.zip
Add a new cache.metadata_overlay module that layers a writable cache over a readonly cache.
svn path=/main/trunk/; revision=2792
Diffstat (limited to 'pym')
-rw-r--r--pym/cache/metadata_overlay.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/pym/cache/metadata_overlay.py b/pym/cache/metadata_overlay.py
new file mode 100644
index 000000000..557855a52
--- /dev/null
+++ b/pym/cache/metadata_overlay.py
@@ -0,0 +1,91 @@
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+import time
+if not hasattr(__builtins__, "set"):
+ from sets import Set as set
+import template
+from flat_hash import database as db_rw
+from metadata import database as db_ro
+
+class database(template.database):
+
+ autocommits = True
+ serialize_eclasses = False
+
+ def __init__(self, location, label, auxdbkeys, **config):
+ super(database, self).__init__(location, label, auxdbkeys)
+ self.db_rw = db_rw(location, label, auxdbkeys, **config)
+ self.db_ro = db_ro(label,"metadata/cache",auxdbkeys)
+
+ def __getitem__(self, cpv):
+ """funnel whiteout validation through here, since value needs to be fetched"""
+ try:
+ value = self.db_rw[cpv]
+ except KeyError:
+ return self.db_ro[cpv] # raises a KeyError when necessary
+ if self._is_whiteout(value):
+ if self._is_whiteout_valid(cpv, value):
+ raise KeyError(cpv)
+ else:
+ del self.db_rw[cpv]
+ return self.db_ro[cpv] # raises a KeyError when necessary
+ else:
+ return value
+
+ def _setitem(self, name, values):
+ try:
+ value_ro = self.db_ro[name]
+ if self._are_values_identical(value_ro,values):
+ # we have matching values in the underlying db_ro
+ # so it is unnecessary to store data in db_rw
+ try:
+ del self.db_rw[name] # delete unwanted whiteout when necessary
+ except KeyError:
+ pass
+ except KeyError:
+ self.db_rw[name] = values
+
+ def _delitem(self, cpv):
+ value = self[cpv] # validates whiteout and/or raises a KeyError when necessary
+ if self.db_ro.has_key(cpv):
+ self.db_rw[cpv] = self._create_whiteout(value)
+ else:
+ del self.db_rw[cpv]
+
+ def has_key(self, cpv):
+ try:
+ self[cpv] # validates whiteout when necessary
+ except KeyError:
+ return False
+ return True
+
+ def iterkeys(self):
+ s = set()
+ for cpv in self.db_rw.iterkeys():
+ if self.has_key(cpv): # validates whiteout when necessary
+ yield cpv
+ # set includes whiteouts so they won't be yielded later
+ s.add(cpv)
+ for cpv in self.db_ro.iterkeys():
+ if cpv not in s:
+ yield cpv
+
+ def _is_whiteout(self, value):
+ return value["EAPI"] == "whiteout"
+
+ def _create_whiteout(self, value):
+ return {"EAPI":"whiteout","_eclasses_":value["_eclasses_"],"_mtime_":value["_mtime_"]}
+
+ def _is_whiteout_valid(self, name, value_rw):
+ try:
+ value_ro = self.db_ro[name]
+ return self._are_values_identical(value_rw,value_ro)
+ except KeyError:
+ return False
+
+ def _are_values_identical(self, value1, value2):
+ if long(value1["_mtime_"]) != long(value2["_mtime_"]):
+ return False
+ return value1["_eclasses_"] == value2["_eclasses_"]