mirror of
https://github.com/ltcptgeneral/cs239-caching.git
synced 2025-04-01 12:33:25 +00:00
Fixed Sieve key not found error, Added test results for sieve
This commit is contained in:
parent
bb38d1eeb4
commit
88be00d210
99
app/cache/eviction_sieve.py
vendored
99
app/cache/eviction_sieve.py
vendored
@ -11,45 +11,49 @@ class Node:
|
|||||||
class SieveCache(Cache):
|
class SieveCache(Cache):
|
||||||
def __init__(self, limit: int):
|
def __init__(self, limit: int):
|
||||||
super().__init__(limit)
|
super().__init__(limit)
|
||||||
self.limit = limit # Fix: Store limit properly
|
self.limit = limit
|
||||||
self.cache = {} # Hash map for O(1) access
|
self.cache = {} # Hash map for O(1) access
|
||||||
self.head = None
|
self.head = None
|
||||||
self.tail = None
|
self.tail = None
|
||||||
self.hand = None
|
self.hand = None # Pointer for eviction
|
||||||
|
|
||||||
def print_cache_state(self):
|
def invalidate(self, key: str) -> bool:
|
||||||
#print("Current cache state:")
|
"""Removes a specific key from cache if it exists."""
|
||||||
node = self.head
|
if key in self.cache:
|
||||||
if not node:
|
node = self.cache.pop(key)
|
||||||
#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:
|
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:
|
def get(self, key: str) -> str:
|
||||||
if key in self.cache:
|
if key in self.cache:
|
||||||
node = self.cache[key]
|
node = self.cache[key]
|
||||||
node.visited = True
|
node.visited = True # Mark node as accessed
|
||||||
#self.print_cache_state()
|
|
||||||
return node.value
|
return node.value
|
||||||
self.print_cache_state()
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def put(self, key: str, val: str) -> bool:
|
def put(self, key: str, val: str) -> bool:
|
||||||
if key in self.cache:
|
if key in self.cache:
|
||||||
node = self.cache[key]
|
node = self.cache[key]
|
||||||
node.value = val
|
node.value = val
|
||||||
node.visited = True
|
node.visited = True
|
||||||
#self.print_cache_state()
|
|
||||||
return False # No eviction needed
|
return False # No eviction needed
|
||||||
|
|
||||||
new_node = Node(key, val)
|
new_node = Node(key, val)
|
||||||
if len(self.cache) >= self.limit:
|
if len(self.cache) >= self.limit:
|
||||||
self.evict()
|
self.evict()
|
||||||
|
|
||||||
|
# Insert new node in circular doubly linked list
|
||||||
if not self.head:
|
if not self.head:
|
||||||
self.head = self.tail = new_node
|
self.head = self.tail = new_node
|
||||||
new_node.next = new_node.prev = new_node
|
new_node.next = new_node.prev = new_node
|
||||||
@ -62,54 +66,31 @@ class SieveCache(Cache):
|
|||||||
|
|
||||||
self.cache[key] = new_node
|
self.cache[key] = new_node
|
||||||
if not self.hand:
|
if not self.hand:
|
||||||
self.hand = self.head
|
self.hand = self.head # Initialize hand pointer
|
||||||
#self.print_cache_state()
|
|
||||||
return False
|
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):
|
def evict(self):
|
||||||
|
if not self.hand:
|
||||||
|
return # No elements to evict
|
||||||
|
|
||||||
|
# Find the first unvisited node to evict
|
||||||
while self.hand.visited:
|
while self.hand.visited:
|
||||||
self.hand.visited = False
|
self.hand.visited = False # Reset visited flag
|
||||||
self.next_hand()
|
self.hand = self.hand.next # Move to next node
|
||||||
|
|
||||||
obj_to_evict = self.hand
|
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:
|
if obj_to_evict == self.head:
|
||||||
self.head = obj_to_evict.next
|
self.head = obj_to_evict.next
|
||||||
if obj_to_evict == self.tail:
|
if obj_to_evict == self.tail:
|
||||||
self.tail = obj_to_evict.prev
|
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
|
obj_to_evict.prev.next = obj_to_evict.next
|
||||||
if __name__ == "__main__":
|
obj_to_evict.next.prev = obj_to_evict.prev
|
||||||
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.")
|
|
||||||
|
47
tests/results_sieve
Normal file
47
tests/results_sieve
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
--- random_read Results ---
|
||||||
|
hits: 1019 misses: 8981 ratio: 0.1019
|
||||||
|
average response time (ms) : 13.882123780250549
|
||||||
|
average cache hit response time (ms) : 0.0010722986732310707
|
||||||
|
average cache miss response time (ms): 15.457092209125651
|
||||||
|
cache throughput (requests / s) : 72.03508741383314
|
||||||
|
real throughput (requests / s) : 63.77470400544125
|
||||||
|
|
||||||
|
--- read_heavy Results ---
|
||||||
|
hits: 803 misses: 7222 ratio: 0.10006230529595016
|
||||||
|
average response time (ms) : 13.242761249482818
|
||||||
|
average cache hit response time (ms) : 0.000984849846674823
|
||||||
|
average cache miss response time (ms): 14.715088367858312
|
||||||
|
cache throughput (requests / s) : 75.51295240930618
|
||||||
|
real throughput (requests / s) : 58.581188594379874
|
||||||
|
|
||||||
|
--- write_heavy Results ---
|
||||||
|
hits: 210 misses: 1808 ratio: 0.10406342913776016
|
||||||
|
average response time (ms) : 12.672739766161554
|
||||||
|
average cache hit response time (ms) : 0.0010308765229724702
|
||||||
|
average cache miss response time (ms): 14.14456436064391
|
||||||
|
cache throughput (requests / s) : 78.9095348324106
|
||||||
|
real throughput (requests / s) : 24.94878943653593
|
||||||
|
|
||||||
|
--- frequent_users Results ---
|
||||||
|
hits: 7235 misses: 2765 ratio: 0.7235
|
||||||
|
average response time (ms) : 4.018647408485412
|
||||||
|
average cache hit response time (ms) : 0.0006961427067754675
|
||||||
|
average cache miss response time (ms): 14.532165458361883
|
||||||
|
cache throughput (requests / s) : 248.83994497464258
|
||||||
|
real throughput (requests / s) : 181.31597211320386
|
||||||
|
|
||||||
|
--- frequent_after_write Results ---
|
||||||
|
hits: 1103 misses: 3827 ratio: 0.22373225152129816
|
||||||
|
average response time (ms) : 11.080196082712913
|
||||||
|
average cache hit response time (ms) : 0.0008352215681309497
|
||||||
|
average cache miss response time (ms): 14.273437532893913
|
||||||
|
cache throughput (requests / s) : 90.2511104077101
|
||||||
|
real throughput (requests / s) : 50.809783230994924
|
||||||
|
|
||||||
|
--- weighted_friend_readonly Results ---
|
||||||
|
hits: 3403 misses: 6597 ratio: 0.3403
|
||||||
|
average response time (ms) : 9.799546551704406
|
||||||
|
average cache hit response time (ms) : 0.000995711092033913
|
||||||
|
average cache miss response time (ms): 14.854036245596161
|
||||||
|
cache throughput (requests / s) : 102.04553799747733
|
||||||
|
real throughput (requests / s) : 86.61266112308168
|
Loading…
x
Reference in New Issue
Block a user