FIFO缓存置换算法 FIFO(First in First out),先进先出。核心原则就是:如果一个数据最先进入缓存中,则应该最早淘汰掉。也就是说,当缓存满的时候,应当把最先进入缓存的数据给淘汰掉,使用python
进行了简单实现,注意:其中用到的Node
和DoubleLinkList
为博客中《《双向链表的原理与实践》》所使用的示例
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 55 56 57 58 59 60 61 62 63 class FIFOCache (object ): def __init__ (self, capacity ): self.capacity = capacity self.size = 0 self.map = {} self.list = DoubleLinkList(self.capacity) def get (self, key ): if key not in self.map : return -1 else : node = self.map .get(key) return node.value def put (self, key, value ): if self.capacity == 0 : return if key in self.map : node = self.map .get(key) self.list .remove(node) node.value = value self.list .append(node) else : if self.size == self.capacity: node = self.list .pop() del self.map [node.key] self.size -= 1 node = Node(key, value) self.list .append(node) self.map [key] = node self.size += 1 def print (self ): self.list .print() if __name__ == '__main__' : fifoCache = FIFOCache(2 ) fifoCache.put(1 , 1 ) fifoCache.print() fifoCache.put(2 , 2 ) fifoCache.print() print(fifoCache.get(1 )) fifoCache.put(1 , 3 ) fifoCache.print() fifoCache.put(4 , 4 ) fifoCache.print() print(fifoCache.get(2 ))
LRU缓存置换算法 LRU(Least Recently Used)最近最少使用,原理就是,当数据在最近一段时间经常被访问,那么它在以后也会经常被访问。这就意味着,如果经常访问的数据,我们需要然其能够快速命中,而不常访问的数据,我们在容量超出限制内,要将其淘汰。
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 55 56 57 class LRUCache (object ): def __init__ (self, capacity ): self.capacity = capacity self.map = {} self.list = DoubleLinkList(self.capacity) def get (self, key ): if key not in self.map : return -1 node = self.map .get(key) self.list .remove(node) self.list .append_front(node) return node.value def put (self, key, value ): if key in self.map : node = self.map [key] self.list .remove(node) node.value = value self.map [key] = node self.list .append_front(node) else : node = Node(key, value) if self.list .size >= self.list .capacity: old_node = self.list .remove() self.map .pop(old_node.key) self.map [key] = node self.list .append_front(node) def print (self ): self.list .print() if __name__ == '__main__' : cache = LRUCache(2 ) cache.put(2 , 2 ) cache.print() cache.put(1 , 1 ) cache.print() print(cache.get(1 )) cache.print() cache.put(3 , 3 ) cache.print() print(cache.get(1 )) cache.print()
LFU缓存置换算法 最少使用置换算法基于“如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小”的思路,和LRU的区别是LFU是基于访问次数的,即如果一个元素访问的次数足够多,即使一段时间不访问,也有可能不会被删除,而LRU会把时间上最久没被访问的数据删除
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 from computer_principle.DoubleLinkedList import DoubleLinkList, Nodeclass LFUNode (Node ): def __init__ (self, key, value ): self.freq = 0 super (LFUNode, self).__init__(key, value) class LFUCache (object ): def __init__ (self, capacity ): self.capacity = capacity self.map = {} self.freq_map = {} self.size = 0 def __update_freq (self, node ): freq = node.freq node = self.freq_map[freq].remove(node) if self.freq_map[freq].size == 0 : del self.freq_map[freq] freq += 1 node.freq = freq if freq not in self.freq_map: self.freq_map[freq] = DoubleLinkList() self.freq_map[freq].append(node) def get (self, key ): if key not in self.map : return -1 node = self.map .get(key) self.__update_freq(node) return node.value def put (self, key, value ): if self.capacity == 0 : return if key in self.map : node = self.map .get(key) self.__update_freq(node) node.value = value else : if self.size == self.capacity: min_freq = min (self.freq_map) old_node = self.freq_map[min_freq].pop() del self.map [old_node.key] self.size -= 1 node = LFUNode(key, value) node.freq = 1 self.map [key] = node if node.freq not in self.freq_map: self.freq_map[node.freq] = DoubleLinkList() self.freq_map[node.freq].append(node) self.size += 1 def print (self ): print('*******************************' ) for k, v in self.freq_map.items(): print('Freq = %d' % k) self.freq_map[k].print() print('*******************************' ) if __name__ == '__main__' : cache = LFUCache(4 ) cache.put(1 , 1 ) cache.put(2 , 1 ) cache.put(3 , 1 ) cache.put(4 , 1 ) cache.print() print(cache.get(1 )) print(cache.get(2 )) cache.put(5 , 1 ) cache.print()