from .cache import Cache class Node: def __init__(self, key, value): self.key = key self.value = value self.visited = False self.next = None self.prev = None class SeiveCache(Cache): def __init__(self, limit: int): super().__init__(limit) self.limit = limit # Fix: Store limit properly self.cache = {} # Hash map for O(1) access self.head = None self.tail = None self.hand = None def print_cache_state(self): print("Current cache state:") node = self.head if not node: print("Cache is empty.") return for _ in range(len(self.cache)): print(f"Key: {node.key}, Value: {node.value}, Visited: {node.visited}") node = node.next if node == self.head: break def get(self, key: str) -> str: if key in self.cache: node = self.cache[key] node.visited = True #self.print_cache_state() return node.value self.print_cache_state() return None def put(self, key: str, val: str) -> bool: if key in self.cache: node = self.cache[key] node.value = val node.visited = True #self.print_cache_state() return False # No eviction needed new_node = Node(key, val) if len(self.cache) >= self.limit: self.evict() if not self.head: self.head = self.tail = new_node new_node.next = new_node.prev = new_node else: new_node.prev = self.tail new_node.next = self.head self.tail.next = new_node self.head.prev = new_node self.tail = new_node self.cache[key] = new_node if not self.hand: self.hand = self.head #self.print_cache_state() return False def invalidate(self, key: str) -> bool: if key in self.cache: node = self.cache.pop(key) if node == self.head: self.head = node.next if node == self.tail: self.tail = node.prev if node.next: node.next.prev = node.prev if node.prev: node.prev.next = node.next #self.print_cache_state() return True return False def next_hand(self): self.hand = self.hand.next if self.hand.next else self.head def evict(self): while self.hand.visited: self.hand.visited = False self.next_hand() obj_to_evict = self.hand self.next_hand() if obj_to_evict == self.head: self.head = obj_to_evict.next if obj_to_evict == self.tail: self.tail = obj_to_evict.prev if obj_to_evict.next: obj_to_evict.next.prev = obj_to_evict.prev if obj_to_evict.prev: obj_to_evict.prev.next = obj_to_evict.next del self.cache[obj_to_evict.key] #self.print_cache_state() # Basic API demo for future testing if __name__ == "__main__": cache = SeiveCache(3) cache.put("a", "1") cache.put("b", "2") cache.put("c", "3") cache.get("a") cache.put("d", "4") # Should evict "b" assert "b" not in cache.cache, f"Eviction failed, cache contents: {cache.cache.keys()}" print("SeiveCache eviction test passed.")