Skip to content

Instantly share code, notes, and snippets.

@axetroy

axetroy/README.md

Last active Dec 21, 2017
Embed
What would you like to do?
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