Skip to content

Commit 666418c

Browse files
committed
feat: Internal eviction methods are now called maintenance
1 parent be6b221 commit 666418c

File tree

6 files changed

+66
-55
lines changed

6 files changed

+66
-55
lines changed

src/cache/bounded/index.ts

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CacheSPI } from '../cache-spi';
44
import { Metrics } from '../metrics/metrics';
55
import { CountMinSketch } from './sketch';
66

7-
import { ON_REMOVE, ON_EVICT, TRIGGER_REMOVE, EVICT } from '../symbols';
7+
import { ON_REMOVE, ON_MAINTENANCE, TRIGGER_REMOVE, MAINTENANCE } from '../symbols';
88

99
import { RemovalReason } from '../removal-reason';
1010
import { CacheNode } from '../cache-node';
@@ -60,9 +60,9 @@ interface BoundedCacheData<K extends KeyType, V> {
6060
sketch: CountMinSketch;
6161
sketchGrowLimit: number;
6262

63-
evictionTimeout: any;
63+
maintenanceTimeout: any;
6464
forceEvictionLimit: number;
65-
evictionInterval: number;
65+
maintenanceInterval: number;
6666

6767
window: CacheSection<K, V>;
6868
protected: CacheSection<K, V>;
@@ -89,7 +89,7 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
8989
private [DATA]: BoundedCacheData<K, V>;
9090

9191
public [ON_REMOVE]?: RemovalListener<K, V>;
92-
public [ON_EVICT]?: () => void;
92+
public [ON_MAINTENANCE]?: () => void;
9393

9494
constructor(options: BoundedCacheOptions<K, V>) {
9595
super();
@@ -105,6 +105,8 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
105105
*/
106106
const sketchWidth = options.weigher ? 256 : Math.max(options.maxSize, 128);
107107

108+
this[MAINTENANCE] = this[MAINTENANCE].bind(this);
109+
108110
this[DATA] = {
109111
maxSize: options.weigher ? -1 : options.maxSize,
110112
removalListener: options.removalListener || null,
@@ -137,12 +139,12 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
137139
head: new BoundedNode<K, V>(null, null),
138140
},
139141

140-
// Timeout used to schedule evictions
141-
evictionTimeout: 0,
142+
// Timeout used to schedule maintenance
143+
maintenanceTimeout: null,
142144
// The maximum size we can temporarily be grow before an eviction is forced
143145
forceEvictionLimit: options.maxSize + Math.max(Math.floor(options.maxSize * percentOverflow), 5),
144146
// The time to wait before an eviction is triggered by a set
145-
evictionInterval: 5000
147+
maintenanceInterval: 5000
146148
};
147149
}
148150

@@ -221,9 +223,9 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
221223

222224
// Schedule eviction
223225
if(data.weightedSize >= data.forceEvictionLimit) {
224-
this[EVICT]();
225-
} else if(! data.evictionTimeout) {
226-
data.evictionTimeout = setTimeout(() => this[EVICT](), data.evictionInterval);
226+
this[MAINTENANCE]();
227+
} else if(! data.maintenanceTimeout) {
228+
data.maintenanceTimeout = setTimeout(this[MAINTENANCE], data.maintenanceInterval);
227229
}
228230

229231
// Return the value we replaced
@@ -320,8 +322,8 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
320322

321323
this[TRIGGER_REMOVE](key, node.value, RemovalReason.EXPLICIT);
322324

323-
if(! data.evictionTimeout) {
324-
data.evictionTimeout = setTimeout(() => this[EVICT](), data.evictionInterval);
325+
if(! data.maintenanceTimeout) {
326+
data.maintenanceTimeout = setTimeout(this[MAINTENANCE], data.maintenanceInterval);
325327
}
326328

327329
return node.value;
@@ -356,19 +358,19 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
356358
data.protected.head.remove();
357359
data.protected.size = 0;
358360

359-
if(data.evictionTimeout) {
360-
clearTimeout(data.evictionTimeout);
361-
data.evictionTimeout = null;
361+
if(data.maintenanceTimeout) {
362+
clearTimeout(data.maintenanceTimeout);
363+
data.maintenanceTimeout = null;
362364
}
363365
}
364366

365367
public keys(): K[] {
366-
this[EVICT]();
368+
this[MAINTENANCE]();
367369
return Array.from(this[DATA].values.keys());
368370
}
369371

370372
public cleanUp() {
371-
this[EVICT]();
373+
this[MAINTENANCE]();
372374
}
373375

374376
get metrics(): Metrics {
@@ -390,7 +392,20 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
390392
}
391393
}
392394

