1
0
mirror of https://github.com/django/django.git synced 2025-11-07 07:15:35 +00:00

Fixed #12671 -- Added set_many(), get_many(), and clear() methods to the cache backend interface. Thanks to Jeff Balogh for the report and patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12306 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee
2010-01-27 08:21:35 +00:00
parent c6ee1f6f24
commit 8e8d4b5888
9 changed files with 142 additions and 10 deletions

View File

@@ -91,3 +91,28 @@ class BaseCache(object):
# so that it always has the same functionality as has_key(), even
# if a subclass overrides it.
return self.has_key(key)
def set_many(self, data, timeout=None):
"""
Set a bunch of values in the cache at once from a dict of key/value
pairs. For certain backends (memcached), this is much more efficient
than calling set() multiple times.
If timeout is given, that timeout will be used for the key; otherwise
the default cache timeout will be used.
"""
for key, value in data.items():
self.set(key, value, timeout)
def delete_many(self, keys):
"""
Set a bunch of values in the cache at once. For certain backends
(memcached), this is much more efficient than calling delete() multiple
times.
"""
for key in keys:
self.delete(key)
def clear(self):
"""Remove *all* values from the cache at once."""
raise NotImplementedError

View File

@@ -84,7 +84,7 @@ class CacheClass(BaseCache):
def _cull(self, cursor, now):
if self._cull_frequency == 0:
cursor.execute("DELETE FROM %s" % self._table)
self.clear()
else:
cursor.execute("DELETE FROM %s WHERE expires < %%s" % self._table, [str(now)])
cursor.execute("SELECT COUNT(*) FROM %s" % self._table)
@@ -92,3 +92,7 @@ class CacheClass(BaseCache):
if num > self._max_entries:
cursor.execute("SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" % self._table, [num / self._cull_frequency])
cursor.execute("DELETE FROM %s WHERE cache_key < %%s" % self._table, [cursor.fetchone()[0]])
def clear(self):
cursor = connection.cursor()
cursor.execute('DELETE FROM %s' % self._table)

View File

@@ -23,3 +23,12 @@ class CacheClass(BaseCache):
def has_key(self, *args, **kwargs):
return False
def set_many(self, *args, **kwargs):
pass
def delete_many(self, *args, **kwargs):
pass
def clear(self):
pass

View File

@@ -2,6 +2,7 @@
import os
import time
import shutil
try:
import cPickle as pickle
except ImportError:
@@ -150,3 +151,9 @@ class CacheClass(BaseCache):
count += len(files)
return count
_num_entries = property(_get_num_entries)
def clear(self):
try:
shutil.rmtree(self._dir)
except (IOError, OSError):
pass

View File

@@ -110,8 +110,7 @@ class CacheClass(BaseCache):
def _cull(self):
if self._cull_frequency == 0:
self._cache.clear()
self._expire_info.clear()
self.clear()
else:
doomed = [k for (i, k) in enumerate(self._cache) if i % self._cull_frequency == 0]
for k in doomed:
@@ -133,3 +132,7 @@ class CacheClass(BaseCache):
self._delete(key)
finally:
self._lock.writer_leaves()
def clear(self):
self._cache.clear()
self._expire_info.clear()

View File

@@ -71,3 +71,17 @@ class CacheClass(BaseCache):
if val is None:
raise ValueError("Key '%s' not found" % key)
return val
def set_many(self, data, timeout=0):
safe_data = {}
for key, value in data.items():
if isinstance(value, unicode):
value = value.encode('utf-8')
safe_data[smart_str(key)] = value
self._cache.set_multi(safe_data, timeout or self.default_timeout)
def delete_many(self, keys):
self._cache.delete_multi(map(smart_str, keys))
def clear(self):
self._cache.flush_all()