Add Git overlay, operation tools, and virtualized preview so large folders stay responsive.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
63
src/Explorer.Application/LruCache.cs
Normal file
63
src/Explorer.Application/LruCache.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
namespace Explorer.Application;
|
||||
|
||||
public sealed class LruCache<TKey, TValue>
|
||||
where TKey : notnull
|
||||
{
|
||||
private readonly int _capacity;
|
||||
private readonly Dictionary<TKey, LinkedListNode<(TKey Key, TValue Value)>> _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<TKey, LinkedListNode<(TKey, TValue)>>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user