From 1908cab67b6cd7fe94cbc3b912443a76a3a94305 Mon Sep 17 00:00:00 2001 From: pathywang Date: Sun, 4 Oct 2026 05:26:09 +0100 Subject: [PATCH 1/3] complete lru-cache --- Sprint-2/implement_lru_cache/lru_cache.py | 73 +++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index e69de29b..1cede8c1 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -0,0 +1,73 @@ +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 + + self.limit = limit + self.cache = {} + self.head = None + self.tail = None + + def _remove_node(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 + else: + self.tail = node.previous + + def _add_to_tail(self, node): + node.next = None + node.previous = self.tail + + if self.tail is not None: + self.tail.next = node + else: + self.head = node + + self.tail = node + + def get(self, key): + if key not in self.cache: + return None + + node = self.cache[key] + + # Move node to the most-recently-used position + if node is not self.tail: + self._remove_node(node) + self._add_to_tail(node) + + return node.value + + def set(self, key, value): + if key in self.cache: + node = self.cache[key] + node.value = value + + # Updating an item counts as using it + if node is not self.tail: + self._remove_node(node) + self._add_to_tail(node) + + return + + node = Node(key, value) + self.cache[key] = node + self._add_to_tail(node) + + if len(self.cache) > self.limit: + lru_node = self.head + + self._remove_node(lru_node) + del self.cache[lru_node.key] \ No newline at end of file From 0ceb2d1bee4bdc60a7cadba5ffec3ef2e59eabf4 Mon Sep 17 00:00:00 2001 From: pathywang Date: Fri, 9 Oct 2026 22:21:41 +0100 Subject: [PATCH 2/3] copy file --- Sprint-2/implement_lru_cache/linked_list.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Sprint-2/implement_lru_cache/linked_list.py diff --git a/Sprint-2/implement_lru_cache/linked_list.py b/Sprint-2/implement_lru_cache/linked_list.py new file mode 100644 index 00000000..e69de29b From 181c2bfb2ab407378be7c932bd7d098babc5aa2d Mon Sep 17 00:00:00 2001 From: pathywang Date: Fri, 9 Oct 2026 22:37:26 +0100 Subject: [PATCH 3/3] seperate class --- Sprint-2/implement_lru_cache/linked_list.py | 55 ++++++++++++++++ Sprint-2/implement_lru_cache/lru_cache.py | 70 ++++++--------------- 2 files changed, 73 insertions(+), 52 deletions(-) diff --git a/Sprint-2/implement_lru_cache/linked_list.py b/Sprint-2/implement_lru_cache/linked_list.py index e69de29b..5999a955 100644 --- a/Sprint-2/implement_lru_cache/linked_list.py +++ b/Sprint-2/implement_lru_cache/linked_list.py @@ -0,0 +1,55 @@ +class Node: + __slots__ = ("value", "next", "previous") + + def __init__(self, value): + self.value = value + self.next = None + self.previous = None + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + + def push_head(self, value): + node = Node(value) + + if self.head is None: + self.head = node + self.tail = node + else: + node.next = self.head + self.head.previous = node + self.head = node + + return node + + def pop_tail(self): + node = self.tail + + if node is None: + return None + + self.remove(node) + + return node.value + + def remove(self, node): + if node == self.head and node == self.tail: + self.head = None + self.tail = None + + elif node == self.head: + self.head = node.next + self.head.previous = None + + elif node == self.tail: + self.tail = node.previous + self.tail.next = None + + else: + node.previous.next = node.next + node.next.previous = node.previous + + node.next = None + node.previous = None \ No newline at end of file diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index 1cede8c1..8e782bdf 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -1,73 +1,39 @@ -class Node: - def __init__(self, key, value): - self.key = key - self.value = value - self.next = None - self.previous = None +from linked_list import LinkedList + class LruCache: def __init__(self, limit): if limit <= 0: - raise ValueError + raise ValueError("Limit must be greater than zero") self.limit = limit self.cache = {} - self.head = None - self.tail = None - - def _remove_node(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 - else: - self.tail = node.previous - - def _add_to_tail(self, node): - node.next = None - node.previous = self.tail - - if self.tail is not None: - self.tail.next = node - else: - self.head = node - - self.tail = node + self.order = LinkedList() def get(self, key): if key not in self.cache: return None node = self.cache[key] + value = node.value[1] - # Move node to the most-recently-used position - if node is not self.tail: - self._remove_node(node) - self._add_to_tail(node) + # Move the accessed item to the head. + self.order.remove(node) + new_node = self.order.push_head(node.value) + self.cache[key] = new_node - return node.value + return value def set(self, key, value): if key in self.cache: node = self.cache[key] - node.value = value - - # Updating an item counts as using it - if node is not self.tail: - self._remove_node(node) - self._add_to_tail(node) - - return - - node = Node(key, value) - self.cache[key] = node - self._add_to_tail(node) + self.order.remove(node) - if len(self.cache) > self.limit: - lru_node = self.head + elif len(self.cache) >= self.limit: + # Remove the least recently used item. + lru_item = self.order.pop_tail() + del self.cache[lru_item[0]] - self._remove_node(lru_node) - del self.cache[lru_node.key] \ No newline at end of file + # Add the item to the head as most recently used. + node = self.order.push_head((key, value)) + self.cache[key] = node \ No newline at end of file