BradleyUffner

CacheManager

Jun 12th, 2018
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.07 KB | None | 0 0
  1. void Main()
  2. {
  3.     var cacheManager = new CacheManager();
  4.     cacheManager.RegisterCache<int, double>("Squares",
  5.                         (int key) =>
  6.                         {
  7.                             Thread.Sleep(2000); // Simulate doing something that takes a while.
  8.                             return Math.Pow(key, 2);
  9.                         });
  10.  
  11.     // spin up multiple threads to prove that cached objects are only loaded once
  12.     Task.Run(() =>
  13.         {
  14.             cacheManager.GetItem<int, double>("Squares", 4); // looking up and caching value for 4
  15.             cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
  16.             cacheManager.GetItem<int, double>("Squares", 6); // looking up and caching value for 6
  17.             cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
  18.             cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
  19.             cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
  20.         });
  21.  
  22.     Task.Run(() =>
  23.         {
  24.             cacheManager.GetItem<int, double>("Squares", 4); // looking up and caching value for 4
  25.             cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
  26.             cacheManager.GetItem<int, double>("Squares", 6); // looking up and caching value for 6
  27.             cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
  28.             cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
  29.             cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
  30.         });
  31.  
  32.     Task.Run(() =>
  33.         {
  34.             cacheManager.GetItem<int, double>("Squares", 4); // looking up and caching value for 4
  35.             cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
  36.             cacheManager.GetItem<int, double>("Squares", 6); // looking up and caching value for 6
  37.             cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
  38.             cacheManager.GetItem<int, double>("Squares", 4); // Returning cached value for 4
  39.             cacheManager.GetItem<int, double>("Squares", 6); // Returning cached value for 6
  40.         });
  41. }
  42.  
  43. // Define other methods and classes here
  44.  
  45. public class CacheManager
  46. {
  47.  
  48.     object _lock;
  49.     private Dictionary<string, ICacheInfo> _caches;
  50.  
  51.     public CacheManager()
  52.     {
  53.         _lock = new object();
  54.         _caches = new Dictionary<string, ICacheInfo>();
  55.     }
  56.  
  57.     public void RegisterCache<TKey, TItem>(string cacheKey,
  58.                                            Func<TKey, TItem> itemLoaderFunc)
  59.     {
  60.         lock (_lock)
  61.         {
  62.             var config = new CacheConfig<TKey, TItem>(itemLoaderFunc);
  63.             _caches.Add(cacheKey, new CacheInfo<TKey, TItem>(config, new CacheData<TKey, TItem>(config)));
  64.         }
  65.     }
  66.  
  67.     public void RegisterCache<TKey, TItem>(string cacheKey,
  68.                                            Func<IEnumerable<KeyValuePair<TKey, TItem>>> listLoaderFunc)
  69.     {
  70.         lock (_lock)
  71.         {
  72.             var config = new CacheConfig<TKey, TItem>(listLoaderFunc);
  73.             _caches.Add(cacheKey, new CacheInfo<TKey, TItem>(config, null));
  74.         }
  75.     }
  76.  
  77.     public CacheData<TKey, TItem> GetCache<TKey, TItem>(string cacheKey)
  78.     {
  79.         lock (_lock)
  80.         {
  81.             var info = (CacheInfo<TKey, TItem>)_caches[cacheKey];
  82.             return (CacheData<TKey, TItem>)info.Data;
  83.         }
  84.     }
  85.  
  86.     public TItem GetItem<TKey, TItem>(string cacheKey, TKey key)
  87.     {
  88.         CacheInfo<TKey, TItem> info;
  89.         lock (_lock)
  90.         {
  91.             info = (CacheInfo<TKey, TItem>)_caches[cacheKey];
  92.         }
  93.  
  94.         var cache = info.Data;
  95.         if (cache == null)
  96.         {
  97.             cache = new CacheData<TKey, TItem>(info.Config);
  98.             cache.LoadList();
  99.         }
  100.         return cache[key];
  101.     }
  102.  
  103.     private interface ICacheInfo { }
  104.     private class CacheInfo<TKey, TItem> : ICacheInfo
  105.     {
  106.         public CacheInfo(CacheConfig<TKey, TItem> config, CacheData<TKey, TItem> data)
  107.         {
  108.             Config = config;
  109.             Data = data;
  110.         }
  111.  
  112.         public CacheData<TKey, TItem> Data { get; }
  113.         public CacheConfig<TKey, TItem> Config { get; }
  114.     }
  115. }
  116.  
  117. public class CacheConfig<TKey, TItem> : ICacheConfig
  118. {
  119.     public CacheConfig(Func<TKey, TItem> itemLoaderFunc)
  120.     {
  121.         ItemLoaderFunc = itemLoaderFunc;
  122.     }
  123.     public CacheConfig(Func<IEnumerable<KeyValuePair<TKey, TItem>>> listLoaderFunc)
  124.     {
  125.         ListLoaderFunc = listLoaderFunc;
  126.     }
  127.  
  128.     public Func<TKey, TItem> ItemLoaderFunc { get; }
  129.     public Func<IEnumerable<KeyValuePair<TKey, TItem>>> ListLoaderFunc { get; }
  130. }
  131.  
  132. public class CacheData<TKey, TItem> : ICacheData
  133. {
  134.     object _lock;
  135.     private readonly Dictionary<TKey, TItem> _items;
  136.     private readonly CacheConfig<TKey, TItem> _config;
  137.  
  138.     public CacheData(CacheConfig<TKey, TItem> config)
  139.     {
  140.         _lock = new object();
  141.         _items = new Dictionary<TKey, TItem>();
  142.         _config = config;
  143.     }
  144.  
  145.     public TItem this[TKey key]
  146.     {
  147.         get
  148.         {
  149.             lock (_lock)
  150.             {
  151.                 if (_items.TryGetValue(key, out var existingItem))
  152.                 {
  153.                     Debug.WriteLine($"returning '{existingItem}' as the cached value of '{key}'");
  154.                     return existingItem;
  155.                 }
  156.                 else
  157.                 {
  158.                     Debug.WriteLine($"looking up value for '{key}'");
  159.                     var item = _config.ItemLoaderFunc(key);
  160.  
  161.                     Debug.WriteLine($"\treturning '{item}' as the value of '{key}' and caching it for later.");
  162.                     _items.Add(key, item);
  163.                     return item;
  164.                 }
  165.             }
  166.         }
  167.     }
  168.  
  169.     public void LoadList()
  170.     {
  171.         lock (_lock)
  172.         {
  173.             _config.ListLoaderFunc();
  174.         }
  175.     }
  176. }
  177.  
  178. public interface ICacheData { }
  179. public interface ICacheConfig { }
Advertisement
Add Comment
Please, Sign In to add comment