LRU 是 Least Recently Used 的縮寫,即最近最少使用,是一種常用的頁面置換算法,選擇內存中最近最久未使用的頁面予以淘汰。
可用的 NodeJS 庫見node-lru-cache
然怎麼使用 JS 簡單寫一個?
思路
解法:維護一個數組,提供 get 和 put 方法,並且限定 max 數量。
使用時,get 可以標記某個元素是最新使用的,提升它去第一項。put 可以加入某個值,但需要判斷是否已經到最大限制 max
- 若未到能直接往數組第一項裏插入
- 若到了最大限制 max,則需要淘汰數據尾端一個元素。
// 4 是最大限制長度
var cacheInstance = new LRU(4);
// arr => ['a', 'b', 'c']
cacheInstance.put('c');
cacheInstance.put('b');
cacheInstance.put('a');
// arr => ['b', 'a', 'c']
cacheInstance.get('b');
// arr => ['d', 'b', 'a', 'c']
cacheInstance.put('d');
// 新插入一個元素,c 就是最久沒有使用的,被淘汰
// arr => ['e' ,'d', 'b', 'a']
cacheInstance.put('e');
具體代碼
function LRU (max) {
this.max = max;
this.cache = [];
}
LRU.prototype.get = function (value) {
let index = this.cache.indexOf(value);
if (index === -1) { return null; }
// 刪除此元素後插入到數組第一項
this.cache.splice(index, 1);
this.cache.unshift(value);
return value;
}
LRU.prototype.put = function (value) {
let index = this.cache.indexOf(value);
// 想要插入的數據已經存在了,那麼直接提升它就可以
if (index > -1) {
this.cache.splice(index, 1);
this.cache.unshift(value);
return null;
}
// 想要插入的數據不存在,需要判斷下是否數組已經到了最大限制
if (this.cache.length < this.max) {
// 若沒到,則直接插入
this.cache.unshift(value);
return value;
}
// 若已經到達最大限制,先淘汰一個最久沒有使用的
this.cache.pop();
this.cache.unshift(value);
return value;
}
使用案例
- vue 2.6 源碼中 keep-alive 組件的策略就用到了 LRU 算法
- 多點登錄,限制一個賬號允許登錄 5 個端,那麼第 6 個端登錄時,就需要擠掉最早登錄的那個端。