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