算法:如何实现LRU缓存方案

1.LRU算法,意思是最近最少使用,LRU缓存就是使用这种原理实现的,简单的说缓存一定量的数据,当超过设定的阈值时就把一些缓存过期的数据删除掉。常用于页面置换算法,是虚拟页式存储管理中常用的算法。
2.我们可以使用两个数据结构实现一个LRU缓存

· 使用双向链表实现的队列,队列的最大容量为缓存的大小。在使用过程中,把最近使用的页面移动到队列头,最近没有使用的页面将被放在队列尾的位置
· 使用一个哈希表,把页号作为键,把缓存在队列中的节点的地址作为值,只需要把这个页对应的节点移动到队列的前面,如果需要的页面在内存中,此时需要把这个页面加载到内存中,简单的说,就是将一个新节点添加到队列前面,并在哈希表中跟新相应的节点地址,如果队列是满的,那么就从队尾移除一个节点,并将新节点添加到队列的前面

3.代码实现:

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

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

    def accessPage(self,pageNum):
        #page不在缓存队列中,把它缓存到队首
        if pageNum not in self.hashSet:
            self.enqueue(pageNum)
        #page已经在缓存队列中,移动到队首
        elif pageNum != self.queue[0]:
            self.queue.remove(pageNum)
            self.queue.appendleft(pageNum)

    def printQueue(self):
        while len(self.queue) > 0:
            print(self.queue.popleft())

if __name__ == '__main__':
    #设置缓存大小为3
    lru = LRU(3)
    lru.accessPage(1)
    lru.accessPage(2)
    lru.accessPage(5)
    lru.accessPage(1)
    lru.accessPage(6)
    lru.accessPage(7)
    #通过上面的访问序列后,缓存信息为
    lru.printQueue()

结果:
7
6
1

猜你喜欢

转载自blog.csdn.net/weixin_43697214/article/details/115335716