xiandie/util/lru.gd

49 lines
951 B
GDScript

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()