-
Notifications
You must be signed in to change notification settings - Fork 372
Expand file tree
/
Copy pathSimpleLRUCache.cs
More file actions
77 lines (66 loc) · 1.6 KB
/
SimpleLRUCache.cs
File metadata and controls
77 lines (66 loc) · 1.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
namespace FFImageLoading.Cache
{
public class SimpleLRUCache<TKey, TValue>
{
private readonly object _lock = new object();
private readonly int _capacity;
private readonly LinkedList<CacheItem<TKey, TValue>> _lru = new LinkedList<CacheItem<TKey, TValue>>();
private readonly Dictionary<TKey, LinkedListNode<CacheItem<TKey, TValue>>> _cache = new Dictionary<TKey, LinkedListNode<CacheItem<TKey, TValue>>>();
public SimpleLRUCache(int capacity)
{
if (capacity < 1)
throw new ArgumentException("Capacity must be greater than zero.");
_capacity = capacity;
}
public void AddOrReplace(TKey key, TValue value)
{
lock(_lock)
{
if (_cache.TryGetValue(key, out var node))
{
node.Value.Value = value;
_lru.Remove(node);
}
else
{
if (_capacity == _lru.Count)
{
var lastNode = _lru.First;
_cache.Remove(lastNode.Value.Key);
_lru.RemoveFirst();
}
node = new LinkedListNode<CacheItem<TKey, TValue>>(new CacheItem<TKey, TValue>(key, value));
_cache.Add(key, node);
}
_lru.AddLast(node);
}
}
public bool TryGetValue(TKey key, out TValue value)
{
lock (_lock)
{
if (_cache.TryGetValue(key, out var node))
{
_lru.Remove(node);
_lru.AddLast(node);
value = node.Value.Value;
return true;
}
value = default;
return false;
}
}
private class CacheItem<K, V>
{
public K Key { get; }
public V Value { get; set; }
public CacheItem(K key, V value)
{
this.Key = key;
this.Value = value;
}
}
}
}