Ionite
1 year ago
committed by
GitHub
9 changed files with 206 additions and 15 deletions
@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic; |
||||
using System.Runtime.CompilerServices; |
||||
|
||||
namespace StabilityMatrix.Helper.Cache; |
||||
|
||||
// ReSharper disable once InconsistentNaming |
||||
public class LRUCache<TK,TV> where TK : notnull |
||||
{ |
||||
private readonly int capacity; |
||||
private readonly Dictionary<TK, LinkedListNode<LRUCacheItem<TK, TV>>> cacheMap = new(); |
||||
private readonly LinkedList<LRUCacheItem<TK, TV>> lruList = new(); |
||||
|
||||
public LRUCache(int capacity) |
||||
{ |
||||
this.capacity = capacity; |
||||
} |
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)] |
||||
public TV? Get(TK key) |
||||
{ |
||||
if (cacheMap.TryGetValue(key, out var node)) |
||||
{ |
||||
var value = node.Value.Value; |
||||
lruList.Remove(node); |
||||
lruList.AddLast(node); |
||||
return value; |
||||
} |
||||
return default; |
||||
} |
||||
|
||||
public bool Get(TK key, out TV? value) |
||||
{ |
||||
value = Get(key); |
||||
return value != null; |
||||
} |
||||
|
||||
[MethodImpl(MethodImplOptions.Synchronized)] |
||||
public void Add(TK key, TV val) |
||||
{ |
||||
if (cacheMap.TryGetValue(key, out var existingNode)) |
||||
{ |
||||
lruList.Remove(existingNode); |
||||
} |
||||
else if (cacheMap.Count >= capacity) |
||||
{ |
||||
RemoveFirst(); |
||||
} |
||||
|
||||
var cacheItem = new LRUCacheItem<TK, TV>(key, val); |
||||
var node = new LinkedListNode<LRUCacheItem<TK, TV>>(cacheItem); |
||||
lruList.AddLast(node); |
||||
cacheMap[key] = node; |
||||
} |
||||
|
||||
private void RemoveFirst() |
||||
{ |
||||
// Remove from LRUPriority |
||||
var node = lruList.First; |
||||
lruList.RemoveFirst(); |
||||
|
||||
if (node == null) return; |
||||
|
||||
// Remove from cache |
||||
cacheMap.Remove(node.Value.Key); |
||||
} |
||||
} |
||||
|
||||
// ReSharper disable once InconsistentNaming |
||||
internal class LRUCacheItem<TK,TV> |
||||
{ |
||||
public LRUCacheItem(TK k, TV v) |
||||
{ |
||||
Key = k; |
||||
Value = v; |
||||
} |
||||
public TK Key; |
||||
public TV Value; |
||||
} |
Loading…
Reference in new issue