redis中LRU演算法的實現

2021-09-12 04:16:48 字數 1516 閱讀 7402

lru(least recently used),即最近最少使用

它應該支援以下操作: 獲取資料 get 和 寫入資料 put 。

獲取資料 get(key) - 如果金鑰 (key) 存在於快取中,則獲取金鑰的值(總是正數),否則返回 -1。

寫入資料 put(key, value) - 如果金鑰不存在,則寫入其資料值。當快取容量達到上限時,它應該在寫入新資料之前刪除最近最少使用的資料值,從而為新的資料值留出空間。

如果對題目還未理解清楚的,可以去**動畫演示。

首先,需要想清楚到底用哪個資料結構用來進行儲存,因為每次get和put時,都會把響應的鍵值對移位置(以便實現最近最少使用的刪除),也就是多數情況下要在此容器的中間位置進行刪除操作,所以應該選擇鏈式儲存結構,對應stl的list.因為無論是選擇序列容器的vector還是deque在中間位置進行插入移除操作,都要耗費線性時間。其次,儲存鍵值對可以用pair<>來封裝乙個int型的鍵和乙個int型的value。即需要維護乙個list>型別的容器。然後,如何實現將最近最少使用的鍵值對從快取中清除掉呢?

其實很簡單,我們可以用乙個佇列來實現,(這裡按照隊尾入隊,隊頭出隊的原則),每次使用這個鍵值對的時候(即進行get或put方法)將此鍵值對放入隊尾,如果此時容量不夠了,又進行了put操作,那麼隊頭元素出隊即可。

如果看過我之前的文章,很容易想起什麼資料結構最適合在這使用,對,沒錯,就是鏈式佇列

在進行get和put方法時,毫無疑問需要遍歷此鏈式佇列,如果我們進行遍歷,那麼時間複雜度為o(n),如果呼叫stl庫中的刪除和查詢演算法的話,那麼時間複雜度為o(1),(庫中的複雜度我們不計算!)

好了,不多說,上**!

#pragma once

#include #include#include using namespace std;

class lrucache

; ~lrucache() = default;

void put(int key, int value);

int get(int key);

};lrucache::lrucache(int capacity):m_capacity(capacity)

{}void lrucache::put(int key, int value)

); if (m_list.size() < m_capacity)

else }

int lrucache::get(int key)

); if (ite != m_list.end())

else

}

嚴格意義上講,實現**的時間複雜度o(n),因為呼叫庫的演算法的時間複雜度為o(n)。此外還可以將list中的位址與key對映,然後儲存到乙個關聯容器中,因為關聯容器的底層資料結構是紅黑樹,時間複雜度為o(log(2)n),這種實現如果有時間的話可以實現出來然後再上傳。

另外,感謝大錘提示我進行下一步的思考,即在get的時候可不可以先不放在隊尾,而等使用者進行了n次get後再放入隊尾,這樣不至於頻繁操作,將使用者經常獲取的鍵值對進行優化操作。抽空再實現。

LRU在Redis中的實現

redis使用的是近似lru演算法,它跟常規的lru演算法還不太一樣。近似lru演算法通過隨機取樣法淘汰資料,每次隨機出5 預設 個key,從裡面淘汰掉最近最少使用的key。redis給每個key增加了乙個額外增加了乙個24bit的字段,用來儲存該key最後一次被訪問的時間。取樣數量 maxmemo...

Redis高階 LRU演算法

首先,redis的過期策略分為定期刪除 惰性刪除。定期刪除 預設100ms隨機抽查一些過期的key將其刪除即可。惰性刪除 當查詢key時,if key 過期 刪除key且不返回 正常執行 為什麼不掃瞄全部的key?如果對所有的key進行掃瞄,那就相當於執行了一次全包掃瞄,效能是非常低的。noeviv...

LRU演算法的實現

0 推薦 lru演算法的實現 什麼是lru演算法lru是least recently used的縮寫,即最近最少使用頁面置換演算法,是為虛擬頁式儲存管理服務的.關於作業系統的記憶體管理,如何節省利用容量不大的記憶體為最多的程序提供資源,一直是研究的重要方向.而記憶體的虛擬儲存管理,是現在最通用,最成...