Code

Ticket #6099: md5_no_refcount.patch

File md5_no_refcount.patch, 6.3 KB (added by sherbang, 7 years ago)

New patch - removes refcounting stubs

  • django/core/cache/backends/filebased.py

    diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py
    index 72cb877..5299ab4 100644
    a b  
    11"File-based cache backend" 
    22 
     3import md5 
    34import os, time 
    45try: 
    56    import cPickle as pickle 
    67except ImportError: 
    78    import pickle 
    89from django.core.cache.backends.base import BaseCache 
    9 from django.utils.http import urlquote_plus 
    1010 
    1111class CacheClass(BaseCache): 
    1212    def __init__(self, dir, params): 
    class CacheClass(BaseCache): 
    2929            self._createdir() 
    3030 
    3131    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) 
    5036 
    5137    def get(self, key, default=None): 
    5238        fname = self._key_to_file(key) 
    class CacheClass(BaseCache): 
    5642            now = time.time() 
    5743            if exp < now: 
    5844                f.close() 
    59                 os.remove(fname) 
     45                self._delete(fname) 
    6046            else: 
    6147                return pickle.load(f) 
    6248        except (IOError, OSError, EOFError, pickle.PickleError): 
    class CacheClass(BaseCache): 
    6551 
    6652    def set(self, key, value, timeout=None): 
    6753        fname = self._key_to_file(key) 
     54        dir = os.path.dirname(fname) 
     55         
    6856        if timeout is None: 
    6957            timeout = self.default_timeout 
     58             
     59        self._cull() 
     60         
    7061        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 
    7865            f = open(fname, 'wb') 
    7966            now = time.time() 
    8067            pickle.dump(now + timeout, f, 2) 
    class CacheClass(BaseCache): 
    8471 
    8572    def delete(self, key): 
    8673        try: 
    87             os.remove(self._key_to_file(key)) 
     74            self._delete(self._key_to_file(key)) 
    8875        except (IOError, OSError): 
    8976            pass 
    9077 
     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 
    9188    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 
    93102 
    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         
    95112        if self._cull_frequency == 0: 
    96113            doomed = filelist 
    97114        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: 
    100118            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)) 
    102122            except (IOError, OSError): 
    103123                pass 
    104124 
    class CacheClass(BaseCache): 
    109129            raise EnvironmentError, "Cache directory '%s' does not exist and could not be created'" % self._dir 
    110130 
    111131    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 
  • tests/regressiontests/cache/tests.py

    diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
    index 9ac2722..c6b8742 100644
    a b class Cache(unittest.TestCase): 
    2424 
    2525    def test_add(self): 
    2626        # test add (only add if key isn't already in cache) 
    27         cache.add("addkey1", "value") 
     27        cache.set("addkey1", "value") 
    2828        cache.add("addkey1", "newvalue") 
    2929        self.assertEqual(cache.get("addkey1"), "value") 
    30  
     30         
    3131    def test_non_existent(self): 
    3232        # get with non-existent keys 
    3333        self.assertEqual(cache.get("does_not_exist"), None) 
    class Cache(unittest.TestCase): 
    7777 
    7878    def test_expiration(self): 
    7979        # 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) 
    8183        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) 
    8391 
    8492    def test_unicode(self): 
    8593        stuff = {