Files
telegram-bot/Core/Cache/MemoryCache.cs
T

103 lines
2.2 KiB
C#
Raw Normal View History

2020-03-03 11:36:00 +04:00
using System;
using System.Collections.Generic;
using System.Threading;
2023-07-29 15:14:52 +03:00
namespace Kruzya.TelegramBot.Core.Cache;
public class MemoryCache<TKey, TValue> : ICacheStorage<TKey, TValue>
2020-03-03 11:36:00 +04:00
{
2023-07-29 15:14:52 +03:00
/// <summary>
/// Represents a cache entry in internal dictionary.
/// </summary>
/// <typeparam name="TVal"></typeparam>
internal struct CacheEntry<TVal>
2020-03-03 11:36:00 +04:00
{
2023-07-29 15:14:52 +03:00
public TVal Value;
public DateTime Created;
public int ExpiresAt;
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
public bool IsExpired()
{
if (ExpiresAt == Timeout.Infinite)
2020-03-03 11:36:00 +04:00
{
2023-07-29 15:14:52 +03:00
return false;
2020-03-03 11:36:00 +04:00
}
2023-07-29 15:14:52 +03:00
return (Created.AddSeconds(ExpiresAt)) < DateTime.Now;
2020-03-03 11:36:00 +04:00
}
2023-07-29 15:14:52 +03:00
}
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
/// <summary>
///
/// </summary>
private readonly Dictionary<TKey, CacheEntry<TValue>> _dict = new();
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
/// <summary>
/// The TTL for all entries if not set.
/// </summary>
private int _defaultTtl;
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
public MemoryCache() : this(Timeout.Infinite)
{
}
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
public MemoryCache(int defaultTtl)
{
_defaultTtl = defaultTtl;
}
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
public bool TryGetValue(TKey key, out TValue value)
{
value = default;
if (!_dict.ContainsKey(key))
2020-03-03 11:36:00 +04:00
{
2023-07-29 15:14:52 +03:00
return false;
2020-03-03 11:36:00 +04:00
}
2023-07-29 15:14:52 +03:00
CacheEntry<TValue> temp;
if (!_dict.TryGetValue(key, out temp))
2023-01-18 02:07:48 +02:00
{
2023-07-29 15:14:52 +03:00
return false;
}
2023-01-18 02:07:48 +02:00
2023-07-29 15:14:52 +03:00
if (temp.IsExpired())
{
_dict.Remove(key);
return false;
2023-01-18 02:07:48 +02:00
}
2023-07-29 15:14:52 +03:00
value = temp.Value;
return true;
}
public TValue GetOr(TKey key, TValue defValue = default)
{
var doesExist = TryGetValue(key, out var value);
if (!doesExist)
2020-03-03 11:36:00 +04:00
{
2023-07-29 15:14:52 +03:00
value = defValue;
2020-03-03 11:36:00 +04:00
}
2023-07-29 15:14:52 +03:00
return value;
}
public void SetValue(TKey key, TValue value)
{
SetValue(key, value, _defaultTtl);
}
2020-03-03 11:36:00 +04:00
2023-07-29 15:14:52 +03:00
public void SetValue(TKey key, TValue value, int timeToLive)
{
if (_dict.ContainsKey(key))
2020-03-03 11:36:00 +04:00
{
2023-07-29 15:14:52 +03:00
_dict.Remove(key);
2020-03-03 11:36:00 +04:00
}
2023-07-29 15:14:52 +03:00
_dict.Add(key, new CacheEntry<TValue>()
{
Created = DateTime.Now,
ExpiresAt = timeToLive,
Value = value
});
2020-03-03 11:36:00 +04:00
}
}