简单LRU cache 实现
来源:互联网 发布:淘宝上信用卡套现吗 编辑:程序博客网 时间:2024/05/22 11:20
起因:我的同事需要一个固定大小的cache,如果记录在cache中,直接从cache中读取,否则从数据库中读取。python的dict 是一个非常简单的cache,但是由于数据量很大,内存很可能增长的过大,因此需要限定记录数,并用LRU算法丢弃旧记录。key 是整型,value是10KB左右的python对象
分析:
1)可以想到,在对于cache,我们需要维护 key -> value 的关系
2)而为了实现LRU,我们又需要一个基于时间的优先级队列,来维护 timestamp -> (key, value) 的关系
3)当cache 中的记录数达到一个上界maxsize时,需要将timestamp 最小的(key,value) 出队列
4) 当一个(key, value) 被命中时,实际上我们需要将它从队列中,移除并插入到队列的尾部。
从分析可以看出我们的cache 要达到性能最优需要满足上面的四项功能,对于队表的快速移除和插入,链表显然是最优的选择,为了快速移除,最好使用双向链表,为了插入尾部,需要有指向尾部的指针。
下面用python 来实现
#encoding=utf-8class LRUCache(object): def __init__(self, maxsize): # cache 的最大记录数 self.maxsize = maxsize # 用于真实的存储数据 self.inner_dd = {} # 链表-头指针 self.head = None # 链表-尾指针 self.tail = None def set(self, key, value): # 达到指定大小 if len(self.inner_dd) >= self.maxsize: self.remove_head_node() node = Node() node.data = (key, value) self.insert_to_tail(node) self.inner_dd[key] = node def insert_to_tail(self, node): if self.tail is None: self.tail = node self.head = node else: self.tail.next = node node.pre = self.tail self.tail = node def remove_head_node(self): node = self.head del self.inner_dd[node.data[0]] node = None self.head = self.head.next self.head.pre = None def get(self, key): if key in self.inner_dd: # 如果命中, 需要将对应的节点移动到队列的尾部 node = self.inner_dd.get(key) self.move_to_tail(node) return node.data[1] return None def move_to_tail(self, node): # 只需处理在队列头部和中间的情况 if not (node == self.tail): if node == self.head: self.head = node.next self.head.pre = None self.tail.next = node node.pre = self.tail node.next = None self.tail = node else: pre_node = node.pre next_node = node.next pre_node.next = next_node next_node.pre = pre_node self.tail.next = node node.pre = self.tail node.next = None self.tail = nodeclass Node(object): def __init__(self): self.pre = None self.next = None # (key, value) self.data = None def __eq__(self, other): if self.data[0] == other.data[0]: return True return False def __str__(self): return str(self.data)if __name__ == '__main__': cache = LRUCache(10) for i in xrange(1000): cache.set(i, i+1) cache.get(2) for key in cache.inner_dd: print key, cache.inner_dd[key]
1 0
- 简单LRU cache 实现
- LRU cache的简单实现
- LRU Cache的简单实现
- 用LinkedHashMap实现的简单LRU Cache
- LRU Cache的简单c++实现
- LRU cache的一个简单实现
- java实现简单的LRU Cache
- LRU cache的实现
- LRU cache实现 (Java)
- [Google] LRU cache实现
- 实现LRU Cache
- 如何实现 LRU Cache?
- LRU Cache实现
- LRU Cache的实现
- LRU Cache 实现
- LRU cache实现
- LRU cache实现 (Java)
- LRU cache实现
- C语言关键字”volatile”的意义(或重要性)
- 《赋得古原草送别》 白居易
- Cocos2d-x版的HelloWorld工程分析
- 循环删除list中多个元素
- poj 3268 Silver Cow Party(dijkstra最短路)
- 简单LRU cache 实现
- uva10020 - Minimal coverage
- HDU 4268 - Alice and Bob
- Java 写一个单例模式(Singleton)出来
- 初闻桂花香
- HDU 5033 Building (单调栈)
- Duilib学习笔记《02》— 界面布局
- spring的RabbitTemplate 发送Message源码导读
- 【ci框架】codeigniter中如何记录错误日志