-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy path100-lfu_cache.py
executable file
·54 lines (47 loc) · 1.65 KB
/
100-lfu_cache.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/python3
"""LFU Cache Replacement Implementation Class
"""
from threading import RLock
BaseCaching = __import__('base_caching').BaseCaching
class LFUCache(BaseCaching):
"""
An implementaion of LFUCache(Least frequently used)
Attributes:
__stats (list): A dictionary of cache keys for access count
__rlock (RLock): Lock accessed resources to prevent race condition
"""
def __init__(self):
""" Instantiation method, sets instance attributes
"""
super().__init__()
self.__stats = {}
self.__rlock = RLock()
def put(self, key, item):
""" Add an item in the cache
"""
if key is not None and item is not None:
keyOut = self._balance(key)
with self.__rlock:
self.cache_data.update({key: item})
if keyOut is not None:
print('DISCARD: {}'.format(keyOut))
def get(self, key):
""" Get an item by key
"""
with self.__rlock:
value = self.cache_data.get(key, None)
if key in self.__stats:
self.__stats[key] += 1
return value
def _balance(self, keyIn):
""" Removes the earliest item from the cache at MAX size
"""
keyOut = None
with self.__rlock:
if keyIn not in self.__stats:
if len(self.cache_data) == BaseCaching.MAX_ITEMS:
keyOut = min(self.__stats, key=self.__stats.get)
self.cache_data.pop(keyOut)
self.__stats.pop(keyOut)
self.__stats[keyIn] = self.__stats.get(keyIn, 0) + 1
return keyOut