Skip to content

Commit 7ca763c

Browse files
committed
Cache improved, added maxExpire
1 parent 87076c9 commit 7ca763c

File tree

2 files changed

+29
-43
lines changed

2 files changed

+29
-43
lines changed

src/common/cache/TimedCache.ts

Lines changed: 21 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,20 @@ export default class TimedCache<TKey = any, T = any> implements Disposable {
4141

4242
private map: Map<TKey,ICachedItem> = new Map();
4343

44-
private times = new Map<number, TKey>();
45-
4644
private weakRef;
4745

46+
private deleteItem = ([key, item]) => {
47+
this.map.delete(key);
48+
this.deletedEvent.dispatch(key);
49+
try {
50+
if (item.dispose) {
51+
item.dispose(item.value)?.catch?.(console.error);
52+
}
53+
} catch {
54+
// do nothing
55+
}
56+
}
57+
4858
constructor(private ttl = 15000, private maxTTL = ttl * 4) {
4959
const r = new WeakRef(this);
5060
cacheSet.add(r);
@@ -58,14 +68,12 @@ export default class TimedCache<TKey = any, T = any> implements Disposable {
5868
}
5969

6070
delete(key: any) {
61-
this.deletedEvent.dispatch(key);
62-
let item = this.map.get(key);
63-
if (item) {
64-
this.map.delete(key);
65-
this.times.delete(item.expire);
66-
}if (!item) {
71+
const item = this.map.get(key);
72+
if (!item) {
6773
return;
6874
}
75+
this.map.delete(key);
76+
this.deletedEvent.dispatch(key);
6977
try {
7078
if (item.dispose) {
7179
item.dispose(item.value)?.catch?.(console.error);
@@ -92,10 +100,8 @@ export default class TimedCache<TKey = any, T = any> implements Disposable {
92100
this.addedEvent.dispatch({ key, value: item.value });
93101
this.map.set(key, item);
94102
} else {
95-
this.times.delete(item.expire);
96103
item.expire += ttl;
97104
}
98-
this.times.set(item.expire, key);
99105
return item.value as T;
100106
}
101107

@@ -123,47 +129,19 @@ export default class TimedCache<TKey = any, T = any> implements Disposable {
123129
});
124130
}
125131
} else {
126-
this.times.delete(item.expire);
127132
item.expire += ttl;
128133
}
129-
this.times.set(item.expire, key);
130134
return item.value;
131135
}
132136

133137
private clearExpired(max = Date.now()): void {
134138

135-
/**
136-
* deletion often leads to fragmentation.
137-
* So we will let this array get garbate collected
138-
* and we will assign new times
139-
*
140-
* The reason we are doing this to an array and not a map
141-
* as map keys won't change regularly but times will
142-
* change on every access.
143-
*/
144-
145-
const oldTimes = this.times;
146-
this.times = new Map();
147-
148-
for(const [i, key] of oldTimes.entries()) {
149-
150-
if (i > max) {
151-
this.times.set(i, key);
152-
return;
153-
}
154-
const value = this.map.get(key);
155-
this.map.delete(key);
156-
157-
// call dispose..
158-
this.deletedEvent.dispatch(key);
159-
try {
160-
const r = value.dispose?.(value.value);
161-
if (r?.then) {
162-
r.catch(() => void 0);
163-
}
164-
} catch (error) {
165-
console.error(error);
139+
for(const entry of this.map.entries()) {
140+
const value = entry[1];
141+
if (value.expire > max && value.maxExpire > max) {
142+
continue;
166143
}
144+
setImmediate(this.deleteItem, entry);
167145
}
168146

169147
}

src/tests/cache/cache.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,14 @@ async function test1() {
5151
// @ts-expect-error
5252
c1.clearExpired(Date.now());
5353

54+
// deletion is not immediate
55+
await sleep(1);
56+
5457
const firstV4 = "v4";
5558

5659
const cc4 = c1.getOrCreate("a1", 0, () => firstV4);
5760

61+
5862
assert.equal(cc4, firstV4);
5963
}
6064

@@ -80,6 +84,8 @@ async function test2() {
8084
// @ts-expect-error
8185
c1.clearExpired(Date.now());
8286

87+
await sleep(1);
88+
8389
const firstV2 = "v2";
8490

8591
const cc2 = c1.getOrCreate("a1", 0, () => firstV2);
@@ -109,6 +115,8 @@ async function test2() {
109115
// @ts-expect-error
110116
c1.clearExpired(Date.now());
111117

118+
await sleep(1);
119+
112120
const firstV4 = "v4";
113121

114122
const cc4 = c1.getOrCreate("a1", 0, () => firstV4);

0 commit comments

Comments
 (0)