|
|
from collections import OrderedDict |
|
|
|
|
|
class LRUCache: |
|
|
""" |
|
|
Least Recently Used (LRU) Cache. |
|
|
設計書で言及されているホットキャッシュのシンプルな実装です。 |
|
|
""" |
|
|
|
|
|
def __init__(self, max_size: int = 20): |
|
|
""" |
|
|
Args: |
|
|
max_size (int): キャッシュの最大サイズ。 |
|
|
""" |
|
|
if max_size <= 0: |
|
|
raise ValueError("max_size must be a positive integer.") |
|
|
self.max_size = max_size |
|
|
self._cache = OrderedDict() |
|
|
|
|
|
def __contains__(self, key): |
|
|
"'key in cache' 構文をサポートします。" |
|
|
return key in self._cache |
|
|
|
|
|
def __getitem__(self, key): |
|
|
"キーに対応する値を取得し、そのキーを最も最近使用されたものとしてマークします。" |
|
|
if key not in self._cache: |
|
|
raise KeyError(f"Key '{key}' not found in cache.") |
|
|
|
|
|
|
|
|
self._cache.move_to_end(key) |
|
|
return self._cache[key] |
|
|
|
|
|
def __setitem__(self, key, value): |
|
|
"キーと値のペアをキャッシュに追加します。" |
|
|
if key in self._cache: |
|
|
|
|
|
self._cache.move_to_end(key) |
|
|
|
|
|
self._cache[key] = value |
|
|
|
|
|
|
|
|
if len(self._cache) > self.max_size: |
|
|
self._cache.popitem(last=False) |
|
|
|
|
|
def get(self, key, default=None): |
|
|
"キーが存在しない場合に例外を送出しないバージョンの get です。" |
|
|
if key in self._cache: |
|
|
return self[key] |
|
|
return default |
|
|
|
|
|
@property |
|
|
def size(self): |
|
|
"現在のキャッシュサイズを返します。" |
|
|
return len(self._cache) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
cache = LRUCache(max_size=3) |
|
|
|
|
|
print("--- Cache Operations ---") |
|
|
cache['coord_1'] = "Tile 1 Data" |
|
|
cache['coord_2'] = "Tile 2 Data" |
|
|
cache['coord_3'] = "Tile 3 Data" |
|
|
print("Cache after adding 3 items:", cache._cache) |
|
|
|
|
|
|
|
|
print("\nAccessing 'coord_1'...") |
|
|
_ = cache['coord_1'] |
|
|
print("Cache state:", cache._cache) |
|
|
|
|
|
|
|
|
print("\nAdding 'coord_4', expecting 'coord_2' to be evicted...") |
|
|
cache['coord_4'] = "Tile 4 Data" |
|
|
print("Cache state:", cache._cache) |
|
|
|
|
|
print("\nIs 'coord_2' in cache?", 'coord_2' in cache) |
|
|
print("Is 'coord_3' in cache?", 'coord_3' in cache) |
|
|
print("Current cache size:", cache.size) |
|
|
|