2015-08-12 18:30:26 -04:00
|
|
|
class LRUCache:
|
2015-08-12 18:13:34 -04:00
|
|
|
def __init__(self, capacity, dispose):
|
2015-08-12 18:30:26 -04:00
|
|
|
self._cache = {}
|
2012-12-06 16:57:55 -05:00
|
|
|
self._lru = []
|
|
|
|
|
self._capacity = capacity
|
2015-08-12 18:13:34 -04:00
|
|
|
self._dispose = dispose
|
2010-12-04 15:03:02 -05:00
|
|
|
|
|
|
|
|
def __setitem__(self, key, value):
|
2015-08-12 18:30:26 -04:00
|
|
|
assert key not in self._cache, (
|
2015-08-13 06:02:00 -04:00
|
|
|
"Unexpected attempt to replace a cached item,"
|
|
|
|
|
" without first deleting the old item.")
|
2012-12-06 16:57:55 -05:00
|
|
|
self._lru.append(key)
|
|
|
|
|
while len(self._lru) > self._capacity:
|
|
|
|
|
del self[self._lru[0]]
|
2015-08-12 18:30:26 -04:00
|
|
|
self._cache[key] = value
|
2010-12-04 15:03:02 -05:00
|
|
|
|
|
|
|
|
def __getitem__(self, key):
|
2015-08-14 05:14:17 -04:00
|
|
|
value = self._cache[key] # raise KeyError if not found
|
|
|
|
|
self._lru.remove(key)
|
|
|
|
|
self._lru.append(key)
|
|
|
|
|
return value
|
2010-12-04 15:03:02 -05:00
|
|
|
|
|
|
|
|
def __delitem__(self, key):
|
2015-08-14 05:14:17 -04:00
|
|
|
value = self._cache.pop(key) # raise KeyError if not found
|
|
|
|
|
self._dispose(value)
|
|
|
|
|
self._lru.remove(key)
|
2010-12-04 15:03:02 -05:00
|
|
|
|
2015-08-12 18:30:26 -04:00
|
|
|
def __contains__(self, key):
|
|
|
|
|
return key in self._cache
|
2012-12-18 13:51:34 -05:00
|
|
|
|
2015-08-12 18:13:34 -04:00
|
|
|
def clear(self):
|
2015-08-12 18:30:26 -04:00
|
|
|
for value in self._cache.values():
|
2015-08-12 18:13:34 -04:00
|
|
|
self._dispose(value)
|
2015-08-12 18:30:26 -04:00
|
|
|
self._cache.clear()
|
|
|
|
|
|
|
|
|
|
# useful for testing
|
|
|
|
|
def items(self):
|
|
|
|
|
return self._cache.items()
|
2015-08-12 18:13:34 -04:00
|
|
|
|
2015-08-12 18:30:26 -04:00
|
|
|
def __len__(self):
|
|
|
|
|
return len(self._cache)
|