LRU(Least Recently Used)最近最少使用-P

2021-09-13  本文已影响0人  ShowMeCoding
LRU缓存

假设:长期不被使用的数据,在未来不被使用到的几率也不大。因此,当数据所占内存达到一定阈值时,我们就要移除掉最近最少使用的数据。

数据结构:哈希链表
哈希表由若干个Key-value组成,在“逻辑上”,这些key-value无所谓排列顺序,谁先谁后都一样

哈希表

哈希链表中,这些Key-value不再是彼此无关的存在,而是被一个链条串了起来,每一个key-value都具有它的前驱、后继,就像双向链表中的节点一样。使原本无序的哈希表变得有序。

哈希链表
class LRUCache(collections.OrderedDict):

    def __init__(self, capacity: int):
        super().__init__()
        self.capacity = capacity


    def get(self, key: int) -> int:
        if key not in self:
            return -1
        self.move_to_end(key)
        return self[key]

    def put(self, key: int, value: int) -> None:
        if key in self:
            self.move_to_end(key)
        self[key] = value
        if len(self) > self.capacity:
            self.popitem(last=False)

使用双向链表,存储具体的值,链表的最大容量为缓存的大小;
使用哈希表,其中键用于存储页号,值用于存储链表的地址
1、访问:
1.1 所需页面不存在内存中,返回 -1
1.2 所需页面在内存中,把最近使用的页面移动到链表的头部,把最近没有使用的页面放到链表的尾部
2、缓存:
2.1 被添加的元素已存在 更新元素值并已到链表头部
2.2 被添加的元素不存在
2.2.1 链表容量达到上限 删除尾部元素
2.2.2 链表容量未达上限 添加至链表头部

class Node:
    def __init__(self, key=0, value=0):
        self.key = key
        self.value = value
        self.prev = None
        self.next = None
    
    def remove_this(self):
        if self.prev:
            self.prev.next = self.next
        if self.next:    
            self.next.prev = self.prev
        self.prev = None
        self.next = None
        return self.key
    
    def put_prev(self, Node):
        Node.prev = self.prev
        self.prev.next = Node
        self.prev = Node
        Node.next = self
    
       
class LRUCache: # 哈希链表

    def __init__(self, capacity: int):
        self.dict = dict()
        self.capacity=capacity
        self.cur_num = 0
        self.head = Node(0,0)
        self.tail = Node(0,0)

        self.head.next = self.tail
        self.tail.prev = self.head

    def get(self, key: int) -> int:
        if key not in self.dict.keys():
            return -1
        else:
            cur_node = self.dict[key]
            cur_node.remove_this()
            self.tail.put_prev(cur_node)
            return cur_node.value

    def put(self, key: int, value: int) -> None:
        cur_node = Node(key, value)
        if key in self.dict.keys():
            self.dict[key].remove_this()
            self.dict[key] = cur_node
            self.tail.put_prev(cur_node)
        elif self.cur_num < self.capacity:        
            self.tail.put_prev(cur_node)
            self.dict[key] = cur_node
            self.cur_num += 1                 
        else:
            del_key = self.head.next.remove_this()
            del self.dict[del_key]
            self.tail.put_prev(cur_node)
            self.dict[key] = cur_node
        return
上一篇下一篇

猜你喜欢

热点阅读