构建一个可用的内存缓存.
cache初稿
const defaultConfig = { | |
MaximumCache: 100000 // 最大缓存个数, 如果缓存超出这个, 则会把最早的缓存删除掉 | |
}; | |
class Granule { | |
constructor(id, data) { | |
const now = new Date(); | |
this.id = id; // 数据id | |
this.data = data; // 数据 | |
this.createdAt = now; // 创建时间 | |
this.updatedAt = now; // 更新时间 | |
this.expiredAt = now; // 过期时间 | |
this.recentlyUsedAt = now; // 最近使用时间 | |
this.usageCount = 0; // 使用次数 | |
} | |
get isExpired() { | |
return new Date().getTime() - this.expiredAt.getTime() > 0; | |
} | |
} | |
class Cache { | |
constructor(config = defaultConfig) { | |
this.config = config; | |
this.map = new Map(); | |
this.tick = 0; | |
} | |
/** | |
* 添加缓存 | |
* @param id 缓存id | |
* @param data 缓存对象 | |
* @param expiration 过期时间 | |
* @returns {Cache} | |
*/ | |
add(id, data, expiration) { | |
if (this.length >= this.config.MaximumCache) { | |
for (let key of this.map.keys()) { | |
this.map.delete(key); | |
break; | |
} | |
} | |
const granule = new Granule(id, data); | |
granule.expiredAt = new Date(expiration); | |
this.map.set(id, granule); | |
} | |
/** | |
* remove cache | |
* @param id | |
*/ | |
remove(id) { | |
this.map.delete(id); | |
} | |
get length() { | |
return this.map.size; | |
} | |
/** | |
* clear cache | |
*/ | |
clear() { | |
this.map.clear(); | |
} | |
/** | |
* Get cache from an given id | |
* @param id | |
* @returns {*} | |
*/ | |
get(id) { | |
const element = this.map.get(id); | |
if (!element) { | |
return void 0; | |
} | |
const granule = element; | |
// 过期返回undefined, 并且删除缓存 | |
if (granule.isExpired) { | |
this.map.delete(id); | |
return void 0; | |
} | |
granule.recentlyUsedAt = new Date(); | |
granule.usageCount++; | |
if (this.tick === 10000) { | |
this.tick = 0; | |
} else { | |
this.tick++; | |
} | |
if (this.tick % 100 === 0) { | |
// 检查过期 | |
for (let g of this.map.values()) { | |
if (g.isExpired) { | |
this.remove(g.id); | |
} | |
} | |
} | |
return granule.data; | |
} | |
} | |
module.exports = Cache; | |
const c = new Cache(); | |
for (let i = 0; i < 110; i++) { | |
c.add(i, i, new Date().getTime() + 3600 * 1000); | |
} | |
console.log(c); | |
console.log(c.length); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment