namespace Explorer.Application; public sealed class LruCache where TKey : notnull { private readonly int _capacity; private readonly Dictionary> _map; private readonly LinkedList<(TKey Key, TValue Value)> _order; private readonly object _gate = new(); public LruCache(int capacity) { ArgumentOutOfRangeException.ThrowIfLessThan(capacity, 1); _capacity = capacity; _map = new Dictionary>(capacity); _order = new LinkedList<(TKey, TValue)>(); } public int Count { get { lock (_gate) return _map.Count; } } public bool TryGet(TKey key, out TValue value) { lock (_gate) { if (_map.TryGetValue(key, out var node)) { _order.Remove(node); _order.AddFirst(node); value = node.Value.Value; return true; } } value = default!; return false; } public void Set(TKey key, TValue value) { lock (_gate) { if (_map.TryGetValue(key, out var existing)) { _order.Remove(existing); existing.Value = (key, value); _order.AddFirst(existing); return; } var node = _order.AddFirst((key, value)); _map[key] = node; while (_map.Count > _capacity) { var last = _order.Last!; _order.RemoveLast(); _map.Remove(last.Value.Key); } } } }