Created
July 12, 2013 15:10
-
-
Save agriffis/5985202 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.core.cache import get_cache | |
class KeyedCache(object): | |
""" | |
Proxied cache object to allow objects to implement their own keying, | |
for example a Django model can implement per-row caching with: | |
def cache_key(self, key): | |
return '{}.{}.{}'.format(self.__class__.__name__, self.pk, key) | |
@property | |
def cache(self): | |
return KeyedCache(lambda k: self.cache_key(k)) | |
then access the cache as `self.cache` instead of the usual bare `cache`. | |
This was originally implemented as a Lieberman-style Proxy (see | |
util/__init__.py) but there were too many leaks because of state stored | |
in the underlying object which could cause the wrong make_key() to be | |
called. This new implementation is much simpler and exposes a limited | |
API which can be augmented as needed. | |
""" | |
def __init__(self, key_func, cache=None): | |
self._key_func = key_func | |
self._cache = cache or get_cache('default') | |
def get(self, key): | |
key = self._key_func(key) | |
return self._cache.get(key) | |
def get_many(self, keys): | |
keys = [self._key_func(k) for k in keys] | |
data = self._cache.get_many(keys) | |
prefix = self._key_func('') # assumes that key is appended | |
assert all(k.startswith(prefix) for k in data) | |
return {k[len(prefix):]:v for k, v in data.items()} | |
def set(self, key, value, timeout=None): | |
key = self._key_func(key) | |
return self._cache.set(key, value, timeout=timeout) | |
def set_many(self, data, timeout=None): | |
data = {self._key_func(k):v for k, v in data.items()} | |
return self._cache.set_many(data, timeout=timeout) | |
def add(self, key, value, timeout=None): | |
key = self._key_func(key) | |
return self._cache.add(key, value, timeout=timeout) | |
def delete(self, key): | |
key = self._key_func(key) | |
return self._cache.delete(key) | |
def delete_many(self, keys): | |
keys = [self._key_func(k) for k in keys] | |
return self._cache.delete_many(keys) | |
def clear(self): | |
keys = self.keys('*') | |
return self.delete_many(keys) | |
def has_key(self, key): | |
key = self._key_func(key) | |
return self._cache.has_key(key) | |
def keys(self, patt): | |
patt = self._key_func(patt) | |
keys = self._cache.keys(patt) | |
prefix = self._key_func('') # assumes that key is appended | |
assert all(k.startswith(prefix) for k in keys) | |
return [k[len(prefix):] for k in keys] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment