Code

Ticket #3241: memcached.py

File memcached.py, 1.6 KB (added by recalcitrare@…, 7 years ago)

revision of memcached backend that can handle keys > 250 characters or containing spaces

Line 
1"Memcached cache backend"
2
3from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
4
5try:
6    import memcache
7except ImportError:
8    raise InvalidCacheBackendError, "Memcached cache backend requires the 'memcache' library"
9
10#
11# The memcache module refuses to use keys longer than 250 characters or containing
12# "control characters", which it defines as anything with a decimal ASCII code below
13# 33. This definition includes the non-printable ASCII characters and the space character,
14# so to allow caching of very long URLs or URLs containing spaces we'll hash them.
15#
16try:
17    import hashlib
18    key_hasher = hashlib.sha1
19except ImportError:
20    import sha
21    key_hasher = sha.new
22
23class CacheClass(BaseCache):
24    def __init__(self, server, params):
25        BaseCache.__init__(self, params)
26        self._cache = memcache.Client(server.split(';'))
27
28    def hash_key(self, key):
29        if ' ' not in key and len(key) < memcache.SERVER_MAX_KEY_LENGTH:
30            return key
31
32        key_hash = key_hasher()
33        key_hash.update(key)
34        return key_hash.hexdigest()
35
36    def get(self, key, default=None):
37        val = self._cache.get(self.hash_key(key))
38        if val is None:
39            return default
40        else:
41            return val
42
43    def set(self, key, value, timeout=0):
44        self._cache.set(self.hash_key(key), value, timeout or self.default_timeout)
45
46    def delete(self, key):
47        self._cache.delete(self.hash_key(key))
48
49    def get_many(self, keys):
50        keys = [self.hash_key(key) for key in keys]
51        return self._cache.get_multi(keys)