Problem:
LRUCache
with capacity = 1
Today I decided to challenge myself and implement a LRU Cache in 25 minutes (Pomodoro FTW).
Quick brainstorm and decided to go with a double linked list and a dict (for _key => listnode).
The basic idea is:
After implementing the whole thing I realise, wait, isn't collections.OrderedDict
just that?
Here's a simple LRU Cache.
In [83]:
from collections import OrderedDict
class LRUCache(object):
"""Implementation of a LRU Cache. Iterating goes from oldest to newest."""
def __init__(self, capacity):
self._cache_impl = OrderedDict()
# calling self.items to count isn't O(1)
self._count = 0
# A simple maximum number of items
self._capacity = capacity
def __setitem__(self, key, value):
"""Set the value for the key and move it to the most recent.
If the cache is full, delete the oldest item.
"""
if key in self._cache_impl:
del self._cache_impl[key]
elif self.full():
# last=False because inserting a new key adds to the end
self._cache_impl.popitem(last=False)
else:
self._count += 1
self._cache_impl[key] = value
def __getitem__(self, key):
"""Get the value for the key and move it to the most recent."""
value = self._cache_impl[key]
del self._cache_impl[key]
self._cache_impl[key] = value
return value
def __delitem__(self, key):
del self._cache_impl[key]
self._count -= 1
def full(self):
return self._count == self._capacity
def values(self):
return self._cache_impl.values()
And here's a simple test:
In [96]:
def test_cache():
cache = LRUCache(2)
cache['spoing'] = 1
cache['boing'] = 2
assert cache.values() == [1,2]
assert cache['spoing'] == 1
assert cache.values() == [2,1]
cache['boom'] = 3
assert cache.values() == [1,3]
cache = LRUCache(3)
cache['spoing'] = 1
cache['boing'] = 2
assert cache.values() == [1,2]
assert cache['spoing'] == 1
assert cache.values() == [2,1]
cache['boom'] = 3
assert cache.values() == [2,1,3]
cache['spoing'] = 4
assert cache.values() == [2,3,4]
I really love python!
In [ ]: