From 2fd0d3ea58f74ca1b09d12204e2fb5d091dd5575 Mon Sep 17 00:00:00 2001 From: Luke Manyamazi Date: Mon, 10 Nov 2025 11:27:27 +0200 Subject: [PATCH] Implement LRU cache and tests --- Sprint-2/implement_lru_cache/lru_cache.py | 35 ++++++++++++++++ .../implement_lru_cache/lru_cache_test.py | 40 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/Sprint-2/implement_lru_cache/lru_cache.py b/Sprint-2/implement_lru_cache/lru_cache.py index e69de29..4069e12 100644 --- a/Sprint-2/implement_lru_cache/lru_cache.py +++ b/Sprint-2/implement_lru_cache/lru_cache.py @@ -0,0 +1,35 @@ +class LruCache: + def __init__(self, limit): + if limit <= 0: + raise ValueError("Limit must be greater than 0") + + self.limit = limit + self.cache = {} + self.access_order = [] # most recent at the end + + def get(self, key): + if key in self.cache: + # Move to most recent position + self.access_order.remove(key) + self.access_order.append(key) + return self.cache[key] + return None + + def set(self, key, value): + if key in self.cache: + # Update existing key + self.cache[key] = value + # Move to most recent position + self.access_order.remove(key) + self.access_order.append(key) + else: + # New key + if len(self.cache) >= self.limit: + # Remove least recently used (first item) + lru_key = self.access_order[0] + del self.cache[lru_key] + self.access_order.pop(0) + + # Add new key as most recent + self.cache[key] = value + self.access_order.append(key) \ No newline at end of file diff --git a/Sprint-2/implement_lru_cache/lru_cache_test.py b/Sprint-2/implement_lru_cache/lru_cache_test.py index d37df01..314da14 100644 --- a/Sprint-2/implement_lru_cache/lru_cache_test.py +++ b/Sprint-2/implement_lru_cache/lru_cache_test.py @@ -54,6 +54,46 @@ def test_eviction_order_after_gets(self): self.assertEqual(cache.get("a"), 1) self.assertEqual(cache.get("c"), 3) + def test_get_refreshes_item(self): + """Test that getting an item makes it recently used""" + cache = LruCache(limit=2) + + cache.set("a", 1) + cache.set("b", 2) + + # Access "a" to make it recently used + cache.get("a") + + # Add new item - should evict "b" not "a" + cache.set("c", 3) + + self.assertIsNone(cache.get("b")) # "b" was evicted + self.assertEqual(cache.get("a"), 1) # "a" remains + self.assertEqual(cache.get("c"), 3) + + def test_complex_usage_pattern(self): + """Test LRU behavior with multiple operations""" + cache = LruCache(limit=3) + + # Add initial items + cache.set("a", 1) + cache.set("b", 2) + cache.set("c", 3) + + # Use items in various order + cache.get("a") + cache.get("c") + cache.get("b") + cache.get("a") + + # Add new item - should evict least recently used ("c") + cache.set("d", 4) + + self.assertIsNone(cache.get("c")) # "c" was evicted + self.assertEqual(cache.get("a"), 1) + self.assertEqual(cache.get("b"), 2) + self.assertEqual(cache.get("d"), 4) + if __name__ == "__main__": unittest.main()