From c2db7b2b9b78847a828512818e79492ecc24ac7c Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 18 Sep 2013 12:27:38 +0200 Subject: [PATCH] Core.Cache - bugfix + add new method to remove items from cache --- .../Cache/CacheProviderExtensions.cs | 5 -- .../Cache/DictionaryCacheProdiverBase.cs | 64 ++++++++++++++++--- src/Umbraco.Core/Cache/ICacheProvider.cs | 2 + src/Umbraco.Core/Cache/NullCacheProvider.cs | 8 +++ .../Cache/ObjectCacheRuntimeCacheProvider.cs | 35 +++++++++- src/Umbraco.Core/Cache/StaticCacheProvider.cs | 42 +++++------- 6 files changed, 115 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Core/Cache/CacheProviderExtensions.cs b/src/Umbraco.Core/Cache/CacheProviderExtensions.cs index 45031366cc..1776913880 100644 --- a/src/Umbraco.Core/Cache/CacheProviderExtensions.cs +++ b/src/Umbraco.Core/Cache/CacheProviderExtensions.cs @@ -35,11 +35,6 @@ namespace Umbraco.Core.Cache provider.InsertCacheItem(cacheKey, () => getCacheItem(), timeout, isSliding, priority, removedCallback, dependentFiles); } - public static void ClearCacheObjectTypes(this ICacheProvider provider) - { - provider.ClearCacheObjectTypes(typeof(T).ToString()); - } - public static IEnumerable GetCacheItemsByKeySearch(this ICacheProvider provider, string keyStartsWith) { var result = provider.GetCacheItemsByKeySearch(keyStartsWith); diff --git a/src/Umbraco.Core/Cache/DictionaryCacheProdiverBase.cs b/src/Umbraco.Core/Cache/DictionaryCacheProdiverBase.cs index 3839a01c65..dafc077b12 100644 --- a/src/Umbraco.Core/Cache/DictionaryCacheProdiverBase.cs +++ b/src/Umbraco.Core/Cache/DictionaryCacheProdiverBase.cs @@ -56,19 +56,67 @@ namespace Umbraco.Core.Cache { using (new WriteLock(Locker)) { - var keysToRemove = DictionaryCache.Cast() - .Select(item => new DictionaryItemWrapper(item)) - .Where(c => DictionaryCache[c.Key.ToString()] != null && DictionaryCache[c.Key.ToString()].GetType().ToString().InvariantEquals(typeName)) - .Select(c => c.Key) - .ToList(); + var keysToRemove = DictionaryCache + .Cast() + .Select(item => new DictionaryItemWrapper(item)) + .Where(c => + { + var k = c.Key.ToString(); + var v = DictionaryCache[k]; + return v != null && v.GetType().ToString().InvariantEquals(typeName); + }) + .Select(c => c.Key) + .ToList(); foreach (var k in keysToRemove) - { DictionaryCache.Remove(k); - } } } - + + public virtual void ClearCacheObjectTypes() + { + using (new WriteLock(Locker)) + { + var typeOfT = typeof(T); + var keysToRemove = DictionaryCache + .Cast() + .Select(item => new DictionaryItemWrapper(item)) + .Where(c => + { + var k = c.Key.ToString(); + var v = DictionaryCache[k]; + return v != null && v.GetType() == typeOfT; + }) + .Select(c => c.Key) + .ToList(); + + foreach (var k in keysToRemove) + DictionaryCache.Remove(k); + } + } + + public virtual void ClearCacheObjectTypes(Func predicate) + { + using (new WriteLock(Locker)) + { + var typeOfT = typeof(T); + var keysToRemove = DictionaryCache + .Cast() + .Select(item => new DictionaryItemWrapper(item)) + .Where(c => + { + var k = c.Key.ToString(); + var v = DictionaryCache[k]; + return v != null && v.GetType() == typeOfT && predicate(k, (T)v); + }) + .Select(c => c.Key) + .ToList(); + + foreach (var k in keysToRemove) + DictionaryCache.Remove(k); + } + } + /// /// Clears all cache items that starts with the key passed. /// diff --git a/src/Umbraco.Core/Cache/ICacheProvider.cs b/src/Umbraco.Core/Cache/ICacheProvider.cs index 799501aaaf..ff947b0ae8 100644 --- a/src/Umbraco.Core/Cache/ICacheProvider.cs +++ b/src/Umbraco.Core/Cache/ICacheProvider.cs @@ -11,6 +11,8 @@ namespace Umbraco.Core.Cache void ClearAllCache(); void ClearCacheItem(string key); void ClearCacheObjectTypes(string typeName); + void ClearCacheObjectTypes(); + void ClearCacheObjectTypes(Func predicate); void ClearCacheByKeySearch(string keyStartsWith); void ClearCacheByKeyExpression(string regexString); IEnumerable GetCacheItemsByKeySearch(string keyStartsWith); diff --git a/src/Umbraco.Core/Cache/NullCacheProvider.cs b/src/Umbraco.Core/Cache/NullCacheProvider.cs index d9d4a46347..4feef3f8a5 100644 --- a/src/Umbraco.Core/Cache/NullCacheProvider.cs +++ b/src/Umbraco.Core/Cache/NullCacheProvider.cs @@ -19,6 +19,14 @@ namespace Umbraco.Core.Cache { } + public virtual void ClearCacheObjectTypes() + { + } + + public virtual void ClearCacheObjectTypes(Func predicate) + { + } + public virtual void ClearCacheByKeySearch(string keyStartsWith) { } diff --git a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs index c64863168b..8e8d61e9b4 100644 --- a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs @@ -46,11 +46,40 @@ namespace Umbraco.Core.Cache { using (new WriteLock(Locker)) { - var keysToRemove = (from c in MemoryCache where c.Value.GetType().ToString().InvariantEquals(typeName) select c.Key).ToList(); + var keysToRemove = MemoryCache + .Where(c => c.Value != null && c.Value.GetType().ToString().InvariantEquals(typeName)) + .Select(c => c.Key) + .ToArray(); + foreach (var k in keysToRemove) + MemoryCache.Remove(k); + } + } + + public virtual void ClearCacheObjectTypes() + { + using (new WriteLock(Locker)) + { + var typeOfT = typeof (T); + var keysToRemove = MemoryCache + .Where(c => c.Value != null && c.Value.GetType() == typeOfT) + .Select(c => c.Key) + .ToArray(); + foreach (var k in keysToRemove) + MemoryCache.Remove(k); + } + } + + public virtual void ClearCacheObjectTypes(Func predicate) + { + using (new WriteLock(Locker)) + { + var typeOfT = typeof(T); + var keysToRemove = MemoryCache + .Where(c => c.Value != null && c.Value.GetType() == typeOfT && predicate(c.Key, (T)c.Value)) + .Select(c => c.Key) + .ToArray(); foreach (var k in keysToRemove) - { MemoryCache.Remove(k); - } } } diff --git a/src/Umbraco.Core/Cache/StaticCacheProvider.cs b/src/Umbraco.Core/Cache/StaticCacheProvider.cs index c0b5e8ba5d..cd58fc3dde 100644 --- a/src/Umbraco.Core/Cache/StaticCacheProvider.cs +++ b/src/Umbraco.Core/Cache/StaticCacheProvider.cs @@ -27,37 +27,29 @@ namespace Umbraco.Core.Cache public virtual void ClearCacheObjectTypes(string typeName) { - foreach (var key in StaticCache.Keys) - { - if (StaticCache[key] != null - && StaticCache[key].GetType().ToString().InvariantEquals(typeName)) - { - object val; - StaticCache.TryRemove(key, out val); - } - } - } + StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType().ToString().InvariantEquals(typeName)); + } + + public virtual void ClearCacheObjectTypes() + { + var typeOfT = typeof(T); + StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT); + } + + public virtual void ClearCacheObjectTypes(Func predicate) + { + var typeOfT = typeof(T); + StaticCache.RemoveAll(kvp => kvp.Value != null && kvp.Value.GetType() == typeOfT && predicate(kvp.Key, (T)kvp.Value)); + } public virtual void ClearCacheByKeySearch(string keyStartsWith) { - foreach (var key in StaticCache.Keys) - { - if (key.InvariantStartsWith(keyStartsWith)) - { - ClearCacheItem(key); - } - } + StaticCache.RemoveAll(kvp => kvp.Key.InvariantStartsWith(keyStartsWith)); } public virtual void ClearCacheByKeyExpression(string regexString) { - foreach (var key in StaticCache.Keys) - { - if (Regex.IsMatch(key, regexString)) - { - ClearCacheItem(key); - } - } + StaticCache.RemoveAll(kvp => Regex.IsMatch(kvp.Key, regexString)); } public virtual IEnumerable GetCacheItemsByKeySearch(string keyStartsWith) @@ -75,7 +67,7 @@ namespace Umbraco.Core.Cache public virtual object GetCacheItem(string cacheKey, Func getCacheItem) { - return StaticCache.GetOrAdd(cacheKey, getCacheItem()); + return StaticCache.GetOrAdd(cacheKey, key => getCacheItem()); } }