From 65cbc752f5440183b0cbcd63105fa0540dcb0470 Mon Sep 17 00:00:00 2001 From: shaghayeghfar <146011477+shaghayeghfar@users.noreply.github.com> Date: Wed, 14 Oct 2026 10:19:06 +0100 Subject: [PATCH 1/2] Implement LRU cache is completed --- Sprint-2/implement_lru_cache/lru_cache.py | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index e69de29b..cd43c068 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -0,0 +1,71 @@ +class Node: + def __init__(self, key, value): + self.key = key + self.value = value + self.previous = None + self.next = None + + +class LruCache: + def __init__(self, limit): + if limit <= 0: + raise ValueError("Limit must be greater than zero") + + self.limit = limit + self.cache = {} + + # Most recently used node is near the head. + # Least recently used node is near the tail. + self.head = Node(None, None) + self.tail = Node(None, None) + + self.head.next = self.tail + self.tail.previous = self.head + + def remove_node(self, node): + # Connect the node's neighbours to each other. + node.previous.next = node.next + node.next.previous = node.previous + + def add_to_front(self, node): + # Insert the node immediately after the head. + node.next = self.head.next + node.previous = self.head + + self.head.next.previous = node + self.head.next = node + + def get(self, key): + if key not in self.cache: + return None + + node = self.cache[key] + + # Using a value makes it the most recently used. + self.remove_node(node) + self.add_to_front(node) + + return node.value + + def set(self, key, value): + # If the key already exists, update its value. + if key in self.cache: + node = self.cache[key] + node.value = value + + self.remove_node(node) + self.add_to_front(node) + return + + # If the cache is full, remove the least recently used node. + if len(self.cache) >= self.limit: + oldest_node = self.tail.previous + + self.remove_node(oldest_node) + del self.cache[oldest_node.key] + + # Create the new node and add it to the front. + new_node = Node(key, value) + + self.cache[key] = new_node + self.add_to_front(new_node) From 029cdd8c3c3b7f4dcea90edf9aa006dd3ba21b83 Mon Sep 17 00:00:00 2001 From: shaghayeghfar <146011477+shaghayeghfar@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:05:45 +0100 Subject: [PATCH 2/2] changes were done --- Sprint-2/implement_lru_cache/lru_cache.py | 57 +++++++++++------------ 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index cd43c068..9613d148 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -1,3 +1,4 @@ + class Node: def __init__(self, key, value): self.key = key @@ -6,66 +7,64 @@ def __init__(self, key, value): self.next = None -class LruCache: - def __init__(self, limit): - if limit <= 0: - raise ValueError("Limit must be greater than zero") - - self.limit = limit - self.cache = {} - - # Most recently used node is near the head. - # Least recently used node is near the tail. +class DoublyLinkedList: + def __init__(self): self.head = Node(None, None) self.tail = Node(None, None) self.head.next = self.tail self.tail.previous = self.head - def remove_node(self, node): - # Connect the node's neighbours to each other. - node.previous.next = node.next - node.next.previous = node.previous - def add_to_front(self, node): - # Insert the node immediately after the head. node.next = self.head.next node.previous = self.head self.head.next.previous = node self.head.next = node + def remove(self, node): + node.previous.next = node.next + node.next.previous = node.previous + + def remove_last(self): + node = self.tail.previous + self.remove(node) + return node + + +class LruCache: + def __init__(self, limit): + if limit <= 0: + raise ValueError("Limit must be greater than zero") + + self.limit = limit + self.cache = {} + self.order = DoublyLinkedList() + def get(self, key): if key not in self.cache: return None node = self.cache[key] - # Using a value makes it the most recently used. - self.remove_node(node) - self.add_to_front(node) + self.order.remove(node) + self.order.add_to_front(node) return node.value def set(self, key, value): - # If the key already exists, update its value. if key in self.cache: node = self.cache[key] node.value = value - self.remove_node(node) - self.add_to_front(node) + self.order.remove(node) + self.order.add_to_front(node) return - # If the cache is full, remove the least recently used node. if len(self.cache) >= self.limit: - oldest_node = self.tail.previous - - self.remove_node(oldest_node) + oldest_node = self.order.remove_last() del self.cache[oldest_node.key] - # Create the new node and add it to the front. new_node = Node(key, value) - self.cache[key] = new_node - self.add_to_front(new_node) + self.order.add_to_front(new_node)