|
| 1 | +from abc import abstractmethod |
| 2 | +import sys |
| 3 | +from collections import deque |
| 4 | + |
| 5 | +class LRUCache: |
| 6 | + """ Page Replacement Algorithm, Least Recently Used (LRU) Caching.""" |
| 7 | + |
| 8 | + dq_store = object() # Cache store of keys |
| 9 | + key_reference_map = object() # References of the keys in cache |
| 10 | + _MAX_CAPACITY: int = 10 # Maximum capacity of cache |
| 11 | + |
| 12 | + @abstractmethod |
| 13 | + def __init__(self, n: int): |
| 14 | + """ Creates an empty store and map for the keys. |
| 15 | + The LRUCache is set the size n. |
| 16 | + """ |
| 17 | + self.dq_store = deque() |
| 18 | + self.key_reference_map = set() |
| 19 | + if not n: |
| 20 | + LRUCache._MAX_CAPACITY = sys.maxsize |
| 21 | + elif n < 0: |
| 22 | + raise ValueError('n should be an integer greater than 0.') |
| 23 | + else: |
| 24 | + LRUCache._MAX_CAPACITY = n |
| 25 | + |
| 26 | + def refer(self, x): |
| 27 | + """ |
| 28 | + Looks for a page in the cache store and adds reference to the set. |
| 29 | + Remove the least recently used key if the store is full. |
| 30 | + Update store to reflect recent access. |
| 31 | + """ |
| 32 | + if x not in self.key_reference_map: |
| 33 | + if len(self.dq_store) == LRUCache._MAX_CAPACITY: |
| 34 | + last_element = self.dq_store.pop() |
| 35 | + self.key_reference_map.remove(last_element) |
| 36 | + else: |
| 37 | + index_remove = 0 |
| 38 | + for idx, key in enumerate(self.dq_store): |
| 39 | + if key == x: |
| 40 | + index_remove = idx |
| 41 | + break |
| 42 | + self.dq_store.remove(index_remove) |
| 43 | + |
| 44 | + self.dq_store.appendleft(x) |
| 45 | + self.key_reference_map.add(x) |
| 46 | + |
| 47 | + def display(self): |
| 48 | + """ |
| 49 | + Prints all the elements in the store. |
| 50 | + """ |
| 51 | + for k in self.dq_store: |
| 52 | + print(k) |
| 53 | + |
| 54 | +if __name__ == "__main__": |
| 55 | + lru_cache = LRUCache(4) |
| 56 | + lru_cache.refer(1) |
| 57 | + lru_cache.refer(2) |
| 58 | + lru_cache.refer(3) |
| 59 | + lru_cache.refer(1) |
| 60 | + lru_cache.refer(4) |
| 61 | + lru_cache.refer(5) |
| 62 | + lru_cache.display() |
0 commit comments