// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Web.Caching { #region Using using System; using System.Threading.Tasks; #endregion /// /// Represents an in memory collection of keys and values whose operations are concurrent. /// internal sealed class MemoryCache { #region Fields /// /// A new instance Initializes a new instance of the class. /// initialized lazily. /// private static readonly Lazy Lazy = new Lazy(() => new MemoryCache()); /// /// The object to lock against. /// private static readonly object SyncRoot = new object(); #endregion #region Constructors /// /// Prevents a default instance of the class /// from being created. /// private MemoryCache() { this.LoadCache(); } #endregion /// /// Gets the current instance of the class. /// public static MemoryCache Instance { get { return Lazy.Value; } } #region Public /// /// Gets the associated with the specified key. /// /// /// The key of the value to get. /// /// /// The matching the given key if the contains an element with /// the specified key; otherwise, null. /// public async Task GetValueAsync(string key) { CachedImage cachedImage = (CachedImage)CacheManager.GetItem(key); if (cachedImage == null) { cachedImage = await SQLContext.GetImageAsync(key); if (cachedImage != null) { CacheManager.AddItem(key, cachedImage); } } return cachedImage; } /// /// Removes the value associated with the specified key. /// /// /// The key of the item to remove. /// /// /// true if the removes an element with /// the specified key; otherwise, false. /// public async Task RemoveAsync(string key) { if (await this.SaveCacheAsync(key, null, true) > 0) { CacheManager.RemoveItem(key); return true; } return false; } /// /// Adds the specified key and value to the dictionary or returns the value if it exists. /// /// /// The key. /// /// /// The cached image to add. /// /// /// The value of the item to add or get. /// public async Task AddAsync(string key, CachedImage cachedImage) { // Add the CachedImage. if (await this.SaveCacheAsync(key, cachedImage, false) > 0) { CacheManager.AddItem(key, cachedImage); } return cachedImage; } #endregion /// /// Saves the in memory cache to the file-system. /// /// /// The key. /// /// /// The cached Image. /// /// /// The remove. /// /// /// true, if the dictionary is saved to the file-system; otherwise, false. /// private async Task SaveCacheAsync(string key, CachedImage cachedImage, bool remove) { try { if (remove) { return await SQLContext.RemoveImageAsync(key); } return await SQLContext.AddImageAsync(cachedImage); } catch { return 0; } } /// /// Loads the cache file to populate the in memory cache. /// private void LoadCache() { lock (SyncRoot) { SQLContext.CreateDatabase(); } } } }