摘要:如果每一個頻率放在一個里面,每個也有頭尾兩個指針,指向相鄰的。實際上相鄰的可以由的第一可以由的最后一個唯一確認。也就是說,在的設計基礎上。也就是說頻率為的點,指向的下一個是頻率為的點移除和一樣。里存在的點,加到尾部的后一個。
只個代碼由LRU改進得到。
如果每一個頻率放在一個LRU里面,每個LRU也有頭尾兩個指針,指向相鄰的LRU。
實際上相鄰的LRU可以由frequency = t+1的第一node,可以由frequency = t的最后一個唯一確認。
也就是說,在LRU的設計基礎上。我們再多記錄一個finalNodes,記錄每種頻率的尾部就好了。
代碼因為情況較多,所以要分析好了,才能歸并。
頻率可以不連續,最小頻率也不一定為1. 我們put(1,1), get(1) LFU里現在只有這個點,頻率為2,最小頻率不是1.
我們在put(2,2), get(2),get(2), get(2). 2出現了4次。 也就是說頻率為2的點1, 指向的下一個是頻率為4的點2.
移除node和LRU一樣。
添加node,
map里不存在的要加到頭部。
2.1 map里存在的點,加到freq + 1尾部的后一個。
2.2 如果剛好freq+1這個頻率不存在(也就是freq+1在finalNodes里沒有,我們就不需要移動。)
public class LFUCache { private int capacity; private int count; private HashMapmap1; // whether appeared private HashMap finalNodes; // value : the final node of key times private Tuple dummyHead; private Tuple dummyEnd; public LFUCache(int capacity) { this.capacity = capacity; count = 0; map1 = new HashMap (); finalNodes = new HashMap<>(); dummyHead = new Tuple(0, 0, 0); dummyEnd = new Tuple(0, 0, 0); dummyHead.next = dummyEnd; dummyEnd.prev = dummyHead; } public int get(int key) { if (capacity == 0 || !map1.containsKey(key)) { return -1; } Tuple old = map1.get(key); put(key, old.value); return old.value; } public void put(int key, int value) { if (capacity == 0) { return; } if (map1.containsKey(key)) { // this key has appeared Tuple cur = map1.get(key); if (finalNodes.get(cur.times) == cur && finalNodes.get(cur.times + 1) == null) { // the position should not change finalNodes.put(cur.times, cur.prev.times == cur.times ? cur.prev : null); cur.times++; cur.value = value; finalNodes.put(cur.times, cur); return; } removeNode(cur); // remove node cur if (finalNodes.get(cur.times) == cur) { finalNodes.put(cur.times, cur.prev.times == cur.times ? cur.prev : null); } cur.times++; cur.value = value; Tuple finalNode = finalNodes.get(cur.times) == null ? finalNodes.get(cur.times - 1) : finalNodes.get(cur.times); insertNode(finalNode, cur); finalNodes.put(cur.times, cur); } else { if (count == capacity) { // reach limt of the cache Tuple head = dummyHead.next; removeNode(head); //remove the first which appeared least times and is the least Used map1.remove(head.key); if (finalNodes.get(head.times) == head) { finalNodes.remove(head.times); } } else { count++; } insertHead(key, value); } } public void insertHead(int key, int value) { Tuple cur = new Tuple(key, value, 1); if (finalNodes.get(1) == null) { insertNode(dummyHead, cur); } else { Tuple finalNode = finalNodes.get(1); insertNode(finalNode, cur); } finalNodes.put(1, cur); map1.put(key, cur); } public void insertNode(Tuple t1, Tuple t2) { t2.next = t1.next; t1.next.prev = t2; t1.next = t2; t2.prev = t1; } public void removeNode(Tuple node) { node.next.prev = node.prev; node.prev.next = node.next; } class Tuple { int key; int value; int times; Tuple prev; Tuple next; public Tuple(int key, int value, int times) { this.key = key; this.value = value; this.times = times; } } } /** * Your LFUCache object will be instantiated and called as such: * LFUCache obj = new LFUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66584.html
摘要:在靜態的頻率分布下,性能也落后于因為其不再為不在緩存中的數據維護任何頻率數據。可以詳見的準入淘汰策略是新增一個新的元素時,判斷使用該元素替換一個舊元素,是否可以提升緩存命中率。 1. Introduction LFU的局限: LFU實現需要維護大而復雜的元數據(頻次統計數據等) 大多數實際工作負載中,訪問頻率隨著時間的推移而發生根本變化(這是外賣業務不適合樸素LFU的根本原因) 針...
摘要:在靜態的頻率分布下,性能也落后于因為其不再為不在緩存中的數據維護任何頻率數據。可以詳見的準入淘汰策略是新增一個新的元素時,判斷使用該元素替換一個舊元素,是否可以提升緩存命中率。 1. Introduction LFU的局限: LFU實現需要維護大而復雜的元數據(頻次統計數據等) 大多數實際工作負載中,訪問頻率隨著時間的推移而發生根本變化(這是外賣業務不適合樸素LFU的根本原因) 針...
摘要:但是內存空間畢竟有限,隨著我們存儲數據的不斷增長,要緩存的數據量越來越大,當超過了我們的內存大小時,該怎么辦呢解決方法有兩種增加物理內存搭建集群和緩存數據的淘汰機制。增加物理內存簡單粗暴,價格十分昂貴,內存的價格大約是萬元左右。redis 使用的時內存空間來存儲數據的,避免業務應用從后端數據庫中讀取數據,可以提升應用的響應速度。但是內存空間畢竟有限,隨著我們存儲數據的不斷增長,要緩存的數據量...
摘要:如果處理不得當,就會造成緩存污染問題。解決緩存污染的算法算法,英文名,字面意思就是最不經常使用的淘汰掉算法,是通過數據被訪問的頻率來判斷一個數據的熱點情況。分析降低了緩存污染帶來的問題,命中率比要高。 微信公眾號:IT一刻鐘大型現實非嚴肅主義現場一刻鐘與你分享優質技術架構與見聞,做一個有劇情的程序員關注可第一時間了解更多精彩內容,定期有福利相送喲。 showImg(https://s...
閱讀 2053·2021-11-22 13:52
閱讀 976·2021-11-17 09:33
閱讀 2708·2021-09-01 10:49
閱讀 2841·2019-08-30 15:53
閱讀 2659·2019-08-29 16:10
閱讀 2432·2019-08-29 11:31
閱讀 1343·2019-08-26 11:40
閱讀 1866·2019-08-26 10:59