| 1 | "Memcached cache backend"
|
|---|
| 2 |
|
|---|
| 3 | from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError
|
|---|
| 4 |
|
|---|
| 5 | try:
|
|---|
| 6 | import memcache
|
|---|
| 7 | except 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 | #
|
|---|
| 16 | try:
|
|---|
| 17 | import hashlib
|
|---|
| 18 | key_hasher = hashlib.sha1
|
|---|
| 19 | except ImportError:
|
|---|
| 20 | import sha
|
|---|
| 21 | key_hasher = sha.new
|
|---|
| 22 |
|
|---|
| 23 | class 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)
|
|---|