LinkedHashMapを使えば、LRUキャッシュでもFIFOキャッシュでも簡単に実現できる。 ユーザプログラムの違いは微々たるものであっても、 内部処理には大きな差があるためパフォーマンスは異なる
下のプログラムでは、エントリの上限を 700 としている。 上限を超えると自動的に削除される。
どれを削除するかについては、super の第三引数で、 最も参照時間が古いもの(LRU)とするか、登録が一番古いもの(FIFO)とするかを選べる。 第一引数は初期サイズ、HashMap ではハッシュ表に空きを作っておく必要がある。 第二引数は充足率を表す。0.75 は 25%の空きを残しておくことを意味する。
class NodeCache<K,V> extends LinkedHashMap<K,V> {
protected int limit = 700;
public NodeCache() {
super(501, 0.75F, true); // true: LRU, false: FIFO
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > limit;
}
}
使い方は、次のようにして、インスタンスを生成する。
static NodeCache<Integer,NodeBlock> cacheNodes = new NodeCache<>();
取り出しは cacheNodes.get(キー) とする。なかったときは null が返る。 下のプログラムでは、存在しなかった場合はファイルから読み込み、 cacheNodes.put(キー, 値) によって登録する。
NodeBlock blk = cacheNodes.get(blockNumber);
if (blk == null) {
blk = load(blockNumber);
if (blk == null) {
System.out.printf("no file: blockNumber=%d\n", blockNumber);
return Long.MIN_VALUE; // エラー
}
cacheNodes.put(blockNumber, blk);
}