2.8python如何实现LRU缓存方案

题目描述:

LRU是 Least Recently Used 的缩写,指“最近最少使用”,LRU环存就是使用这种原理实现,简单地说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉。常用于页面置换算法,是虚拟页式存储管理中常用的算法。

思路:
使用两个数据结构实现一个LRU环存:
(1) 使用双向链表实现的队列,队列的最大容量为缓存的大小。在使用的过程中,把最近使用的页面移动到队列头,最近没有使用的页面将被放在队列尾的位置
(2) 使用一个哈希表,把页号作为键,把缓存在队列中的结点的地址作为值;(不是很理解为什么要用一个哈希表,下面代码中未使用哈希表,仅是使用了一个双向的队列)
当引用一个页面时,如果所需的页面在内存中,只需要把这个页对应的结点移动到队列的前面。如果所需要的页面不在内存中,此时需要把这个页面加载到内存中。简单地说,就是将一个新结点添加到队列的前面(最近使用),并在哈希表中更新相应的结点地址。如果队列是满的,那么就从队列尾部移除一个结点(队尾表示距离现在久远),并将新结点添加到队列的前面(队头表示现在,队尾表示过去)。

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/22 16:53
# @Author  : buu
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/weixin_44321080
from collections import deque


class LRU:
    def __init__(self, cacheSize):
        self.cacheSize = cacheSize  # 要缓存的数据大小
        self.queue = deque()
        # self.hashSet = set()

    def isQueueFull(self):  # 判断缓存队列是否满
        return len(self.queue) == self.cacheSize

    def enQueue(self, pageNum):  # 把页号为 pageNum 的页缓存到队列中,同时也添加到 Hash 表中
        if self.isQueueFull():  # 如果队列满了,则需要删除队尾的缓存的页
            # self.hashSet.remove(self.queue[-1])
            self.queue.pop()
        self.queue.appendleft(pageNum)
        # self.hashSet.add(pageNum)  # 把新缓存的结点同时添加到 hash 表中

    def accessPage(self, pageNum):
        """
        当访问某一个page的时候会调用此函数,对于访问的page有两种情况:
        1. 如果page在缓存队列中,直接把这个结点移动到队首;
        2. 如果page不在缓存队列中,则把这个page缓存到队首;
        :param pageNum:
        :return:
        """
        if pageNum not in self.queue:  # page不在缓存队列中,则把它缓存到队首
            self.enQueue(pageNum)
        elif pageNum != self.queue[0]:  # page在缓存队列中,则移动到队首
            self.queue.remove(pageNum)
            self.queue.appendleft(pageNum)

    def printQueue(self):
        while len(self.queue) > 0:
            print(self.queue.popleft(), end=' ')


if __name__ == '__main__':
    lru = LRU(3)  # 假设缓存大小为3
    lru.accessPage(1) # 队列:1
    lru.accessPage(2) # 队列:2,1
    lru.accessPage(5) # 队列:5,2,1
    lru.accessPage(1) # 队列:1,5,2,因为1在队列中了,所以移到队首
    lru.accessPage(6) # 队列:6,1,5
    lru.accessPage(7) # 队列:7,6,1
    lru.printQueue()  # 通过上面的访问序列后,打印缓存的信息

结果:
在这里插入图片描述

end

发布了76 篇原创文章 · 获赞 2 · 访问量 2564

猜你喜欢

转载自blog.csdn.net/weixin_44321080/article/details/104067703
今日推荐