TypeScript での TTL つきキャッシュの実装例です。
※2024/02/26 にバグを修正
オブジェクトの登録時刻がキャッシュ作成時に指定した TTL を過ぎると、キャッシュを参照した際に undefined を返却します。
キャッシュの実装で利用している list の実装は以下にあります。
Typescript での双方向連結リスト
■キャッシュの実装
■実行例
■実行結果
※2024/02/26 にバグを修正
オブジェクトの登録時刻がキャッシュ作成時に指定した TTL を過ぎると、キャッシュを参照した際に undefined を返却します。
キャッシュの実装で利用している list の実装は以下にあります。
Typescript での双方向連結リスト
■キャッシュの実装
/** * * Cache with TTL * */ import { Node, List } from '../list/lib/list'; import { SimpleCache } from 'SimpleCache'; export class TtlCache { private _max_size: number; private _list: List = new List(); private _hash: any = {}; private _ttl_msec: number; public constructor(max_size: number, ttl_msec: number) { if (max_size < 1) max_size = 1; this._max_size = max_size; this._ttl_msec = ttl_msec; } public get(key: string) { super.get(key); // obj = [key, obj, time]; const now = (new Date()).getTime(); const node = this._hash[key]; if (node === undefined) return undefined; if (node.obj[2] + this._ttl_msec < now) { // timeout this._list.remove_node(node); delete this._hash[key]; return undefined; } this._list.remove(node); this._list.push(node); return node.obj[1]; } public set(key: string, obj: any) { // obj = [key, obj, time]; // update obj if exists const now = (new Date()).getTime(); let node = this._hash[key]; if (node === undefined) { const node = new Node([key, obj, now]); this.push(node); if (this._list.length > this._max_size) { this._list.shift_node(); delete this._hash[key]; } } else { node.obj = [key, obj, now]; this.remove_node(node); this.push_node(node); } return obj; } }
■実行例
import { setTimeout } from 'timers/promises'; import { TtlCache } from './TtlCache'; async function test_set() { const cache = new TtlCache(8, 1000); const num = 10; for (let i = 0; i < num; i++) { const key = `key_${i}`; const value = `value_${i}`; cache.set(key, value); const time = (new Date()).getTime(); console.log(`${time} ${key}: ${value}`); } console.log(''); await setTimeout(500); for (let i = 0; i < num; i++) { await setTimeout(100); const key = `key_${i}`; const value = cache.get(key); const time = (new Date()).getTime(); console.log(`${time} ${key}: ${value}`); } return 0; } async function main() { let errs = 0; errs += await test_set(); return 0; } main();
■実行結果
1708956725261 key_0: value_0 1708956725262 key_1: value_1 1708956725262 key_2: value_2 1708956725262 key_3: value_3 1708956725262 key_4: value_4 1708956725262 key_5: value_5 1708956725262 key_6: value_6 1708956725262 key_7: value_7 1708956725262 key_8: value_8 1708956725262 key_9: value_9 1708956725870 key_0: undefined 1708956725973 key_1: undefined 1708956726076 key_2: value_2 1708956726179 key_3: value_3 1708956726280 key_4: undefined 1708956726384 key_5: undefined 1708956726492 key_6: undefined 1708956726595 key_7: undefined 1708956726699 key_8: undefined 1708956726806 key_9: undefined