redis 缓存淘汰策略LRU算法实现
Lru,就是将缓存中近期不经常使用的记录进行淘汰清理。
import collections
class LRUCache():
def __init__(self, capacity):
self.capacity = capacity
self.dc = collections.OrderedDict()
def get(self, key) -> int:
if key not in self.dc:
return -1
self.dc.move_to_end(key)
return self.dc.get(key)
def put(self, key, value):
if key in self.dc:
self.dc.move_to_end(key)
self.dc[key] = value
if len(self.dc) > self.capacity:
self.dc.popitem(last=False)
上面用到了有序字典 OrderdDict(), 实现起来非常方便,要注意的就是明白move_to_end 及 popitem(last=False) 两个函数,其他使用方式和dict类似。
move_to_end(key) 将key的键值对移动到有序队列的末尾
popitem() last=False 就表示先进先出,last=True表示后进先出。
当然使用collections之前也写了list版本的,如下:
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.queues = []
def get(self, key: int) -> int:
val = -1
tmp = []
flag = False
for k, v in enumerate(self.queues):
if key in v.keys():
val = v.get(key)
self.queues.pop(k)
flag = True
break
if flag:
self.queues = [{key: val}] + self.queues
print(self.queues)
return val
else:
return -1
def put(self, key: int, value: int) -> None:
if self.capacity == len(self.queues):
# 满了
if self.get(key) == -1:
self.queues.pop(-1)
self.queues = [{key: value}] + self.queues
else:
# 存在并更新
for q in range(len(self.queues)):
if key in self.queues[q].keys():
self.queues[q] = {key: value}
else:
# self.queues.append({key: value})
if self.get(key) == -1:
# 不存在插入
self.queues = [{key: value}] + self.queues
else:
# 存在并更新
for q in range(len(self.queues)):
if key in self.queues[q].keys():
self.queues[q] = {key: value}
不建议使用,贴出来主要是方便理解。