diff options
Diffstat (limited to 'webapp/django/core/cache/backends/locmem.py')
-rw-r--r-- | webapp/django/core/cache/backends/locmem.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/webapp/django/core/cache/backends/locmem.py b/webapp/django/core/cache/backends/locmem.py new file mode 100644 index 0000000000..15a169dc37 --- /dev/null +++ b/webapp/django/core/cache/backends/locmem.py @@ -0,0 +1,129 @@ +"Thread-safe in-memory cache backend." + +import time +try: + import cPickle as pickle +except ImportError: + import pickle + +from django.core.cache.backends.base import BaseCache +from django.utils.synch import RWLock + +class CacheClass(BaseCache): + def __init__(self, _, params): + BaseCache.__init__(self, params) + self._cache = {} + self._expire_info = {} + + max_entries = params.get('max_entries', 300) + try: + self._max_entries = int(max_entries) + except (ValueError, TypeError): + self._max_entries = 300 + + cull_frequency = params.get('cull_frequency', 3) + try: + self._cull_frequency = int(cull_frequency) + except (ValueError, TypeError): + self._cull_frequency = 3 + + self._lock = RWLock() + + def add(self, key, value, timeout=None): + self._lock.writer_enters() + try: + exp = self._expire_info.get(key) + if exp is None or exp <= time.time(): + try: + self._set(key, pickle.dumps(value), timeout) + return True + except pickle.PickleError: + pass + return False + finally: + self._lock.writer_leaves() + + def get(self, key, default=None): + self._lock.reader_enters() + try: + exp = self._expire_info.get(key) + if exp is None: + return default + elif exp > time.time(): + try: + return pickle.loads(self._cache[key]) + except pickle.PickleError: + return default + finally: + self._lock.reader_leaves() + self._lock.writer_enters() + try: + del self._cache[key] + del self._expire_info[key] + return default + finally: + self._lock.writer_leaves() + + def _set(self, key, value, timeout=None): + if len(self._cache) >= self._max_entries: + self._cull() + if timeout is None: + timeout = self.default_timeout + self._cache[key] = value + self._expire_info[key] = time.time() + timeout + + def set(self, key, value, timeout=None): + self._lock.writer_enters() + # Python 2.3 and 2.4 don't allow combined try-except-finally blocks. + try: + try: + self._set(key, pickle.dumps(value), timeout) + except pickle.PickleError: + pass + finally: + self._lock.writer_leaves() + + def has_key(self, key): + self._lock.reader_enters() + try: + exp = self._expire_info.get(key) + if exp is None: + return False + elif exp > time.time(): + return True + finally: + self._lock.reader_leaves() + + self._lock.writer_enters() + try: + del self._cache[key] + del self._expire_info[key] + return False + finally: + self._lock.writer_leaves() + + def _cull(self): + if self._cull_frequency == 0: + self._cache.clear() + self._expire_info.clear() + else: + doomed = [k for (i, k) in enumerate(self._cache) if i % self._cull_frequency == 0] + for k in doomed: + self._delete(k) + + def _delete(self, key): + try: + del self._cache[key] + except KeyError: + pass + try: + del self._expire_info[key] + except KeyError: + pass + + def delete(self, key): + self._lock.writer_enters() + try: + self._delete(key) + finally: + self._lock.writer_leaves() |