起因:我的同事需要乙個固定大小的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-8
class 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
&nbs程式設計客棧p; 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
&bzbegqnbsp; next_node.pre = pre_node
self.tail.next = node
node.pre = self.tail
node.next = none
self.tail = node
class 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__ == '_www.cppcns.com_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]
本文標題: python實現的乙個簡單lru cache
本文位址:
python簡單實現邏輯回歸 LR
import numpy as np import math from sklearn import datasets from collections import counter infinity float 2 31 邏輯回歸的實現 defsigmodformatrix xb,thetas p...
Python 實現乙個簡單的多執行緒
import threading def main str print str def create thread num,args threads for i in range num try t threading.thread target main,args args t.start exc...
Python 基於Redis實現乙個簡單的分布式鎖
redis lock.py import redis import time import threading 連線池方式 pool redis.connectionpool host 127.0.0.1 port 6379 redis con redis.redis connection pool...