Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void Main()
- {
- var cacheManager = new CacheManager();
- cacheManager.RegisterCache<int, double>("Squares",
- (int key) =>
- {
- Thread.Sleep(2000); // Simulate doing something that takes a while.
- return Math.Pow(key, 2);
- });
- // spin up multiple threads to prove that cached objects are only loaded once
- Task.Run(() =>
- {
- cacheManager.GetItem<int, double>("Squares", 4); // looking up and caching value for 4
- cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
- cacheManager.GetItem<int, double>("Squares", 6); // looking up and caching value for 6
- cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
- cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
- cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
- });
- Task.Run(() =>
- {
- cacheManager.GetItem<int, double>("Squares", 4); // looking up and caching value for 4
- cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
- cacheManager.GetItem<int, double>("Squares", 6); // looking up and caching value for 6
- cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
- cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
- cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
- });
- Task.Run(() =>
- {
- cacheManager.GetItem<int, double>("Squares", 4); // looking up and caching value for 4
- cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
- cacheManager.GetItem<int, double>("Squares", 6); // looking up and caching value for 6
- cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
- cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
- cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
- });
- }
- // Define other methods and classes here
- public class CacheManager
- {
- object _lock;
- private Dictionary<string, ICacheInfo> _caches;
- public CacheManager()
- {
- _lock = new object();
- _caches = new Dictionary<string, ICacheInfo>();
- }
- public void RegisterCache<TKey, TItem>(string cacheKey,
- Func<TKey, TItem> itemLoaderFunc)
- {
- lock (_lock)
- {
- var config = new CacheConfig<TKey, TItem>(itemLoaderFunc);
- _caches.Add(cacheKey, new CacheInfo<TKey, TItem>(config, new CacheData<TKey, TItem>(config)));
- }
- }
- public void RegisterCache<TKey, TItem>(string cacheKey,
- Func<IEnumerable<KeyValuePair<TKey, TItem>>> listLoaderFunc)
- {
- lock (_lock)
- {
- var config = new CacheConfig<TKey, TItem>(listLoaderFunc);
- _caches.Add(cacheKey, new CacheInfo<TKey, TItem>(config, null));
- }
- }
- public CacheData<TKey, TItem> GetCache<TKey, TItem>(string cacheKey)
- {
- lock (_lock)
- {
- var info = (CacheInfo<TKey, TItem>)_caches[cacheKey];
- return (CacheData<TKey, TItem>)info.Data;
- }
- }
- public TItem GetItem<TKey, TItem>(string cacheKey, TKey key)
- {
- CacheInfo<TKey, TItem> info;
- lock (_lock)
- {
- info = (CacheInfo<TKey, TItem>)_caches[cacheKey];
- }
- var cache = info.Data;
- if (cache == null)
- {
- cache = new CacheData<TKey, TItem>(info.Config);
- cache.LoadList();
- }
- return cache[key];
- }
- private interface ICacheInfo { }
- private class CacheInfo<TKey, TItem> : ICacheInfo
- {
- public CacheInfo(CacheConfig<TKey, TItem> config, CacheData<TKey, TItem> data)
- {
- Config = config;
- Data = data;
- }
- public CacheData<TKey, TItem> Data { get; }
- public CacheConfig<TKey, TItem> Config { get; }
- }
- }
- public class CacheConfig<TKey, TItem> : ICacheConfig
- {
- public CacheConfig(Func<TKey, TItem> itemLoaderFunc)
- {
- ItemLoaderFunc = itemLoaderFunc;
- }
- public CacheConfig(Func<IEnumerable<KeyValuePair<TKey, TItem>>> listLoaderFunc)
- {
- ListLoaderFunc = listLoaderFunc;
- }
- public Func<TKey, TItem> ItemLoaderFunc { get; }
- public Func<IEnumerable<KeyValuePair<TKey, TItem>>> ListLoaderFunc { get; }
- }
- public class CacheData<TKey, TItem> : ICacheData
- {
- object _lock;
- private readonly Dictionary<TKey, TItem> _items;
- private readonly CacheConfig<TKey, TItem> _config;
- public CacheData(CacheConfig<TKey, TItem> config)
- {
- _lock = new object();
- _items = new Dictionary<TKey, TItem>();
- _config = config;
- }
- public TItem this[TKey key]
- {
- get
- {
- lock (_lock)
- {
- if (_items.TryGetValue(key, out var existingItem))
- {
- Debug.WriteLine($"returning '{existingItem}' as the cached value of '{key}'");
- return existingItem;
- }
- else
- {
- Debug.WriteLine($"looking up value for '{key}'");
- var item = _config.ItemLoaderFunc(key);
- Debug.WriteLine($"\treturning '{item}' as the value of '{key}' and caching it for later.");
- _items.Add(key, item);
- return item;
- }
- }
- }
- }
- public void LoadList()
- {
- lock (_lock)
- {
- _config.ListLoaderFunc();
- }
- }
- }
- public interface ICacheData { }
- public interface ICacheConfig { }
Advertisement
Add Comment
Please, Sign In to add comment