using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CacheManager.Core; namespace PhoenixLib.Caching { public class InMemoryCacheRepository : ILongKeyCachedRepository { private static readonly string Prefix = "repo:" + typeof(T).Name.ToLower(); private static readonly ICacheManager CacheManager = CacheFactory.Build(Prefix, settings => { settings.WithSystemRuntimeCacheHandle(Prefix); }); public void Set(long id, T value) { Set(id, value, Prefix); } public void Set(long id, T value, TimeSpan timeToKeepInCache) { Set(id, value, Prefix, timeToKeepInCache); } public void Set(long id, T value, string prefix) { CacheManager.Put(ToKey(prefix, id), value); } public void Set(long id, T value, string prefix, TimeSpan timeToKeepInCache) { CacheManager.Put(new CacheItem(ToKey(prefix, id), value, ExpirationMode.Sliding, timeToKeepInCache)); } public async Task SetAsync(long id, Func> fetchDelegate) => Set(id, await fetchDelegate.Invoke(), Prefix); public async Task SetAsync(long id, Func> fetchDelegate, TimeSpan timeToKeepInCache) => CacheManager.Put(new CacheItem(ToKey(id), await fetchDelegate.Invoke(), ExpirationMode.Sliding, timeToKeepInCache)); public void Remove(long id) { CacheManager.Remove(ToKey(id)); } public T Get(long id) => Get(id, Prefix); public T Get(long id, string prefix) => CacheManager.Get(ToKey(prefix, id)); public T GetOrSet(long id, Func fetchDelegate) { CacheItem cacheItem = CacheManager.GetCacheItem(ToKey(id)); if (cacheItem != null) { return cacheItem.Value; } Set(id, fetchDelegate()); return CacheManager.Get(ToKey(id)); } public T GetOrSet(long id, Func fetchDelegate, TimeSpan timeToKeepInCache) { CacheItem cacheItem = CacheManager.GetCacheItem(ToKey(id)); if (cacheItem != null) { return cacheItem.Value; } Set(id, fetchDelegate(), timeToKeepInCache); return CacheManager.Get(ToKey(id)); } public async Task GetOrSetAsync(long id, Func> fetchDelegate) => CacheManager.GetOrAdd(ToKey(id), await fetchDelegate.Invoke()); public async Task GetOrSetAsync(long id, Func> fetchDelegate, TimeSpan timeToKeepInCache) { CacheItem cacheItem = CacheManager.GetCacheItem(ToKey(id)); if (cacheItem != null) { return cacheItem.Value; } await SetAsync(id, fetchDelegate, timeToKeepInCache); return CacheManager.Get(ToKey(id)); } public IReadOnlyList GetValues(IEnumerable keys) => GetValues(keys, Prefix); public IReadOnlyList GetValues(IEnumerable keys, string prefix) { return keys.Select(key => CacheManager.Get(ToKey(prefix, key))).Where(result => !result.Equals(default(T))) .ToList(); } private static string ToKey(long id) => ToKey(Prefix, id); private static string ToKey(string prefix, long id) => $"{prefix}:{id}"; } }