You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.5 KiB
125 lines
3.5 KiB
5 years ago
|
"""
|
||
|
Memory Backends
|
||
|
---------------
|
||
|
|
||
|
Provides simple dictionary-based backends.
|
||
|
|
||
|
The two backends are :class:`.MemoryBackend` and :class:`.MemoryPickleBackend`;
|
||
|
the latter applies a serialization step to cached values while the former
|
||
|
places the value as given into the dictionary.
|
||
|
|
||
|
"""
|
||
|
|
||
|
from ..api import CacheBackend, NO_VALUE
|
||
|
from ...util.compat import pickle
|
||
|
|
||
|
|
||
|
class MemoryBackend(CacheBackend):
|
||
|
"""A backend that uses a plain dictionary.
|
||
|
|
||
|
There is no size management, and values which
|
||
|
are placed into the dictionary will remain
|
||
|
until explicitly removed. Note that
|
||
|
Dogpile's expiration of items is based on
|
||
|
timestamps and does not remove them from
|
||
|
the cache.
|
||
|
|
||
|
E.g.::
|
||
|
|
||
|
from dogpile.cache import make_region
|
||
|
|
||
|
region = make_region().configure(
|
||
|
'dogpile.cache.memory'
|
||
|
)
|
||
|
|
||
|
|
||
|
To use a Python dictionary of your choosing,
|
||
|
it can be passed in with the ``cache_dict``
|
||
|
argument::
|
||
|
|
||
|
my_dictionary = {}
|
||
|
region = make_region().configure(
|
||
|
'dogpile.cache.memory',
|
||
|
arguments={
|
||
|
"cache_dict":my_dictionary
|
||
|
}
|
||
|
)
|
||
|
|
||
|
|
||
|
"""
|
||
|
pickle_values = False
|
||
|
|
||
|
def __init__(self, arguments):
|
||
|
self._cache = arguments.pop("cache_dict", {})
|
||
|
|
||
|
def get(self, key):
|
||
|
value = self._cache.get(key, NO_VALUE)
|
||
|
if value is not NO_VALUE and self.pickle_values:
|
||
|
value = pickle.loads(value)
|
||
|
return value
|
||
|
|
||
|
def get_multi(self, keys):
|
||
|
ret = [
|
||
|
self._cache.get(key, NO_VALUE)
|
||
|
for key in keys]
|
||
|
if self.pickle_values:
|
||
|
ret = [
|
||
|
pickle.loads(value)
|
||
|
if value is not NO_VALUE else value
|
||
|
for value in ret
|
||
|
]
|
||
|
return ret
|
||
|
|
||
|
def set(self, key, value):
|
||
|
if self.pickle_values:
|
||
|
value = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
|
||
|
self._cache[key] = value
|
||
|
|
||
|
def set_multi(self, mapping):
|
||
|
pickle_values = self.pickle_values
|
||
|
for key, value in mapping.items():
|
||
|
if pickle_values:
|
||
|
value = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
|
||
|
self._cache[key] = value
|
||
|
|
||
|
def delete(self, key):
|
||
|
self._cache.pop(key, None)
|
||
|
|
||
|
def delete_multi(self, keys):
|
||
|
for key in keys:
|
||
|
self._cache.pop(key, None)
|
||
|
|
||
|
|
||
|
class MemoryPickleBackend(MemoryBackend):
|
||
|
"""A backend that uses a plain dictionary, but serializes objects on
|
||
|
:meth:`.MemoryBackend.set` and deserializes :meth:`.MemoryBackend.get`.
|
||
|
|
||
|
E.g.::
|
||
|
|
||
|
from dogpile.cache import make_region
|
||
|
|
||
|
region = make_region().configure(
|
||
|
'dogpile.cache.memory_pickle'
|
||
|
)
|
||
|
|
||
|
The usage of pickle to serialize cached values allows an object
|
||
|
as placed in the cache to be a copy of the original given object, so
|
||
|
that any subsequent changes to the given object aren't reflected
|
||
|
in the cached value, thus making the backend behave the same way
|
||
|
as other backends which make use of serialization.
|
||
|
|
||
|
The serialization is performed via pickle, and incurs the same
|
||
|
performance hit in doing so as that of other backends; in this way
|
||
|
the :class:`.MemoryPickleBackend` performance is somewhere in between
|
||
|
that of the pure :class:`.MemoryBackend` and the remote server oriented
|
||
|
backends such as that of Memcached or Redis.
|
||
|
|
||
|
Pickle behavior here is the same as that of the Redis backend, using
|
||
|
either ``cPickle`` or ``pickle`` and specifying ``HIGHEST_PROTOCOL``
|
||
|
upon serialize.
|
||
|
|
||
|
.. versionadded:: 0.5.3
|
||
|
|
||
|
"""
|
||
|
pickle_values = True
|