JS 實現一個 LRU 算法

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 個端登錄時,就需要擠掉最早登錄的那個端。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章