--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/django/core/cache/backends/locmem.py Fri Jul 18 18:22:23 2008 +0000
@@ -0,0 +1,127 @@
+"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)
+ except pickle.PickleError:
+ pass
+ 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()