TheAlgorithms-Python
92 строки · 2.4 Кб
1from __future__ import annotations
2
3import sys
4from collections import deque
5from typing import Generic, TypeVar
6
7T = TypeVar("T")
8
9
10class LRUCache(Generic[T]):
11"""
12Page Replacement Algorithm, Least Recently Used (LRU) Caching.
13
14>>> lru_cache: LRUCache[str | int] = LRUCache(4)
15>>> lru_cache.refer("A")
16>>> lru_cache.refer(2)
17>>> lru_cache.refer(3)
18
19>>> lru_cache
20LRUCache(4) => [3, 2, 'A']
21
22>>> lru_cache.refer("A")
23>>> lru_cache
24LRUCache(4) => ['A', 3, 2]
25
26>>> lru_cache.refer(4)
27>>> lru_cache.refer(5)
28>>> lru_cache
29LRUCache(4) => [5, 4, 'A', 3]
30
31"""
32
33dq_store: deque[T] # Cache store of keys
34key_reference: set[T] # References of the keys in cache
35_MAX_CAPACITY: int = 10 # Maximum capacity of cache
36
37def __init__(self, n: int) -> None:
38"""Creates an empty store and map for the keys.
39The LRUCache is set the size n.
40"""
41self.dq_store = deque()
42self.key_reference = set()
43if not n:
44LRUCache._MAX_CAPACITY = sys.maxsize
45elif n < 0:
46raise ValueError("n should be an integer greater than 0.")
47else:
48LRUCache._MAX_CAPACITY = n
49
50def refer(self, x: T) -> None:
51"""
52Looks for a page in the cache store and adds reference to the set.
53Remove the least recently used key if the store is full.
54Update store to reflect recent access.
55"""
56if x not in self.key_reference:
57if len(self.dq_store) == LRUCache._MAX_CAPACITY:
58last_element = self.dq_store.pop()
59self.key_reference.remove(last_element)
60else:
61self.dq_store.remove(x)
62
63self.dq_store.appendleft(x)
64self.key_reference.add(x)
65
66def display(self) -> None:
67"""
68Prints all the elements in the store.
69"""
70for k in self.dq_store:
71print(k)
72
73def __repr__(self) -> str:
74return f"LRUCache({self._MAX_CAPACITY}) => {list(self.dq_store)}"
75
76
77if __name__ == "__main__":
78import doctest
79
80doctest.testmod()
81
82lru_cache: LRUCache[str | int] = LRUCache(4)
83lru_cache.refer("A")
84lru_cache.refer(2)
85lru_cache.refer(3)
86lru_cache.refer("A")
87lru_cache.refer(4)
88lru_cache.refer(5)
89lru_cache.display()
90
91print(lru_cache)
92assert str(lru_cache) == "LRUCache(4) => [5, 4, 'A', 3]"
93