summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <classic@zzzcomputing.com>2013-11-26 22:13:46 -0500
committerMike Bayer <classic@zzzcomputing.com>2013-11-26 22:13:46 -0500
commit6e0491a7e3d83d00df277e261031cf64f0ee437e (patch)
tree40798eb5e52b8ab659f22b07ef4cf9928c0bc100
parentc9deaf1b8879d295f8d2eac03b17bdf10033cd84 (diff)
parent4ff86bd4bb728e5bac000af4d4f2e64b8e456f03 (diff)
downloaddogpile-cache-6e0491a7e3d83d00df277e261031cf64f0ee437e.tar.gz
Merged in jvanasco/dogpile.cache (pull request #11)
memory_pickle backend support
-rw-r--r--docs/build/api.rst15
-rw-r--r--dogpile/cache/backends/__init__.py1
-rw-r--r--dogpile/cache/backends/memory.py42
-rw-r--r--tests/cache/test_memory_pickle_backend.py5
4 files changed, 51 insertions, 12 deletions
diff --git a/docs/build/api.rst b/docs/build/api.rst
index d45493e..1f79c73 100644
--- a/docs/build/api.rst
+++ b/docs/build/api.rst
@@ -14,12 +14,12 @@ Backend API
=============
See the section :ref:`creating_backends` for details on how to
-register new backends or :ref:`changing_backend_behavior` for details on
-how to alter the behavior of existing backends.
+register new backends or :ref:`changing_backend_behavior` for details on
+how to alter the behavior of existing backends.
.. automodule:: dogpile.cache.api
:members:
-
+
Backends
==========
@@ -27,6 +27,9 @@ Backends
.. automodule:: dogpile.cache.backends.memory
:members:
+.. automodule:: dogpile.cache.backends.memory_pickle
+ :members:
+
.. automodule:: dogpile.cache.backends.memcached
:members:
@@ -35,11 +38,11 @@ Backends
.. automodule:: dogpile.cache.backends.file
:members:
-
+
.. automodule:: dogpile.cache.proxy
:members:
-
-
+
+
Plugins
========
diff --git a/dogpile/cache/backends/__init__.py b/dogpile/cache/backends/__init__.py
index a0c111b..a9b9c2e 100644
--- a/dogpile/cache/backends/__init__.py
+++ b/dogpile/cache/backends/__init__.py
@@ -5,4 +5,5 @@ register_backend("dogpile.cache.pylibmc", "dogpile.cache.backends.memcached", "P
register_backend("dogpile.cache.bmemcached", "dogpile.cache.backends.memcached", "BMemcachedBackend")
register_backend("dogpile.cache.memcached", "dogpile.cache.backends.memcached", "MemcachedBackend")
register_backend("dogpile.cache.memory", "dogpile.cache.backends.memory", "MemoryBackend")
+register_backend("dogpile.cache.memory_pickle", "dogpile.cache.backends.memory", "MemoryPickleBackend")
register_backend("dogpile.cache.redis", "dogpile.cache.backends.redis", "RedisBackend")
diff --git a/dogpile/cache/backends/memory.py b/dogpile/cache/backends/memory.py
index e606bea..a37b3d9 100644
--- a/dogpile/cache/backends/memory.py
+++ b/dogpile/cache/backends/memory.py
@@ -8,6 +8,11 @@ Provides a simple dictionary-based backend.
from dogpile.cache.api import CacheBackend, NO_VALUE
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
class MemoryBackend(CacheBackend):
"""A backend that uses a plain dictionary.
@@ -41,24 +46,32 @@ class MemoryBackend(CacheBackend):
"""
+ is_pickle = False
+
def __init__(self, arguments):
self._cache = arguments.pop("cache_dict", {})
def get(self, key):
- return self._cache.get(key, NO_VALUE)
+ value = self._cache.get(key, NO_VALUE)
+ if value is not NO_VALUE :
+ if self.is_pickle :
+ value = pickle.loads(value)
+ return value
def get_multi(self, keys):
- return [
- self._cache.get(key, NO_VALUE)
- for key in keys
- ]
+ values = []
+ for key in keys :
+ values.append(self.get(key))
+ return values
def set(self, key, value):
+ if self.is_pickle :
+ value = pickle.dumps(value)
self._cache[key] = value
def set_multi(self, mapping):
for key,value in mapping.items():
- self._cache[key] = value
+ self.set(key, value)
def delete(self, key):
self._cache.pop(key, None)
@@ -66,3 +79,20 @@ class MemoryBackend(CacheBackend):
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 `set`
+ and deserializes the objects on `get`. This is because objects cached in
+ the MemoryBackend are cached as the actual object, so changes to them will
+ persist without a `set`.
+
+ This backend takes a lightweight performance hit through pickling, in order
+ to achieve parity with other cache backends where the objects returned by
+ `get` are a discretely new object, and `set` must be called to persist
+ changes.
+
+ MemoryPickleBackend will try to serialize with cPickle, and will fall back
+ to pickle if it is not available.
+ """
+ is_pickle = True
diff --git a/tests/cache/test_memory_pickle_backend.py b/tests/cache/test_memory_pickle_backend.py
new file mode 100644
index 0000000..563718c
--- /dev/null
+++ b/tests/cache/test_memory_pickle_backend.py
@@ -0,0 +1,5 @@
+from ._fixtures import _GenericBackendTest
+
+class MemoryBackendTest(_GenericBackendTest):
+ backend = "dogpile.cache.memory_pickle"
+