dak ブログ

python、rubyなどのプログラミング、MySQL、サーバーの設定などの備忘録。レゴの写真も。

TypeScript でシンプルなキャッシュの実装

2024-02-23 14:45:46 | Node.js
TypeScript で最大オブジェクト数までオブジェクトを格納するシンプルなキャッシュの実装例です。
※2024/02/25 バグを修正しました

キー:オブジェクト をリストで管理し、直近でアクセスされた キー:オブジェクト をリストの末尾に移動させます。
格納する キー:オブジェクト が最大数に達すると、リストの先頭の キー:オブジェクト を削除して、新しい キー:オブジェクト を登録します。
オブジェクトを取得する際、リストの末尾に該当の キー:オブジェクト を移動させ、アクセス頻度が高いキーがキャッシュに残りやすくしています。

list の実装は以下にあります。
Typescript での双方向連結リスト
■キャッシュ
/**
 *
 * Simple Cache
 *
 */

import { Node, List } from '../list/lib/list';


export class SimpleCache {
  private _size: number = 0;
  private _max_size: number;
  private _list: List = new List();
  private _hash: any = {};
  
  public constructor(max_size: number) {
    if (max_size < 1) max_size = 1;
    this._max_size = max_size;
  }
  
  public get(key: string) {
    const node = this._hash[key];
    if (node === undefined) return undefined;
    
    this._list.remove_node(node);
    this._list.push(node);
    return node.obj;
  }
  
  public set(key: string, obj: any) {
    let node = this._hash[key];
    if (node === undefined) {
      // update obj if exists
      node = new Node([key, obj]);
      this._hash[key] = node;
      this._list.push_node(node);
      this._size += 1;
    }
    else {
      // set (key, obj)
      this._list.remove_node(node);
      this._list.push_node(node);
    }
      
    // remove head if size is max
    if (this._size > this._max_size) {
      const [old_key, old_obj] = this._list.shift();
      delete this._hash[old_key];
      this._size -= 1;
    }
    
    return obj;
  }
}

■実行例
import { SimpleCache } from './SimpleCache';

function test_set() {
  const cache = new SimpleCache(3);
  const num = 10;
  
  console.log('set');
  for (let i = 0; i < num; i++) {
    const key = `key_${i}`;
    const value = `value_${i}`;
    cache.set(key, value);
    console.log(`${key}: ${value}`);
  }

  console.log('get');
  for (let i = 0; i < num; i++) {
    const key = `key_${i}`;
    const value = cache.get(key);
    console.log(`${key}: ${value}`);
  }

  return 0;
}


function main() {
  let errs = 0;
  errs += test_set();
  
  return 0;
}

main();

■実行結果
set
key_0: value_0
key_1: value_1
key_2: value_2
key_3: value_3
key_4: value_4
key_5: value_5
key_6: value_6
key_7: value_7
key_8: value_8
key_9: value_9
get
key_0: undefined
key_1: undefined
key_2: undefined
key_3: undefined
key_4: undefined
key_5: undefined
key_6: undefined
key_7: key_7,value_7
key_8: key_8,value_8
key_9: key_9,value_9


この記事についてブログを書く
« BigQuery で "{属性名}: {属... | トップ | TypeScript で TTL つきキャ... »

Node.js」カテゴリの最新記事