Package translate :: Package misc :: Module lru
[hide private]
[frames] | no frames]

Source Code for Module translate.misc.lru

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # 
  4  # Copyright 2009 Zuza Software Foundation 
  5  # 
  6  # This file is part of translate. 
  7  # 
  8  # This program is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  # 
 13  # This program is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with this program; if not, see <http://www.gnu.org/licenses/>. 
 20   
 21  from collections import deque 
 22  from weakref import WeakValueDictionary 
 23  import gc 
 24   
25 -class LRUCachingDict(WeakValueDictionary):
26 """Caching dictionary like object that discards the least recently 27 used objects when number of cached items exceeds maxsize. 28 29 cullsize is the fraction of items that will be discarded when 30 maxsize is reached. 31 """ 32
33 - def __init__(self, maxsize, cullsize=2, *args, **kwargs):
34 self.cullsize = max(2, cullsize) 35 self.maxsize = max(cullsize, maxsize) 36 self.queue = deque() 37 WeakValueDictionary.__init__(self, *args, **kwargs)
38
39 - def __setitem__(self, key, value):
40 # check boundaries to minimiza duplicate references 41 while len(self.queue) and self.queue[0][0] == key: 42 # item at left end of queue pop it since it'll be appended 43 # to right 44 self.queue.popleft() 45 46 while len(self.queue) and self.queue[-1][0] == key: 47 # item at right end of queue pop it since it'll be 48 # appended again 49 self.queue.pop() 50 51 self.queue.append((key, value)) 52 WeakValueDictionary.__setitem__(self, key, value) 53 54 if len(self) > self.maxsize: 55 while len(self) > (self.maxsize - self.maxsize / self.cullsize): 56 # maximum cache size exceeded, remove an old item 57 self.queue.popleft() 58 while gc.collect() > 0: 59 pass
60
61 - def __getitem__(self, key):
62 value = WeakValueDictionary.__getitem__(self, key) 63 # check boundaries to minimiza duplicate references 64 while len(self.queue) > 1 and self.queue[0][0] == key: 65 # item at left end of queue pop it since it'll be appended 66 # to right 67 self.queue.popleft() 68 69 # only append if item is not at right end of queue 70 if not (len(self.queue) and self.queue[-1][0] == key): 71 self.queue.append((key, value)) 72 73 return value
74
75 - def __delitem__(self, key):
76 # can't efficiently find item in queue to delete, check 77 # boundaries. otherwise just wait till next cache purge 78 while len(self.queue) and self.queue[0][0] == key: 79 # item at left end of queue pop it since it'll be appended 80 # to right 81 self.queue.popleft() 82 83 while len(self.queue) and self.queue[-1][0] == key: 84 # item at right end of queue pop it since it'll be 85 # appended again 86 self.queue.pop() 87 88 return WeakValueDictionary.__delitem__(self, key)
89
90 - def clear(self):
91 self.queue.clear() 92 return WeakValueDictionary.clear(self)
93
94 - def setdefault(self, key, default):
95 if key not in self: 96 self[key]=default 97 98 return self[key]
99