mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
8.6 KiB
239 lines
8.6 KiB
// --------------------------------------------------------------------------------------------------------------------
|
|
// <copyright file="MemCache.cs" company="James South">
|
|
// Copyright (c) James South.
|
|
// Licensed under the Apache License, Version 2.0.
|
|
// </copyright>
|
|
// <summary>
|
|
// Encapsulates methods that allow the caching and retrieval of objects from the in memory cache.
|
|
// </summary>
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
namespace ImageProcessor.Web.Caching
|
|
{
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.Caching;
|
|
|
|
/// <summary>
|
|
/// Encapsulates methods that allow the caching and retrieval of objects from the in memory cache.
|
|
/// </summary>
|
|
internal static class MemCache
|
|
{
|
|
/// <summary>
|
|
/// The cache
|
|
/// </summary>
|
|
private static readonly ObjectCache Cache = MemoryCache.Default;
|
|
|
|
/// <summary>
|
|
/// An internal list of cache keys to allow bulk removal.
|
|
/// </summary>
|
|
private static readonly ConcurrentDictionary<string, string> CacheItems = new ConcurrentDictionary<string, string>();
|
|
|
|
/// <summary>
|
|
/// Adds an item to the cache.
|
|
/// </summary>
|
|
/// <param name="key">
|
|
/// A unique identifier for the cache entry.
|
|
/// </param>
|
|
/// <param name="value">
|
|
/// The object to insert.
|
|
/// </param>
|
|
/// <param name="policy">
|
|
/// Optional. An <see cref="T:System.Runtime.Caching.CacheItemPolicy"/> object that contains eviction details for the cache entry. This object
|
|
/// provides more options for eviction than a simple absolute expiration. The default value for the optional parameter
|
|
/// is null.
|
|
/// </param>
|
|
/// <param name="regionName">
|
|
/// Optional. A named region in the cache to which the cache entry can be added,
|
|
/// if regions are implemented. The default value for the optional parameter
|
|
/// is null.
|
|
/// </param>
|
|
/// <returns>
|
|
/// True if the insertion try succeeds, or false if there is an already an entry
|
|
/// in the cache with the same key as key.
|
|
/// </returns>
|
|
public static bool AddItem(string key, object value, CacheItemPolicy policy = null, string regionName = null)
|
|
{
|
|
bool isAdded;
|
|
|
|
lock (Cache)
|
|
{
|
|
if (policy == null)
|
|
{
|
|
// Create a new cache policy with the default values
|
|
policy = new CacheItemPolicy();
|
|
}
|
|
|
|
try
|
|
{
|
|
Cache.Set(key, value, policy, regionName);
|
|
isAdded = true;
|
|
}
|
|
catch
|
|
{
|
|
isAdded = false;
|
|
}
|
|
|
|
if (isAdded)
|
|
{
|
|
CacheItems[key] = regionName;
|
|
}
|
|
}
|
|
|
|
return isAdded;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fetches an item matching the given key from the cache.
|
|
/// </summary>
|
|
/// <param name="key">
|
|
/// A unique identifier for the cache entry.
|
|
/// </param>
|
|
/// <param name="regionName">
|
|
/// Optional. A named region in the cache to which the cache entry can be added,
|
|
/// if regions are implemented. The default value for the optional parameter
|
|
/// is null.
|
|
/// </param>
|
|
/// <returns>
|
|
/// The cache entry that is identified by key.
|
|
/// </returns>
|
|
public static object GetItem(string key, string regionName = null)
|
|
{
|
|
lock (Cache)
|
|
{
|
|
return Cache.Get(key, regionName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates an item to the cache.
|
|
/// </summary>
|
|
/// <param name="key">
|
|
/// A unique identifier for the cache entry.
|
|
/// </param>
|
|
/// <param name="value">
|
|
/// The object to insert.
|
|
/// </param>
|
|
/// <param name="policy">
|
|
/// Optional. An <see cref="T:System.Runtime.Caching.CacheItemPolicy"/> object that contains eviction details for the cache entry. This object
|
|
/// provides more options for eviction than a simple absolute expiration. The default value for the optional parameter
|
|
/// is null.
|
|
/// </param>
|
|
/// <param name="regionName">
|
|
/// Optional. A named region in the cache to which the cache entry can be added,
|
|
/// if regions are implemented. The default value for the optional parameter
|
|
/// is null.
|
|
/// </param>
|
|
/// <returns>
|
|
/// True if the update try succeeds, or false if there is an already an entry
|
|
/// in the cache with the same key as key.
|
|
/// </returns>
|
|
public static bool UpdateItem(string key, object value, CacheItemPolicy policy = null, string regionName = null)
|
|
{
|
|
bool isUpDated = true;
|
|
|
|
// Remove the item from the cache if it already exists. MemoryCache will
|
|
// not add an item with an existing name.
|
|
if (GetItem(key, regionName) != null)
|
|
{
|
|
isUpDated = RemoveItem(key, regionName);
|
|
}
|
|
|
|
if (policy == null)
|
|
{
|
|
// Create a new cache policy with the default values
|
|
policy = new CacheItemPolicy();
|
|
}
|
|
|
|
if (isUpDated)
|
|
{
|
|
isUpDated = AddItem(key, value, policy, regionName);
|
|
}
|
|
|
|
return isUpDated;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes an item matching the given key from the cache.
|
|
/// </summary>
|
|
/// <param name="key">
|
|
/// A unique identifier for the cache entry.
|
|
/// </param>
|
|
/// <param name="regionName">
|
|
/// Optional. A named region in the cache to which the cache entry can be added,
|
|
/// if regions are implemented. The default value for the optional parameter
|
|
/// is null.
|
|
/// </param>
|
|
/// <returns>
|
|
/// True if the removal try succeeds, or false if there is an already an entry
|
|
/// in the cache with the same key as key.
|
|
/// </returns>
|
|
public static bool RemoveItem(string key, string regionName = null)
|
|
{
|
|
bool isRemoved;
|
|
|
|
lock (Cache)
|
|
{
|
|
isRemoved = Cache.Remove(key, regionName) != null;
|
|
|
|
if (isRemoved)
|
|
{
|
|
string removedValue;
|
|
CacheItems.TryRemove(key, out removedValue);
|
|
}
|
|
}
|
|
|
|
return isRemoved;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the cache.
|
|
/// </summary>
|
|
/// <param name="regionName">
|
|
/// The region name.
|
|
/// </param>
|
|
/// <returns>
|
|
/// The <see cref="bool"/>.
|
|
/// </returns>
|
|
public static bool Clear(string regionName = null)
|
|
{
|
|
bool isCleared = false;
|
|
|
|
lock (CacheItems)
|
|
{
|
|
// You can't remove items from a collection whilst you are iterating over it so you need to
|
|
// create a collection to store the items to remove.
|
|
ConcurrentDictionary<string, string> tempDictionary = new ConcurrentDictionary<string, string>();
|
|
|
|
foreach (KeyValuePair<string, string> cacheItem in CacheItems)
|
|
{
|
|
// Does the cached key come with a region.
|
|
if ((cacheItem.Value == null) || (cacheItem.Value != null && cacheItem.Value.Equals(regionName, StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
isCleared = RemoveItem(cacheItem.Key, cacheItem.Value);
|
|
|
|
if (isCleared)
|
|
{
|
|
string key = cacheItem.Key;
|
|
string value = cacheItem.Value;
|
|
tempDictionary.AddOrUpdate(key, value, (oldkey, oldValue) => value);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isCleared)
|
|
{
|
|
// Loop through and clear out the dictionary of cache keys.
|
|
foreach (KeyValuePair<string, string> cacheItem in tempDictionary)
|
|
{
|
|
string removedValue;
|
|
CacheItems.TryRemove(cacheItem.Key, out removedValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
return isCleared;
|
|
}
|
|
}
|
|
}
|
|
|