首先,这两种算法都是为了构建一个缓存函数,用以控制数组长度。
FIFO的设计理念是:当达到缓存上限时,就去掉最先加进来的一项。
LRU的设计理念是:当达到缓存上限时,去除最不经常访问的一项。那么怎么判断谁是最不经常访问的一项呢?做法就是每当访问的时候,就把被访问的那项提升到末位。也就是说,要是没读取任何一项,还是去掉最先加入的一项。
js代码实现:
FIFO函数
class FifoCache {
constructor(maxCache) {
this.maxCache = maxCache || 100; // 缓存上限
this.arr = [];
}
get(key) {
// 读取元素的方法
console.log("arr:", this.arr);
return this.arr[key];
}
set(key, value) {
// 设置元素的方法
if (this.arr[key] || this.arr[key] == 0) {
// key值存在,更新这个元素
this.arr[key] = value;
} else {
// 不存在,直接新增
if (this.arr.length == this.maxCache) {
this.arr.shift(); // 到达上限,移除队列第一个元素
}
this.arr.push(value);
}
}
}
var fifo = new FifoCache(5); // 缓存上限为10
fifo.set(0, 0); // 设置了第一项为1
fifo.set(1, 1);
fifo.set(2, 2);
fifo.set(3, 3);
fifo.set(4, 4);
fifo.set(5, 5);
fifo.set(0, 6);
console.log(fifo.get(0));
LRU函数
class LRUCache {
constructor(maxCache) {
this.maxCache = maxCache || 100; // 缓存上限
this.arr = new Map(); // 使用es6的map来生成数组,可以减少时间复杂度,参考别人的优化版,具体为啥能减少不太清楚
}
get(key) {
// 读取元素的方法
if (this.arr.has(key)) {
// 有这个key,说明有这个值,那么就把它的位置调到末位
let temp = this.arr.get(key)
this.arr.delete(key) // 删除这项
this.arr.set(key, temp) // 再加入,相当于数组先shift,再push,就把它挪到末位了
return temp;
}
return -1;
}
set(key, value) {
if (this.cache.has(key)) {
// 存在的话就先删除,再加入
this.arr.delete(key)
} else if (this.arr.size >= this.maxCache ) {
// 不存在,且达到缓存上限,移除使用频率最低的一项
this.arr.delete(this.arr.keys().next().value) // Map实例keys()方法会返回所有
// 的键,然后next().value能得到第一个键的值
}
this.arr.set(key, value)
}
}