using System; using System.Collections.Generic; using System.Threading; namespace Kruzya.TelegramBot.Core.Cache; public class MemoryCache : ICacheStorage { /// /// Represents a cache entry in internal dictionary. /// /// internal struct CacheEntry { public TVal Value; public DateTime Created; public int ExpiresAt; public bool IsExpired() { if (ExpiresAt == Timeout.Infinite) { return false; } return (Created.AddSeconds(ExpiresAt)) < DateTime.Now; } } /// /// /// private readonly Dictionary> _dict = new(); /// /// The TTL for all entries if not set. /// private int _defaultTtl; public MemoryCache() : this(Timeout.Infinite) { } public MemoryCache(int defaultTtl) { _defaultTtl = defaultTtl; } public bool TryGetValue(TKey key, out TValue value) { value = default; if (!_dict.ContainsKey(key)) { return false; } CacheEntry temp; if (!_dict.TryGetValue(key, out temp)) { return false; } if (temp.IsExpired()) { _dict.Remove(key); return false; } value = temp.Value; return true; } public TValue GetOr(TKey key, TValue defValue = default) { var doesExist = TryGetValue(key, out var value); if (!doesExist) { value = defValue; } return value; } public void SetValue(TKey key, TValue value) { SetValue(key, value, _defaultTtl); } public void SetValue(TKey key, TValue value, int timeToLive) { if (_dict.ContainsKey(key)) { _dict.Remove(key); } _dict.Add(key, new CacheEntry() { Created = DateTime.Now, ExpiresAt = timeToLive, Value = value }); } }