-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathfifo-cache.ts
More file actions
64 lines (56 loc) · 1.52 KB
/
fifo-cache.ts
File metadata and controls
64 lines (56 loc) · 1.52 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
62
63
64
/**
* Copyright (c) 2022-present Hengyang Zhang
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
const DEFAULT_THRESHOLD = 10
/**
* FIFO cache
*/
class FIFOCache<T> {
keyQueue: string[] = []
threshold: number
map: Record<string, T> = {}
constructor(threshold?: number) {
if (!threshold) {
threshold = DEFAULT_THRESHOLD
} else if (!Number.isInteger(threshold)) {
throw new Error('Threshold MUST BE integer')
} else if (threshold <= 0) {
threshold = DEFAULT_THRESHOLD
}
this.threshold = threshold
}
async set(key: string, value: T) {
if (!key || !value) return
const hasKey = this.map[key]
this.map[key] = value
if (!hasKey) {
// New key
this.keyQueue.push(key)
const length = this.keyQueue.length
if (length > this.threshold) {
const deleted = this.keyQueue.slice(0, length - this.threshold)
deleted.forEach(key => delete this.map[key])
}
}
}
async getOrSupply(key: string, supplier: () => PromiseLike<T>): Promise<T> {
const exist = this.map[key]
if (exist) {
return exist
}
const value = await supplier()
this.set(key, value)
return value
}
clear() {
this.keyQueue = []
this.map = {}
}
size() {
return this.keyQueue.length
}
}
export default FIFOCache