Skip to content

2622. Cache With Time Limit 👍

Approach 1: Synchronous

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
interface Value {
  value: number;
  expiredAt: number;
}

class TimeLimitedCache {
  private cache = new Map<number, Value>();

  set(key: number, value: number, duration: number): boolean {
    const now = Date.now();
    const exists = this.getValue(now, key) !== undefined;
    this.cache.set(key, { value, expiredAt: now + duration });
    return exists;
  }

  get(key: number): number {
    const val = this.getValue(Date.now(), key);
    return val === undefined ? -1 : val.value;
  }

  count(): number {
    const now = Date.now();
    for (const key of this.cache.keys())
      if (this.getValue(now, key) === undefined) {
        this.cache.delete(key);
      }
    return this.cache.size;
  }

  private getValue(now: number, key: number): Value | undefined {
    const val = this.cache.get(key);
    return val && now <= val.expiredAt ? val : undefined;
  }
}

Approach 2: Asynchronous w/ setTimeout()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
interface TTLValue {
  value: number;
  timer: ReturnType<typeof setTimeout>;
}

class TimeLimitedCache {
  private cache = new Map<number, TTLValue>();

  set(key: number, value: number, duration: number): boolean {
    const exists = this.cache.has(key);
    if (exists) {
      clearTimeout(this.cache.get(key).timer);
    }
    this.cache.set(key, {
      value,
      timer: setTimeout(() => this.cache.delete(key), duration),
    });
    return exists;
  }

  get(key: number): number {
    return this.cache.has(key) ? this.cache.get(key).value : -1;
  }

  count(): number {
    return this.cache.size;
  }
}