Created
April 27, 2018 00:17
-
-
Save HuangXiZhou/8e47a43d74326d01b24675f82d885039 to your computer and use it in GitHub Desktop.
JavaScript LruCache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LruCache { | |
constructor(maxsize) { | |
this._cache = {}; // 缓存 | |
this._queue = []; // 队列 | |
this._maxsize = maxsize; // 最大值 | |
// 如果最大值输入非法 默认无限大 | |
if (!this._maxsize || !(typeof this._maxsize === 'number') || this._maxsize <= 0) { | |
this._maxsize = Infinity; | |
} | |
// 运行定时器,定时检查过期值 | |
setInterval(() => { | |
this._queue.forEach((el, idx) => { | |
const key = el; | |
const insertTime = this._cache[key].insertTime; | |
const expire = this._cache[key].expire; | |
const curTime = +new Date(); | |
// 如果存在过期时间且超期,移除数据 | |
if (expire && curTime - insertTime > expire) { | |
this._queue.splice(idx--, 1); | |
delete this._cache[key]; | |
} | |
}); | |
}, 1000); | |
} | |
// 生成唯一索引 | |
_makeSymbol(key) { | |
return Symbol.for(key); | |
} | |
// 更新队列 | |
_update(queue, key) { | |
// 移除 | |
queue.forEach((el, idx) => { | |
if (el === key) { | |
queue.splice(idx, 1); | |
} | |
}); | |
// 前置 | |
queue.unshift(key); | |
return queue; | |
} | |
// 插入数据 | |
set(key, value, expire) { | |
key = this._makeSymbol(key); // 生成唯一索引 | |
// 如果已经存在该值,则重新赋值 | |
if (this._cache[key]) { | |
this._cache[key] = { | |
value, | |
expire, | |
insertTime: this._cache[key].insertTime | |
} | |
this._queue = this._update(this._queue, key); // 更新队列 | |
} else { | |
// 如果不存在,则插入 | |
this._cache[key] = { | |
value, | |
expire, | |
insertTime: +new Date() | |
} | |
// 索引置前 | |
this._queue.unshift(key); | |
// 超出最大值,截断 | |
while (this._queue.length > this._maxsize) { | |
const item = this._queue.pop(); // 尾截断 | |
delete this._cache[item]; // 删除 | |
} | |
} | |
} | |
// 获取数据 | |
get(key) { | |
key = this._makeSymbol(key); | |
// 如果存在该值 | |
if (this._cache[key]) { | |
const insertTime = this._cache[key].insertTime; // 插入时间 | |
const expire = this._cache[key].expire; // 过期时间 | |
const curTime = +new Date(); // 当前时间 | |
// 如果不存在过期时间 或 存在过期时间但尚未过期 | |
if (!expire || (expire && curTime - insertTime < expire)) { | |
// 更新队列,前置索引 | |
this._queue = this._update(this._queue, key); | |
return this._cache[key].value; | |
} else if (expire && curTime - insertTime > expire) { | |
// 已经过期 | |
this._queue.forEach((el, idx) => { | |
if (el === key) { | |
this._queue.slice(idx, 1); | |
delete this._cache[key]; | |
} | |
}) | |
return null | |
} | |
} else { | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment