49 lines
951 B
GDScript
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()
|