lrucache.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. class LRUCache:
  2. def __init__(self, capacity, dispose):
  3. self._cache = {}
  4. self._lru = []
  5. self._capacity = capacity
  6. self._dispose = dispose
  7. def __setitem__(self, key, value):
  8. assert key not in self._cache, (
  9. "Unexpected attempt to replace a cached item."
  10. " If this is intended, please delete the old item first."
  11. " The dispose function will be called on delete.")
  12. self._lru.append(key)
  13. while len(self._lru) > self._capacity:
  14. del self[self._lru[0]]
  15. self._cache[key] = value
  16. def __getitem__(self, key):
  17. try:
  18. self._lru.remove(key)
  19. self._lru.append(key)
  20. except ValueError:
  21. pass
  22. return self._cache[key]
  23. def __delitem__(self, key):
  24. try:
  25. self._lru.remove(key)
  26. except ValueError:
  27. pass
  28. error = KeyError(key)
  29. removed = self._cache.pop(key, error)
  30. if removed == error:
  31. raise error
  32. self._dispose(removed)
  33. def __contains__(self, key):
  34. return key in self._cache
  35. def clear(self):
  36. for value in self._cache.values():
  37. self._dispose(value)
  38. self._cache.clear()
  39. # useful for testing
  40. def items(self):
  41. return self._cache.items()
  42. def __len__(self):
  43. return len(self._cache)