1 //
2 // Copyright (c) 2010-2024 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Collections.Generic;
10 
11 namespace Antmicro.Renode.Utilities
12 {
13     public class LRUCache<TKey, TVal>
14     {
LRUCache(int limit)15         public LRUCache(int limit)
16         {
17             this.limit = limit;
18 
19             values = new Dictionary<TKey, CacheItem>();
20             ordering = new LinkedList<TKey>();
21             locker = new object();
22         }
23 
TryGetValue(TKey key, out TVal value)24         public bool TryGetValue(TKey key, out TVal value)
25         {
26             lock(locker)
27             {
28                 if(values.TryGetValue(key, out var item))
29                 {
30                     ordering.Remove(item.Position);
31                     ordering.AddFirst(item.Position);
32 
33                     value = item.Value;
34                     return true;
35                 }
36 
37                 value = default(TVal);
38                 return false;
39             }
40         }
41 
Add(TKey key, TVal value)42         public void Add(TKey key, TVal value)
43         {
44             lock(locker)
45             {
46                 var node = ordering.AddFirst(key);
47                 values[key] = new CacheItem { Position = node, Value = value };
48 
49                 if(ordering.Count > limit)
50                 {
51                     values.Remove(ordering.Last.Value);
52                     ordering.RemoveLast();
53                 }
54                 OnChanged?.Invoke();
55             }
56         }
57 
Invalidate()58         public void Invalidate()
59         {
60             lock(locker)
61             {
62                 values.Clear();
63                 ordering.Clear();
64                 OnChanged?.Invoke();
65             }
66         }
67 
68         public event Action OnChanged;
69 
70         private readonly object locker;
71         private readonly int limit;
72         private readonly Dictionary<TKey, CacheItem> values;
73         private readonly LinkedList<TKey> ordering;
74 
75         private struct CacheItem
76         {
77             public TVal Value;
78             public LinkedListNode<TKey> Position;
79         }
80     }
81 }
82 
83