Fixed Sieve key not found error, Added test results for sieve

This commit is contained in:
isha28-uclaCS
2025-03-07 19:21:39 -08:00
parent bb38d1eeb4
commit 88be00d210
2 changed files with 87 additions and 59 deletions

View File

@@ -11,45 +11,49 @@ class Node:
class SieveCache(Cache):
def __init__(self, limit: int):
super().__init__(limit)
self.limit = limit # Fix: Store limit properly
self.limit = limit
self.cache = {} # Hash map for O(1) access
self.head = None
self.tail = None
self.hand = None
self.hand = None # Pointer for eviction
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
def invalidate(self, key: str) -> bool:
"""Removes a specific key from cache if it exists."""
if key in self.cache:
node = self.cache.pop(key)
if node == self.head:
break
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
return True # Successfully invalidated
return False # Key not found
def get(self, key: str) -> str:
if key in self.cache:
node = self.cache[key]
node.visited = True
#self.print_cache_state()
node.visited = True # Mark node as accessed
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()
# Insert new node in circular doubly linked list
if not self.head:
self.head = self.tail = new_node
new_node.next = new_node.prev = new_node
@@ -62,54 +66,31 @@ class SieveCache(Cache):
self.cache[key] = new_node
if not self.hand:
self.hand = self.head
#self.print_cache_state()
self.hand = self.head # Initialize hand pointer
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):
if not self.hand:
return # No elements to evict
# Find the first unvisited node to evict
while self.hand.visited:
self.hand.visited = False
self.next_hand()
self.hand.visited = False # Reset visited flag
self.hand = self.hand.next # Move to next node
obj_to_evict = self.hand
self.next_hand()
self.hand = self.hand.next # Move hand forward
# Remove from cache dictionary if exists
if obj_to_evict.key in self.cache:
del self.cache[obj_to_evict.key]
# Evict the node from linked list
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.")
obj_to_evict.prev.next = obj_to_evict.next
obj_to_evict.next.prev = obj_to_evict.prev