Ticket #6099: md5_no_refcount.patch
| File md5_no_refcount.patch, 6.3 kB (added by sherbang, 9 months ago) |
|---|
-
a/django/core/cache/backends/filebased.py
old new 1 1 "File-based cache backend" 2 2 3 import md5 3 4 import os, time 4 5 try: 5 6 import cPickle as pickle 6 7 except ImportError: 7 8 import pickle 8 9 from django.core.cache.backends.base import BaseCache 9 from django.utils.http import urlquote_plus10 10 11 11 class CacheClass(BaseCache): 12 12 def __init__(self, dir, params): … … 29 29 self._createdir() 30 30 31 31 def add(self, key, value, timeout=None): 32 fname = self._key_to_file(key) 33 if timeout is None: 34 timeout = self.default_timeout 35 try: 36 filelist = os.listdir(self._dir) 37 except (IOError, OSError): 38 self._createdir() 39 filelist = [] 40 if len(filelist) > self._max_entries: 41 self._cull(filelist) 42 if os.path.basename(fname) not in filelist: 43 try: 44 f = open(fname, 'wb') 45 now = time.time() 46 pickle.dump(now + timeout, f, 2) 47 pickle.dump(value, f, 2) 48 except (IOError, OSError): 49 pass 32 if self.has_key(key): 33 return None 34 35 self.set(key, value, timeout) 50 36 51 37 def get(self, key, default=None): 52 38 fname = self._key_to_file(key) … … 56 42 now = time.time() 57 43 if exp < now: 58 44 f.close() 59 os.remove(fname)45 self._delete(fname) 60 46 else: 61 47 return pickle.load(f) 62 48 except (IOError, OSError, EOFError, pickle.PickleError): … … 65 51 66 52 def set(self, key, value, timeout=None): 67 53 fname = self._key_to_file(key) 54 dir = os.path.dirname(fname) 55 68 56 if timeout is None: 69 57 timeout = self.default_timeout 58 59 self._cull() 60 70 61 try: 71 filelist = os.listdir(self._dir) 72 except (IOError, OSError): 73 self._createdir() 74 filelist = [] 75 if len(filelist) > self._max_entries: 76 self._cull(filelist) 77 try: 62 if not os.path.exists(dir): 63 os.makedirs(dir) 64 78 65 f = open(fname, 'wb') 79 66 now = time.time() 80 67 pickle.dump(now + timeout, f, 2) … … 84 71 85 72 def delete(self, key): 86 73 try: 87 os.remove(self._key_to_file(key))74 self._delete(self._key_to_file(key)) 88 75 except (IOError, OSError): 89 76 pass 90 77 78 def _delete(self, file): 79 os.remove(file) 80 try: 81 #remove the 2 subdirs if they're empty 82 dir = os.path.dirname(file) 83 os.rmdir(dir) 84 os.rmdir(os.path.dirname(dir)) 85 except: 86 pass 87 91 88 def has_key(self, key): 92 return os.path.exists(self._key_to_file(key)) 89 fname = self._key_to_file(key) 90 try: 91 f = open(fname, 'rb') 92 exp = pickle.load(f) 93 now = time.time() 94 if exp < now: 95 f.close() 96 self._delete(fname) 97 return False 98 else: 99 return True 100 except (IOError, OSError, EOFError, pickle.PickleError): 101 return False 93 102 94 def _cull(self, filelist): 103 def _cull(self): 104 if int(self._num_entries) < self._max_entries: 105 return 106 107 try: 108 filelist = os.listdir(self._dir) 109 except (IOError, OSError): 110 return 111 95 112 if self._cull_frequency == 0: 96 113 doomed = filelist 97 114 else: 98 doomed = [k for (i, k) in enumerate(filelist) if i % self._cull_frequency == 0] 99 for fname in doomed: 115 doomed = [os.path.join(self._dir, k) for (i, k) in enumerate(filelist) if i % self._cull_frequency == 0] 116 117 for topdir in doomed: 100 118 try: 101 os.remove(os.path.join(self._dir, fname)) 119 for root, _, files in os.walk(topdir): 120 for file in files: 121 self._delete(os.path.join(root,file)) 102 122 except (IOError, OSError): 103 123 pass 104 124 … … 109 129 raise EnvironmentError, "Cache directory '%s' does not exist and could not be created'" % self._dir 110 130 111 131 def _key_to_file(self, key): 112 return os.path.join(self._dir, urlquote_plus(key)) 132 path = md5.new(key.encode('utf-8')).hexdigest() 133 path = os.path.join(path[:2], path[2:4], path[4:]) 134 return os.path.join(self._dir, path) 135 136 def _get_num_entries(self): 137 count = 0 138 for _,_,files in os.walk(self._dir): 139 count += len(files) 140 return count 141 _num_entries = property(_get_num_entries) 142 -
a/tests/regressiontests/cache/tests.py
old new 24 24 25 25 def test_add(self): 26 26 # test add (only add if key isn't already in cache) 27 cache. add("addkey1", "value")27 cache.set("addkey1", "value") 28 28 cache.add("addkey1", "newvalue") 29 29 self.assertEqual(cache.get("addkey1"), "value") 30 30 31 31 def test_non_existent(self): 32 32 # get with non-existent keys 33 33 self.assertEqual(cache.get("does_not_exist"), None) … … 77 77 78 78 def test_expiration(self): 79 79 # expiration 80 cache.set('expire', 'very quickly', 1) 80 cache.set('expire1', 'very quickly', 1) 81 cache.set('expire2', 'very quickly', 1) 82 cache.set('expire3', 'very quickly', 1) 81 83 time.sleep(2) 82 self.assertEqual(cache.get("expire"), None) 84 85 self.assertEqual(cache.get("expire1"), None) 86 87 cache.add("expire2", "newvalue") 88 self.assertEqual(cache.get("expire2"), "newvalue") 89 90 self.assertEqual(cache.has_key("expire3"), False) 83 91 84 92 def test_unicode(self): 85 93 stuff = {
