From 302e0651907048f85575758d59d2f0a0ad399269 Mon Sep 17 00:00:00 2001 From: Zobeir-Rigi Date: Mon, 6 Jul 2026 00:51:07 +0100 Subject: [PATCH 1/2] Implement LRU cache --- Sprint-2/implement_lru_cache/lru_cache.py | 89 +++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index e69de29..a31c398 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -0,0 +1,89 @@ +class Node: + def __init__(self, key, value): + self.key = key + self.value = value + self.next = None + self.previous = None + + +class LruCache: + def __init__(self, limit): + if limit <= 0: + raise ValueError("Limit must be greater than 0") + + self.limit = limit + self.cache = {} + self.head = None + self.tail = None + + def _add_to_head(self, node): + node.previous = None + node.next = self.head + + if self.head is not None: + self.head.previous = node + + self.head = node + + if self.tail is None: + self.tail = node + + def _move_to_head(self, node): + if node == self.head: + return + + if node.previous is not None: + node.previous.next = node.next + + if node.next is not None: + node.next.previous = node.previous + + if node == self.tail: + self.tail = node.previous + + node.previous = None + node.next = self.head + + if self.head is not None: + self.head.previous = node + + self.head = node + + def _remove_tail(self): + if self.tail is None: + return + + old_tail = self.tail + + if self.head == self.tail: + self.head = None + self.tail = None + else: + self.tail = old_tail.previous + self.tail.next = None + + del self.cache[old_tail.key] + + def get(self, key): + node = self.cache.get(key) + + if node is None: + return None + + self._move_to_head(node) + return node.value + + def set(self, key, value): + if key in self.cache: + node = self.cache[key] + node.value = value + self._move_to_head(node) + return + + node = Node(key, value) + + self.cache[key] = node + self._add_to_head(node) + + if len(self.cache) > self.limit: + self._remove_tail() \ No newline at end of file From 0adc4c66a086ca5de4fccf5db8f8b27b8538206f Mon Sep 17 00:00:00 2001 From: Zobeir-Rigi Date: Tue, 14 Jul 2026 18:58:30 +0100 Subject: [PATCH 2/2] Refactor LRU cache implementation --- Sprint-2/implement_lru_cache/lru_cache.py | 67 ++++++++++++----------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index a31c398..2e49853 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -6,17 +6,12 @@ def __init__(self, key, value): self.previous = None -class LruCache: - def __init__(self, limit): - if limit <= 0: - raise ValueError("Limit must be greater than 0") - - self.limit = limit - self.cache = {} +class DoublyLinkedList: + def __init__(self): self.head = None self.tail = None - def _add_to_head(self, node): + def add_to_head(self, node): node.previous = None node.next = self.head @@ -28,41 +23,45 @@ def _add_to_head(self, node): if self.tail is None: self.tail = node - def _move_to_head(self, node): - if node == self.head: - return - + def remove(self, node): if node.previous is not None: node.previous.next = node.next + else: + self.head = node.next if node.next is not None: node.next.previous = node.previous - - if node == self.tail: + else: self.tail = node.previous + node.next = None node.previous = None - node.next = self.head - if self.head is not None: - self.head.previous = node + def move_to_head(self, node): + if node == self.head: + return - self.head = node + self.remove(node) + self.add_to_head(node) - def _remove_tail(self): + def remove_tail(self): if self.tail is None: - return + return None - old_tail = self.tail + node = self.tail + self.remove(node) - if self.head == self.tail: - self.head = None - self.tail = None - else: - self.tail = old_tail.previous - self.tail.next = None + return node + + +class LruCache: + def __init__(self, limit): + if limit <= 0: + raise ValueError("Limit must be greater than 0") - del self.cache[old_tail.key] + self.limit = limit + self.cache = {} + self.items = DoublyLinkedList() def get(self, key): node = self.cache.get(key) @@ -70,20 +69,24 @@ def get(self, key): if node is None: return None - self._move_to_head(node) + self.items.move_to_head(node) + return node.value def set(self, key, value): if key in self.cache: node = self.cache[key] node.value = value - self._move_to_head(node) + self.items.move_to_head(node) return node = Node(key, value) self.cache[key] = node - self._add_to_head(node) + self.items.add_to_head(node) if len(self.cache) > self.limit: - self._remove_tail() \ No newline at end of file + old_node = self.items.remove_tail() + + if old_node is not None: + del self.cache[old_node.key]