-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathcache.js
More file actions
61 lines (55 loc) · 1.36 KB
/
Copy pathcache.js
File metadata and controls
61 lines (55 loc) · 1.36 KB
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* Caches values in memory with a single key of any type.
*
* @template K, V
*/
export class KeyedCache {
/** @type {Map<K, V>} */
#map = new Map();
/**
* Returns cached value, initializing if necessary
*
* @param {K} key
* @param {() => V} factory
* @returns {V} cached value
*
* @example
* const result = cache.getOrCreate(42, async () => await doWork(42));
*/
getOrCreate(key, factory) {
let value = this.#map.get(key);
if (value === undefined) {
value = factory();
this.#map.set(key, value);
}
return value;
}
}
/**
* Caches values in memory with an ordered pair of keys of any types.
*
* @template K1, K2, V
*/
export class KeyedPairCache {
// Two-layer nested cache
/** @type {KeyedCache<K1, KeyedCache<K2, V>>} */
#cache1 = new KeyedCache();
/**
* Returns cached value, initializing if necessary.
* Keys are ordered, so (key1, key2) != (key2, key1).
*
* @param {K1} key1
* @param {K2} key2
* @param {() => V} factory
* @returns {V} cached value
*
* @example
* const result = cache.getOrCreate(42, 7, async () => await doWork(42, 7));
*/
getOrCreate(key1, key2, factory) {
// key1 => cache for the next layer
const cache2 = this.#cache1.getOrCreate(key1, () => new KeyedCache());
// key2 => final value
return cache2.getOrCreate(key2, factory);
}
}