@tool class_name LRU extends RefCounted # LRU 算法 var cache_size = 1 # keys. 新的在后面,旧的在前面 var lru_list = [] # key -> value var cache = {} var cache_mutex = Mutex.new() func _init(size := 8) -> void: cache_size = size func _get(key: Variant) -> Variant: var v = null cache_mutex.lock() if cache.has(key): lru_list.erase(key) lru_list.append(key) v = cache[key] cache_mutex.unlock() return v func _set(key: StringName, value: Variant) -> bool: cache_mutex.lock() if cache.has(key): lru_list.erase(key) if cache[key] != value: _release_value(cache[key]) cache[key] = value lru_list.append(key) if lru_list.size() > cache_size: var k = lru_list.pop_front() _release_value(cache[k]) cache.erase(k) cache_mutex.unlock() return true func _release_value(v: Variant) -> void: if v is Node: if not v.is_inside_tree() and is_instance_valid(v): v.queue_free() elif not v is RefCounted: v.free()