LRUアルゴリズムの簡単な説明
より一般的なキャッシュアルゴリズムは、メモリ管理で使用されるアルゴリズムでもあります。メモリがいっぱいになると、メモリ内の最後に使用されていないページが選択されて削除されます。
実現する方法
ハッシュテーブル+二重リンクリスト
二重リンクリストには、これらのキーと値のペアが使用されている順序で格納されます。ヘッドの近くのキーと値のペアが最も最近使用され、テールの近くのキーと値のペアが最も使用されていません。
ハッシュテーブルは通常のハッシュマップ(ES6マップ)であり、キャッシュされたデータのキーを二重リンクリスト内の位置にマップします。
最初にハッシュテーブルを使用して、二重リンクリスト内のキャッシュアイテムの位置を見つけ、それを二重リンクリストの先頭に移動します。次に、O(1)でgetまたはput操作を完了できます。時間。具体的な方法は次のとおりです。
get操作の場合、最初にキーが存在するかどうかを判別します。
- キーが存在しない場合は、-1-1を返します。
- キーが存在する場合、そのキーに対応するノードが最後に使用されたノードです。ハッシュテーブルを介して二重リンクリスト内のノードの位置を見つけ、それを二重リンクリストの先頭に移動して、最後にノードの値を返します。
put操作の場合、最初にキーが存在するかどうかを判別します。
- キーが存在しない場合は、キーと値を使用して新しいノードを作成し、二重リンクリストの先頭にノードを追加して、キーとノードをハッシュテーブルに追加します。次に、二重リンクリストのノード数が容量を超えているかどうかを判断し、容量を超えている場合は、二重リンクリストのテールノードを削除し、ハッシュテーブルの対応する項目を削除します。
- キーが存在する場合は、get操作と同様です。最初にハッシュテーブルを検索し、次に対応するノードの値をvalueに更新して、ノードを二重リンクリストの先頭に移動します。
var LRUCache = function (capacity) {
this.cache = new Map();
this.capacity = capacity;
};
LRUCache.prototype.get = function (key) {
if (this.cache.has(key)) {
// 存在即更新
let temp = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, temp);
return temp;
}
return -1;
};
LRUCache.prototype.put = function (key, value) {
if (this.cache.has(key)) {
// 存在即更新(删除后加入)
this.cache.delete(key);
} else if (this.cache.size >= this.capacity) {
// 不存在即加入
// 缓存超过最大值,则移除最近没有使用的
this.cache.delete(this.cache.keys().next().value);
}
this.cache.set(key, value);
};