OLD | NEW |
(Empty) | |
| 1 from .abc import DefaultMapping |
| 2 |
| 3 |
| 4 class _DefaultSize(object): |
| 5 def __getitem__(self, _): |
| 6 return 1 |
| 7 |
| 8 def __setitem__(self, _, value): |
| 9 assert value == 1 |
| 10 |
| 11 def pop(self, _): |
| 12 return 1 |
| 13 |
| 14 |
| 15 class Cache(DefaultMapping): |
| 16 """Mutable mapping to serve as a simple cache or cache base class.""" |
| 17 |
| 18 __size = _DefaultSize() |
| 19 |
| 20 def __init__(self, maxsize, missing=None, getsizeof=None): |
| 21 if missing: |
| 22 self.__missing = missing |
| 23 if getsizeof: |
| 24 self.__getsizeof = getsizeof |
| 25 self.__size = dict() |
| 26 self.__data = dict() |
| 27 self.__currsize = 0 |
| 28 self.__maxsize = maxsize |
| 29 |
| 30 def __repr__(self): |
| 31 return '%s(%r, maxsize=%d, currsize=%d)' % ( |
| 32 self.__class__.__name__, |
| 33 list(self.__data.items()), |
| 34 self.__maxsize, |
| 35 self.__currsize, |
| 36 ) |
| 37 |
| 38 def __getitem__(self, key): |
| 39 try: |
| 40 return self.__data[key] |
| 41 except KeyError: |
| 42 return self.__missing__(key) |
| 43 |
| 44 def __setitem__(self, key, value): |
| 45 maxsize = self.__maxsize |
| 46 size = self.getsizeof(value) |
| 47 if size > maxsize: |
| 48 raise ValueError('value too large') |
| 49 if key not in self.__data or self.__size[key] < size: |
| 50 while self.__currsize + size > maxsize: |
| 51 self.popitem() |
| 52 if key in self.__data: |
| 53 diffsize = size - self.__size[key] |
| 54 else: |
| 55 diffsize = size |
| 56 self.__data[key] = value |
| 57 self.__size[key] = size |
| 58 self.__currsize += diffsize |
| 59 |
| 60 def __delitem__(self, key): |
| 61 size = self.__size.pop(key) |
| 62 del self.__data[key] |
| 63 self.__currsize -= size |
| 64 |
| 65 def __contains__(self, key): |
| 66 return key in self.__data |
| 67 |
| 68 def __missing__(self, key): |
| 69 value = self.__missing(key) |
| 70 try: |
| 71 self.__setitem__(key, value) |
| 72 except ValueError: |
| 73 pass # value too large |
| 74 return value |
| 75 |
| 76 def __iter__(self): |
| 77 return iter(self.__data) |
| 78 |
| 79 def __len__(self): |
| 80 return len(self.__data) |
| 81 |
| 82 @staticmethod |
| 83 def __getsizeof(value): |
| 84 return 1 |
| 85 |
| 86 @staticmethod |
| 87 def __missing(key): |
| 88 raise KeyError(key) |
| 89 |
| 90 @property |
| 91 def maxsize(self): |
| 92 """The maximum size of the cache.""" |
| 93 return self.__maxsize |
| 94 |
| 95 @property |
| 96 def currsize(self): |
| 97 """The current size of the cache.""" |
| 98 return self.__currsize |
| 99 |
| 100 def getsizeof(self, value): |
| 101 """Return the size of a cache element's value.""" |
| 102 return self.__getsizeof(value) |
OLD | NEW |