blob: 557855a52135de1b8633a79cd5f46161efb7eb55 [file] [log] [blame]
# 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_"]