// -----------------------------------------------------------------------
//
// 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);
}
}
}
}
}