// ----------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // ----------------------------------------------------------------------- namespace ImageProcessor.Web.Caching { #region Using using System; using System.Collections.Generic; using System.Threading.Tasks; using ImageProcessor.Web.Helpers; #endregion /// /// Represents a collection of keys and values whose operations are concurrent. /// internal sealed class PersistantDictionary : LockedDictionary { #region Fields /// /// A new instance Initializes a new instance of the class. /// initialized lazily. /// private static readonly Lazy Lazy = new Lazy(() => new PersistantDictionary()); /// /// 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 PersistantDictionary() { this.LoadCache(); } #endregion /// /// Gets the current instance of the class. /// public static PersistantDictionary Instance { get { return Lazy.Value; } } #region Public /// /// Tries to remove 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 TryRemoveAsync(string key) { // No CachedImage to remove. if (!this.ContainsKey(key)) { return false; } // Remove the CachedImage. CachedImage value = this[key]; this.Remove(key); await this.SaveCacheAsync(key, value, true); return true; } /// /// 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)) { this.Add(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 false; } } /// /// Loads the cache file to populate the in memory cache. /// private void LoadCache() { lock (SyncRoot) { SQLContext.CreateDatabase(); Dictionary dictionary = SQLContext.GetImages(); foreach (KeyValuePair pair in dictionary) { this.Add(pair); } } } } }