Это расширяет границы моего понимания того, как Ruby использует память, но я подозреваю, что наиболее эффективной реализацией будет список с двойной связью, где каждый доступ перемещает ключ в начало списка, а каждая вставка отбрасывает элемент если достигнут максимальный размер.
Однако, предполагая, что класс Hash
Руби уже очень эффективен, я бы поспорил, что довольно наивное решение простого добавления данных о возрасте в Hash
было бы довольно хорошим. Вот пример быстрой игрушки, которая делает это:
class Cache
attr_accessor :max_size
def initialize(max_size = 4)
@data = {}
@max_size = max_size
end
def store(key, value)
@data.store key, [0, value]
age_keys
prune
end
def read(key)
if value = @data[key]
renew(key)
age_keys
end
value
end
private # -------------------------------
def renew(key)
@data[key][0] = 0
end
def delete_oldest
m = @data.values.map{ |v| v[0] }.max
@data.reject!{ |k,v| v[0] == m }
end
def age_keys
@data.each{ |k,v| @data[k][0] += 1 }
end
def prune
delete_oldest if @data.size > @max_size
end
end
Вероятно, существует более быстрый способ найти самый старый элемент, и он не проходит тщательной проверки, но мне было бы любопытно узнать, как кто-то считает, что это сравнивается с более сложным дизайном, связанным списком или чем-то другим.