# $Id: cache.py 2062 2006-05-03 05:40:30Z dairiki $
# cache.py - cache API and implementation for Myghty
# Copyright (C) 2004, 2005 Michael Bayer mike_mp@zzzcomputing.com
#
# This module is part of Myghty and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
#
#
from myghty.container import *
from myghty.util import *
import myghty.buffer
import re
class Cache:
"""a front-end to the containment API implementing a data cache.
This is a per-request object and is not synchronized against other threads
or processes. (the containment API it talks to, is)."""
def __init__(self, component, type = None, container_class = None , debug_file = None, **params):
self.params = CacheArgs()
self.params.set_params(**params)
self.type = type
if component is not None:
self.namespace = component.id
else:
self.namespace = None
self.dict = {}
# attach a ContainerContext to the component, which will hold
# onto the namespacemanager(s) corresponding to that component.
# the scope of the context is the same as that of the component,
# so if a component is unused and gets garbage collected, its
# namespacemanagers will get collected as well.
if component is not None:
if hasattr(component, "_container_context"):
self.context = component._container_context
else:
self.context = ContainerContext(log_file = debug_file)
component._container_context = self.context
if type is not None:
self.container_class = container_registry(type, 'Container')
elif container_class is None:
if params.setdefault('data_dir', None) is not None:
# DBMContainer is definitely faster than FileContainer
# for caching
self.container_class = DBMContainer
else:
self.container_class = MemoryContainer
else:
self.container_class = container_class
def _get_container(self, key, **params):
if not self.dict.has_key(key):
self.dict[key] = self._create_container(self.namespace, key, **params)
return self.dict[key]
def _create_container(self, namespace, key, type = None, container_class = None, **params):
if container_class is None:
if type is not None:
container_class = container_registry(type, 'Container')
else:
container_class = self.container_class
cparams = self.params.get_params(**params)
return container_class(context = self.context, namespace = namespace, key = key, **cparams)
def set_container(self, key, **params):
self.dict[key] = self._create_container(self.namespace, key, **params)
return self.dict[key]
def get_container(self, key, **params):
return self._get_container(key, **params)
def get_value(self, key, **params):
return self._get_container(key, **params).get_value()
def set_value(self, key, value, **params):
self._get_container(key, **params).set_value(value)
def remove_value(self, key):
if self.dict.has_key(key):
self.dict[key].clear_value()
del self.dict[key]
def clear(self):
nm = self.get_container(None).get_namespace_manager()
nm.remove()
self.dict = {}
# public dict interface
def __getitem__(self, key):
return self.get_value(key)
def __contains__(self, key):
container = self._get_container(key)
return container.has_current_value()
def has_key(self, key):
container = self._get_container(key)
return container.has_current_value()
def __delitem__(self, key):
self.remove_value(key)
def __setitem__(self, key, value):
self.set_value(key, value)
class CacheArgs(PrefixArgs):
def __init__(self, **params):
PrefixArgs.__init__(self, 'cache_')
self.set_prefix_params(**params)
def clone(self, **params):
p = self.get_params(**params)
arg = CacheArgs()
arg.params = p
return arg
def get_cache(self, component, **params):
return Cache(component, **self.get_params(**params))
|