← Wszystkie zadaniaNode.js · Middle

Cache z czasem życia (TTL)

Napisz createTtlCache({ ttlMs, now }) z metodami get, set(key, value, ttl?), has, delete i size. Wpis żyje ttl milisekund (domyślnie ttlMs) od ostatniego set; gdy now() >= expiresAt, jest już przeterminowany.

Przeterminowane wpisy nie są zwracane i są usuwane przy dostępie, a size() liczy tylko żywe. has musi działać także dla wartości 0, null czy "". Czas pochodzi z now(), aby cache dało się testować bez czekania.

Testy (5)

  1. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('a', 1);
    expect(cache.get('a')).toBe(1);
    t = 999;
    expect(cache.get('a')).toBe(1);
    t = 1000;
    expect(cache.get('a')).toBe(undefined);
  2. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('short', 'x', 100);
    cache.set('long', 'y');
    t = 500;
    expect(cache.has('short')).toBe(false);
    expect(cache.has('long')).toBe(true);
  3. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('a', 1);
    t = 800;
    cache.set('a', 2);
    t = 1500;
    expect(cache.get('a')).toBe(2);
  4. let t = 0;
    const cache = createTtlCache({ ttlMs: 100, now: () => t });
    cache.set('a', 1); cache.set('b', 2); cache.set('c', 3, 1000);
    expect(cache.size()).toBe(3);
    t = 200;
    expect(cache.size()).toBe(1);
  5. let t = 0;
    const cache = createTtlCache({ ttlMs: 1000, now: () => t });
    cache.set('zero', 0);
    cache.set('empty', null);
    expect(cache.has('zero')).toBe(true);
    expect(cache.has('empty')).toBe(true);
    expect(cache.has('missing')).toBe(false);
    expect(cache.delete('zero')).toBe(true);
    expect(cache.has('zero')).toBe(false);