From 4a4ce10c04e0660b213edd61bb6d247caf62833b Mon Sep 17 00:00:00 2001 From: Sergey Gut Date: Tue, 3 Mar 2020 11:36:00 +0400 Subject: [PATCH] Initial work on cache --- Core/Cache/ICacheStorage.cs | 10 ++++ Core/Cache/MemoryCache.cs | 93 +++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 Core/Cache/ICacheStorage.cs create mode 100644 Core/Cache/MemoryCache.cs diff --git a/Core/Cache/ICacheStorage.cs b/Core/Cache/ICacheStorage.cs new file mode 100644 index 0000000..016f554 --- /dev/null +++ b/Core/Cache/ICacheStorage.cs @@ -0,0 +1,10 @@ +using System; + +namespace Kruzya.TelegramBot.Core.Cache +{ + public interface ICacheStorage + { + public bool TryGetValue(TKey key, ref TValue value); + public void SetValue(TKey key, TValue value, int timeToLive); + } +} \ No newline at end of file diff --git a/Core/Cache/MemoryCache.cs b/Core/Cache/MemoryCache.cs new file mode 100644 index 0000000..b4afc69 --- /dev/null +++ b/Core/Cache/MemoryCache.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +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 Dictionary> dict = new Dictionary>(); + + /// + /// 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, ref TValue value) + { + 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 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 + }); + } + } +} \ No newline at end of file