internal class LRUSample
{
public static void Test()
{
LRUCache cache = new LRUCache(2);
const string key1 = nameof(key1);
const string key2 = nameof(key2);
const string key3 = nameof(key3);
const string value1 = nameof(value1);
const string value2 = nameof(value2);
const string value3 = nameof(value3);
cache.Set(key1, value1);
cache.Set(key2, value2);
Console.WriteLine($"{key1}: {cache.Get(key1)};{key2}: {cache.Get(key2)};{key3}: {cache.Get(key3)};");
cache.Set(key3, value3);
Console.WriteLine($"{key1}: {cache.Get(key1)};{key2}: {cache.Get(key2)};{key3}: {cache.Get(key3)};");
cache.Set(key1, value1);
Console.WriteLine($"{key1}: {cache.Get(key1)};{key2}: {cache.Get(key2)};{key3}: {cache.Get(key3)};");
}
public class LRUCache
{
private class DLinkedNode
{
public string Key { get; set; }
public string Value { get; set; }
public DLinkedNode Pre { get; set; }
public DLinkedNode Post { get; set; }
}
private readonly ConcurrentDictionary<string, DLinkedNode> _cache = new ConcurrentDictionary<string, DLinkedNode>();
private int _count;
private readonly int _capacity;
private readonly DLinkedNode _head, _tail;
public LRUCache(int capacity)
{
_count = 0;
_capacity = capacity;
_head = new DLinkedNode();
_head.Pre = default;
_tail = new DLinkedNode();
_tail.Post = default;
_head.Post = _tail;
_tail.Pre = _head;
}
public string Get(string key)
{
DLinkedNode node = _cache.GetValueOrDefault(key);
if (node == null) return default;
MoveToHead(node); // 这里可以根据需要进行关闭,有些地方的实现,这里是没有的
return node.Value;
}
public void Set(string key, string value)
{
DLinkedNode node = _cache.GetValueOrDefault(key);
if (node != null)
{
node.Value = value;
MoveToHead(node);
return;
}
DLinkedNode newNode = new DLinkedNode();
newNode.Key = key;
newNode.Value = value;
_ = _cache.AddOrUpdate(key, newNode,
(_, _) =>
{
return newNode;
});
AddNode(newNode);
//++_count;
int count = Interlocked.Increment(ref _count);
if (count > _capacity)
{
DLinkedNode tail = PopTail();
_ = _cache.TryRemove(tail.Key, out _);
//--_count;
_ = Interlocked.Decrement(ref _count);
}
}
private void AddNode(DLinkedNode node)
{
node.Pre = _head;
node.Post = _head.Post;
_head.Post.Pre = node;
_head.Post = node;
}
private void RemoveNode(DLinkedNode node)
{
DLinkedNode pre = node.Pre;
DLinkedNode post = node.Post;
pre.Post = post;
post.Pre = pre;
}
private void MoveToHead(DLinkedNode node)
{
RemoveNode(node);
AddNode(node);
}
private DLinkedNode PopTail()
{
DLinkedNode res = _tail.Pre;
RemoveNode(res);
return res;
}
}
}
LRU 简单实现(C#版)
最新推荐文章于 2024-04-23 22:35:38 发布