-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
142 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,96 @@ | ||
import { Cache } from './cache' | ||
import { TTLParams, Keyable } from '../types' | ||
|
||
/** | ||
* ### About | ||
* This cache removes values based on TTL (Time-To-Live). | ||
* | ||
* If you store a key with a TTL of 1 second, that key will be removed after 1 second. | ||
* | ||
* ### Example | ||
* ```typescript | ||
* const cache = new TTLCache({maxsize: 2, ttl: 1000}) | ||
* | ||
* //store some keys | ||
* | ||
* //default ttl will be used (1000) | ||
* cache['foo'] = 'bar' | ||
* | ||
* //custom ttl will be used (500) | ||
* cache.set('bar', 'foo', 500) | ||
* | ||
* //store another key | ||
* cache['baz'] = 'foo' | ||
* //throws SizeError, you need to delete some key to store another key | ||
* | ||
* //will log: undefined | ||
* setTimeout(() => console.log(cache['bar']), 1000) | ||
* | ||
* ``` | ||
*/ | ||
export class TTLCache extends Cache { | ||
protected _timeouts: Map<Keyable, NodeJS.Timeout> | ||
protected _defaultTTL?: number | ||
|
||
/** | ||
* Creates a new TTLCache. | ||
*/ | ||
constructor(params: TTLParams = {}){ | ||
super({ | ||
maxsize: params.maxsize, | ||
useClones: params.useClones | ||
}) | ||
|
||
this._timeouts = new Map() | ||
if (params.ttl) { | ||
this._defaultTTL = params.ttl | ||
} | ||
} | ||
|
||
set(key: Keyable, value: unknown, ttl = 0){ | ||
super.set(key, value) | ||
|
||
if (this._timeouts.has(key)) { | ||
clearTimeout( | ||
this._timeouts.get(key) | ||
) | ||
|
||
this._timeouts.delete(key) | ||
} | ||
|
||
if (ttl || this._defaultTTL){ | ||
this._timeouts.set( | ||
key, | ||
setTimeout( | ||
() => { | ||
this.del(key) | ||
this.emit('expired', key) | ||
}, | ||
ttl || this._defaultTTL | ||
) | ||
) | ||
} | ||
} | ||
|
||
del(key: Keyable){ | ||
super.del(key) | ||
if (this._timeouts.has(key)) { | ||
clearTimeout( | ||
this._timeouts.get(key) | ||
) | ||
this._timeouts.delete(key) | ||
} | ||
} | ||
} | ||
import { Cache } from './cache' | ||
import { TTLParams, Keyable } from '../types' | ||
|
||
/** | ||
* ### About | ||
* This cache removes values based on TTL (Time-To-Live). | ||
* | ||
* If you store a key with a TTL of 1 second, that key will be removed after 1 second. | ||
* | ||
* ### Example | ||
* ```typescript | ||
* const cache = new TTLCache({maxsize: 2, ttl: 1000}) | ||
* | ||
* //store some keys | ||
* | ||
* //default ttl will be used (1000) | ||
* cache['foo'] = 'bar' | ||
* | ||
* //custom ttl will be used (500) | ||
* cache.set('bar', 'foo', 500) | ||
* | ||
* //store another key | ||
* cache['baz'] = 'foo' | ||
* //throws SizeError, you need to delete some key to store another key | ||
* | ||
* //will log: undefined | ||
* setTimeout(() => console.log(cache['bar']), 1000) | ||
* | ||
* ``` | ||
*/ | ||
export class TTLCache extends Cache { | ||
protected _timeouts: Map<Keyable, number> | ||
protected _defaultTTL?: number | ||
protected _checkInterval?: number | ||
private _intervalId?: NodeJS.Timeout | ||
|
||
/** | ||
* Creates a new TTLCache. | ||
*/ | ||
constructor(params: TTLParams = {}){ | ||
super({ | ||
maxsize: params.maxsize, | ||
useClones: params.useClones | ||
}) | ||
|
||
this._timeouts = new Map() | ||
this._checkInterval = params.checkPeriod ?? 60000 | ||
if (params.ttl) { | ||
this._defaultTTL = params.ttl | ||
} | ||
|
||
setInterval(() => this._checkExpired(), this._checkInterval) | ||
} | ||
|
||
set(key: Keyable, value: unknown, ttl = 0){ | ||
super.set(key, value) | ||
|
||
if (this._timeouts.has(key)) { | ||
this._timeouts.delete(key) | ||
} | ||
|
||
if (ttl || this._defaultTTL){ | ||
this._timeouts.set( | ||
key, | ||
Date.now() + (ttl ?? this._defaultTTL) | ||
) | ||
} | ||
} | ||
|
||
del(key: Keyable){ | ||
super.del(key) | ||
if (this._timeouts.has(key)) { | ||
this._timeouts.delete(key) | ||
} | ||
} | ||
|
||
private _clearInterval() { | ||
if (this._intervalId) { | ||
clearInterval(this._intervalId) | ||
} | ||
} | ||
|
||
destroy() { | ||
this._clearInterval() | ||
} | ||
|
||
private _checkExpired() { | ||
const now = Date.now() | ||
for (const [key, expirationTime] of this._timeouts.entries()) { | ||
if (expirationTime <= now) { | ||
this.del(key) | ||
this.emit('expired', key) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,46 @@ | ||
export interface CacheParams { | ||
/** | ||
* Defines the maximum number of keys that will be stored. | ||
* In some caches, this parameter is required; the default is `undefined`. | ||
*/ | ||
maxsize?: number | ||
|
||
/** | ||
* If true, a **deep copy** of all data will be created before storing. | ||
* The default is `false`. | ||
*/ | ||
useClones?: boolean | ||
} | ||
|
||
export interface TTLParams extends CacheParams { | ||
/** | ||
* The **Time to Live** of the cache in **ms**. | ||
* If you don't provide the `ttl` parameter in the `set` function, this `ttl` will be used. | ||
* If not provided, the cache will not delete keys. | ||
*/ | ||
ttl?: number | ||
} | ||
|
||
export interface RRParams extends CacheParams { | ||
/** | ||
* Random logic for the deletion of keys in the cache. | ||
* The default is `Math.floor(Math.random() * length)`. | ||
*/ | ||
randomLogic?: (length: number) => number | ||
} | ||
|
||
export type ParamsLike = CacheParams | TTLParams | RRParams | ||
|
||
export interface CachePoolParams { | ||
/** | ||
* Defines the maximum number of caches that will be stored. | ||
* This parameter is optional; the default is `undefined`. | ||
*/ | ||
maxsize?: number | ||
} | ||
export interface CacheParams { | ||
/** | ||
* Defines the maximum number of keys that will be stored. | ||
* In some caches, this parameter is required; the default is `undefined`. | ||
*/ | ||
maxsize?: number | ||
|
||
/** | ||
* If true, a **deep copy** of all data will be created before storing. | ||
* The default is `false`. | ||
*/ | ||
useClones?: boolean | ||
} | ||
|
||
export interface TTLParams extends CacheParams { | ||
/** | ||
* The **Time to Live** of the cache in **ms**. | ||
* If you don't provide the `ttl` parameter in the `set` function, this `ttl` will be used. | ||
* If not provided, the cache will not delete keys. | ||
*/ | ||
ttl?: number | ||
|
||
/** | ||
* The **Check Period** to verify if key is expired or not. | ||
* **default:** 60000 - 1 minute | ||
*/ | ||
checkPeriod?: number | ||
} | ||
|
||
export interface RRParams extends CacheParams { | ||
/** | ||
* Random logic for the deletion of keys in the cache. | ||
* The default is `Math.floor(Math.random() * length)`. | ||
*/ | ||
randomLogic?: (length: number) => number | ||
} | ||
|
||
export type ParamsLike = CacheParams | TTLParams | RRParams | ||
|
||
export interface CachePoolParams { | ||
/** | ||
* Defines the maximum number of caches that will be stored. | ||
* This parameter is optional; the default is `undefined`. | ||
*/ | ||
maxsize?: number | ||
} |