393-
private [EVICT]() {
395+
private [MAINTENANCE]() {
396+
/*
397+
* Trigger the onMaintenance listener if one exists. This is done
398+
* before eviction occurs so that extra layers have a chance to
399+
* apply their own eviction rules.
400+
*
401+
* This can be things such as things being removed because they have
402+
* been expired which in turn might cause eviction to be unnecessary.
403+
*/
404+
const onMaintenance = this[ON_MAINTENANCE];
405+
if(onMaintenance) {
406+
onMaintenance();
407+
}
408+
394409
const data = this[DATA];
395410

396411
/*
@@ -455,15 +470,9 @@ export class BoundedCache<K extends KeyType, V> extends AbstractCache<K, V> impl
455470
this[TRIGGER_REMOVE](toRemove.key, toRemove.value, RemovalReason.SIZE);
456471
}
457472

458-
// Trigger the onEvict listener if one exists
459-
const onEvict = this[ON_EVICT];
460-
if(onEvict) {
461-
onEvict();
462-
}
463-
464-
if(data.evictionTimeout) {
465-
clearTimeout(data.evictionTimeout);
466-
data.evictionTimeout = null;
473+
if(data.maintenanceTimeout) {
474+
clearTimeout(data.maintenanceTimeout);
475+
data.maintenanceTimeout = null;
467476
}
468477
}
469478
}

src/cache/boundless/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { RemovalReason } from '../removal-reason';
99

1010
import { Metrics } from '../metrics/metrics';
1111

12-
import { ON_REMOVE, ON_EVICT, TRIGGER_REMOVE, EVICT } from '../symbols';
12+
import { ON_REMOVE, ON_MAINTENANCE, TRIGGER_REMOVE, MAINTENANCE } from '../symbols';
1313

1414
const DATA = Symbol('boundlessData');
1515

@@ -43,7 +43,7 @@ export class BoundlessCache<K extends KeyType, V> extends AbstractCache<K, V> im
4343
private [DATA]: BoundlessCacheData<K, V>;
4444

4545
public [ON_REMOVE]?: RemovalListener<K, V>;
46-
public [ON_EVICT]?: () => void;
46+
public [ON_MAINTENANCE]?: () => void;
4747

4848
constructor(options: BoundlessCacheOptions<K, V>) {
4949
super();
@@ -88,7 +88,7 @@ export class BoundlessCache<K extends KeyType, V> extends AbstractCache<K, V> im
8888

8989
// Schedule an eviction
9090
if(! data.evictionTimeout) {
91-
data.evictionTimeout = setTimeout(() => this[EVICT](), EVICTION_DELAY);
91+
data.evictionTimeout = setTimeout(() => this[MAINTENANCE](), EVICTION_DELAY);
9292
}
9393

9494
// Return the value we replaced
@@ -130,7 +130,7 @@ export class BoundlessCache<K extends KeyType, V> extends AbstractCache<K, V> im
130130

131131
// Queue an eviction event if one is not set
132132
if(! data.evictionTimeout) {
133-
data.evictionTimeout = setTimeout(() => this[EVICT](), EVICTION_DELAY);
133+
data.evictionTimeout = setTimeout(() => this[MAINTENANCE](), EVICTION_DELAY);
134134
}
135135

136136
return old;
@@ -167,7 +167,7 @@ export class BoundlessCache<K extends KeyType, V> extends AbstractCache<K, V> im
167167
* Get all of the keys currently in the cache.
168168
*/
169169
public keys() {
170-
this[EVICT]();
170+
this[MAINTENANCE]();
171171
return Array.from(this[DATA].values.keys());
172172
}
173173

@@ -176,7 +176,7 @@ export class BoundlessCache<K extends KeyType, V> extends AbstractCache<K, V> im
176176
*/
177177
public cleanUp() {
178178
// Simply request eviction so extra layers can handle this
179-
this[EVICT]();
179+
this[MAINTENANCE]();
180180
}
181181

182182
get metrics(): Metrics {
@@ -197,9 +197,9 @@ export class BoundlessCache<K extends KeyType, V> extends AbstractCache<K, V> im
197197
}
198198
}
199199

200-
private [EVICT]() {
200+
private [MAINTENANCE]() {
201201
// Trigger the onEvict listener if one exists
202-
const onEvict = this[ON_EVICT];
202+
const onEvict = this[ON_MAINTENANCE];
203203
if(onEvict) {
204204
onEvict();
205205
}

src/cache/cache-spi.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { KeyType } from './key-type';
22
import { RemovalListener } from './removal-listener';
33

4-
import { ON_REMOVE, ON_EVICT } from './symbols';
4+
import { ON_REMOVE, ON_MAINTENANCE } from './symbols';
55

66
/**
77
* Type not part of the public API, used by caches and their layers as their
@@ -15,8 +15,8 @@ export interface CacheSPI<K extends KeyType, V> {
1515
[ON_REMOVE]?: RemovalListener<K, V>;
1616

1717
/**
18-
* Called when eviction occurs in the cache. Can be used by layers to
19-
* perform extra tasks during eviction, such as expiring items.
18+
* Called when maintenance occurs in the cache. Can be used by layers to
19+
* perform extra tasks during maintenance windows, such as expiring items.
2020
*/
21-
[ON_EVICT]?: () => void;
21+
[ON_MAINTENANCE]?: () => void;
2222
}

src/cache/expiration/index.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { RemovalReason } from '../removal-reason';
1313
import { TimerWheel, TimerNode } from './timer-wheel';
1414
import { MaxAgeDecider } from './max-age-decider';
1515

16-
import { PARENT, ON_REMOVE, TRIGGER_REMOVE, ON_EVICT } from '../symbols';
16+
import { PARENT, ON_REMOVE, TRIGGER_REMOVE, ON_MAINTENANCE, MAINTENANCE } from '../symbols';
1717

1818
const DATA = Symbol('expirationData');
1919

@@ -46,6 +46,7 @@ export class ExpirationCache<K extends KeyType, V> extends AbstractCache<K, V> i
4646
private [PARENT]: Cache<K, Expirable<V>> & CacheSPI<K, Expirable<V>>;
4747

4848
public [ON_REMOVE]?: RemovalListener<K, V>;
49+
public [ON_MAINTENANCE]?: () => void;
4950

5051
constructor(options: ExpirationCacheOptions<K, V>) {
5152
super();
@@ -75,8 +76,8 @@ export class ExpirationCache<K extends KeyType, V> extends AbstractCache<K, V> i
7576
this[TRIGGER_REMOVE](key, node.value as V, reason);
7677
};
7778

78-
// Custom eviction behaviour to advance the wheel
79-
this[PARENT][ON_EVICT] = () => this[DATA].timerWheel.advance();
79+
// Custom maintenance behaviour to advance the wheel
80+
this[PARENT][ON_MAINTENANCE] = this[MAINTENANCE].bind(this);
8081
}
8182

8283
get maxSize(): number {
@@ -172,12 +173,13 @@ export class ExpirationCache<K extends KeyType, V> extends AbstractCache<K, V> i
172173
return this[PARENT].metrics;
173174
}
174175

175-
get [ON_EVICT](): (() => void) | undefined {
176-
return this[PARENT][ON_EVICT];
177-
}
176+
private [MAINTENANCE]() {
177+
this[DATA].timerWheel.advance();
178178

179-
set [ON_EVICT](listener: (() => void) | undefined) {
180-
this[PARENT][ON_EVICT] = listener;
179+
const onMaintenance = this[ON_MAINTENANCE];
180+
if(onMaintenance) {
181+
onMaintenance();
182+
}
181183
}
182184

183185
private [TRIGGER_REMOVE](key: K, value: V, reason: RemovalReason) {

src/cache/symbols.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ export const TRIGGER_REMOVE = Symbol('triggerRemove');
1313
/**
1414
* SPI extension for listening to eviction events.
1515
*/
16-
export const ON_EVICT = Symbol('onEvict');
16+
export const ON_MAINTENANCE = Symbol('onMaintenance');
1717

1818
/**
19-
* Shared symbol used for common code related to eviction.
19+
* Shared symbol used for common code related to maintenace.
2020
*/
21-
export const EVICT = Symbol('evict');
21+
export const MAINTENANCE = Symbol('maintenance');

src/cache/wrapped.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AbstractCache } from './abstract';
77
import { Metrics } from './metrics/metrics';
88
import { RemovalListener } from './removal-listener';
99

10-
import { ON_REMOVE, ON_EVICT, TRIGGER_REMOVE } from './symbols';
10+
import { ON_REMOVE, ON_MAINTENANCE, TRIGGER_REMOVE } from './symbols';
1111
import { RemovalReason } from './removal-reason';
1212

1313
const PARENT = Symbol('parent');
@@ -81,12 +81,12 @@ export abstract class WrappedCache<K extends KeyType, V> extends AbstractCache<K
8181
return this[PARENT].metrics;
8282
}
8383

84-
public get [ON_EVICT](): (() => void) | undefined {
85-
return this[PARENT][ON_EVICT];
84+
public get [ON_MAINTENANCE](): (() => void) | undefined {
85+
return this[PARENT][ON_MAINTENANCE];
8686
}
8787

88-
public set [ON_EVICT](listener: (() => void) | undefined) {
89-
this[PARENT][ON_EVICT] = listener;
88+
public set [ON_MAINTENANCE](listener: (() => void) | undefined) {
89+
this[PARENT][ON_MAINTENANCE] = listener;
9090
}
9191

9292
private [TRIGGER_REMOVE](key: K, value: V, reason: RemovalReason) {

0 commit comments

Comments
 (0)