-
Notifications
You must be signed in to change notification settings - Fork 127
/
Copy pathmemoize-with-time-limit.js
123 lines (111 loc) · 3.46 KB
/
memoize-with-time-limit.js
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Write a class that allows getting and setting key-value pairs,
// however a time until expiration is associated with each key.
// The class has three public methods:
// set(key, value, duration): accepts an integer key, an integer value, and a duration in milliseconds.
// Once the duration has elapsed, the key should be inaccessible.
// The method should return true if the same un-expired key already exists and false otherwise.
// Both the value and duration should be overwritten if the key already exists.
// get(key): if an un-expired key exists, it should return the associated value.
// Otherwise, it should return -1.
// count(): returns the count of un-expired keys.
class TimeLimitedCache {
constructor() {
this.cache = new Map();
}
/**
* @param {number} key
* @return {boolean} if un-expired key already existed
*/
checkAndExpireCacheByKey(key) {
let keyExisted = this.cache.has(key);
if (keyExisted && Date.now() > this.cache.get(key).expired) {
this.cache.delete(key);
keyExisted = false;
}
return keyExisted;
}
checkAndExpireCache() {
for (const key of this.cache.keys()) {
this.checkAndExpireCacheByKey(key);
}
}
/**
* @param {number} key
* @param {number} value
* @param {number} duration time until expiration in ms
* @return {boolean} if un-expired key already existed
*/
set(key, value, duration) {
const keyExisted = this.checkAndExpireCacheByKey(key);
this.cache.set(key, {
value,
expired: duration + Date.now()
});
return keyExisted;
};
/**
* @param {number} key
* @return {number} value associated with key
*/
get(key) {
return this.checkAndExpireCacheByKey(key) ? this.cache.get(key).value : -1;
};
/**
* @return {number} count of non-expired keys
*/
count() {
this.checkAndExpireCache();
return this.cache.size;
};
}
class TimeLimitedCacheTimeout {
constructor() {
this.cache = new Map();
}
/**
* @param {number} key
* @param {number} value
* @param {number} duration time until expiration in ms
* @return {boolean} if un-expired key already existed
*/
set(key, value, duration) {
const keyExisted = this.cache.has(key);
if (keyExisted) {
clearTimeout(this.cache.get(key).timer);
}
this.cache.set(key, {
value,
timer: setTimeout(() => this.cache.delete(key), duration)
});
return keyExisted;
};
/**
* @param {number} key
* @return {number} value associated with key
*/
get(key) {
return this.cache.has(key) ? this.cache.get(key).value : -1;
};
/**
* @return {number} count of non-expired keys
*/
count() {
return this.cache.size;
};
}
const timeLimitedCache = new TimeLimitedCache();
console.log('timeLimitedCache:', timeLimitedCache.set(1, 42, 1000)); // false
console.log('timeLimitedCache:', timeLimitedCache.get(1)); // 42
console.log('timeLimitedCache:', timeLimitedCache.count()); // 1
setTimeout(
() => console.log('timeLimitedCache after 1200 ms:', timeLimitedCache.count()),
1200
); // 0
const timeLimitedCacheTimeout = new TimeLimitedCacheTimeout();
console.log('timeLimitedCacheTimeout:', timeLimitedCacheTimeout.set(1, 42, 1000)); // false
console.log('timeLimitedCacheTimeout:', timeLimitedCacheTimeout.get(1)); // 42
console.log('timeLimitedCacheTimeout:', timeLimitedCacheTimeout.count()); // 1
setTimeout(
() => console.log('timeLimitedCacheTimeout after 1200 ms:', timeLimitedCacheTimeout.count()),
1200
); // 0