aboutsummaryrefslogtreecommitdiff
path: root/src/cachetools/lru.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/cachetools/lru.py')
-rw-r--r--src/cachetools/lru.py40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/cachetools/lru.py b/src/cachetools/lru.py
new file mode 100644
index 0000000..dbbe787
--- /dev/null
+++ b/src/cachetools/lru.py
@@ -0,0 +1,40 @@
+import collections
+
+from .cache import Cache
+
+
+class LRUCache(Cache):
+ """Least Recently Used (LRU) cache implementation."""
+
+ def __init__(self, maxsize, getsizeof=None):
+ Cache.__init__(self, maxsize, getsizeof)
+ self.__order = collections.OrderedDict()
+
+ def __getitem__(self, key, cache_getitem=Cache.__getitem__):
+ value = cache_getitem(self, key)
+ if key in self: # __missing__ may not store item
+ self.__update(key)
+ return value
+
+ def __setitem__(self, key, value, cache_setitem=Cache.__setitem__):
+ cache_setitem(self, key, value)
+ self.__update(key)
+
+ def __delitem__(self, key, cache_delitem=Cache.__delitem__):
+ cache_delitem(self, key)
+ del self.__order[key]
+
+ def popitem(self):
+ """Remove and return the `(key, value)` pair least recently used."""
+ try:
+ key = next(iter(self.__order))
+ except StopIteration:
+ raise KeyError("%s is empty" % type(self).__name__) from None
+ else:
+ return (key, self.pop(key))
+
+ def __update(self, key):
+ try:
+ self.__order.move_to_end(key)
+ except KeyError:
+ self.__order[key] = None