File size: 2,895 Bytes
937ff6a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
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__":
# サイズ3のキャッシュを作成
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)
# coord_1にアクセス -> 最近使用されたアイテムになる
print("\nAccessing 'coord_1'...")
_ = cache['coord_1']
print("Cache state:", cache._cache)
# 新しいアイテムを追加 -> 最も古く使用されていない 'coord_2' が削除される
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)
|