cache初稿

README.md
复制

构建一个可用的内存缓存.

https://github.com/axetroy/todo/issues/70

cache.js
复制

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);

大牛们的评论:朕有话说

还没有人评论哦,赶紧抢沙发!