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