U4-4931 - fixing & refactoring
Conflicts: src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
This commit is contained in:
@@ -30,29 +30,11 @@ namespace Umbraco.Core.Cache
|
||||
get { return _wrapper; }
|
||||
}
|
||||
|
||||
// don't use, _cache enumerates DictionaryEntry items
|
||||
//
|
||||
//private IEnumerable<KeyValuePair<string, object>> EnumerateDictionaryCache()
|
||||
//{
|
||||
// // DictionaryCache just wraps _cache which has a special enumerator
|
||||
// var enumerator = _cache.GetEnumerator();
|
||||
// while (enumerator.MoveNext())
|
||||
// {
|
||||
// var key = enumerator.Key as string;
|
||||
// if (key == null) continue;
|
||||
// yield return new KeyValuePair<string, object>(key, enumerator.Value);
|
||||
// }
|
||||
//}
|
||||
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
// remove null values as well!
|
||||
|
||||
foreach (var entry in _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).StartsWith(CacheItemPrefix) /* && x.Value != null */))
|
||||
foreach (var entry in GetDictionaryEntries())
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
@@ -68,14 +50,15 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
var typeName2 = typeName;
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
foreach (var entry in _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).StartsWith(CacheItemPrefix)
|
||||
&& x.Value != null
|
||||
&& x.Value.GetType().ToString().InvariantEquals(typeName2)))
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
var value = ((Lazy<object>) x.Value).Value;
|
||||
return value == null || value.GetType().ToString().InvariantEquals(typeName); // remove null values as well
|
||||
}))
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
@@ -87,12 +70,13 @@ namespace Umbraco.Core.Cache
|
||||
var typeOfT = typeof(T);
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
foreach (var entry in _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).StartsWith(CacheItemPrefix)
|
||||
&& x.Value != null
|
||||
&& x.Value.GetType() == typeOfT))
|
||||
//&& x.Value is T))
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
var value = ((Lazy<object>)x.Value).Value;
|
||||
return value == null || value.GetType() == typeOfT; // remove null values as well
|
||||
}))
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
@@ -102,57 +86,59 @@ namespace Umbraco.Core.Cache
|
||||
// note: compare on exact type, don't use "is"
|
||||
|
||||
var typeOfT = typeof(T);
|
||||
try
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
foreach (var entry in _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).StartsWith(CacheItemPrefix)
|
||||
&& x.Value.GetType() == typeOfT // false if x.Value is null
|
||||
//&& x.Value is T
|
||||
&& predicate((string)x.Key, (T) x.Value)))
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// oops, what is this?!
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x =>
|
||||
{
|
||||
// entry.Value is Lazy<object> and not null, its value may be null
|
||||
var value = ((Lazy<object>)x.Value).Value;
|
||||
if (value == null) return true; // remove null values as well
|
||||
return value.GetType() == typeOfT
|
||||
// run predicate on the 'public key' part only, ie without prefix
|
||||
&& predicate(((string) x.Key).Substring(plen), (T) value);
|
||||
}))
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
foreach (var entry in _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).InvariantStartsWith(string.Format("{0}-{1}", CacheItemPrefix, keyStartsWith))))
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x => ((string)x.Key).Substring(plen).InvariantStartsWith(keyStartsWith)))
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1; // string.Format("{0}-", CacheItemPrefix)
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
foreach (var entry in _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).StartsWith(CacheItemPrefix)
|
||||
&& Regex.IsMatch(((string)x.Key).Substring(plen), regexString)))
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
.Where(x => Regex.IsMatch(((string)x.Key).Substring(plen), regexString)))
|
||||
_cache.Remove((string)entry.Key);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<DictionaryEntry> GetDictionaryEntries()
|
||||
{
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
return _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string && ((string) x.Key).StartsWith(prefix));
|
||||
}
|
||||
|
||||
public override IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (new ReadLock(Locker))
|
||||
{
|
||||
return _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string)x.Key).InvariantStartsWith(string.Format("{0}-{1}", CacheItemPrefix, keyStartsWith)))
|
||||
return GetDictionaryEntries()
|
||||
.Where(x => ((string) x.Key).Substring(plen).InvariantStartsWith(keyStartsWith))
|
||||
.Select(x => ((Lazy<object>)x.Value).Value)
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
@@ -161,14 +147,13 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public override IEnumerable<object> GetCacheItemsByKeyExpression(string regexString)
|
||||
{
|
||||
var plen = CacheItemPrefix.Length + 1; // string.Format("{0}-", CacheItemPrefix)
|
||||
const string prefix = CacheItemPrefix + "-";
|
||||
var plen = prefix.Length;
|
||||
using (new ReadLock(Locker))
|
||||
{
|
||||
return _cache.Cast<DictionaryEntry>()
|
||||
.Where(x => x.Key is string
|
||||
&& ((string) x.Key).StartsWith(CacheItemPrefix)
|
||||
&& Regex.IsMatch(((string) x.Key).Substring(plen), regexString))
|
||||
.Select(x => ((Lazy<object>) x.Value).Value)
|
||||
return GetDictionaryEntries()
|
||||
.Where(x => Regex.IsMatch(((string) x.Key).Substring(plen), regexString))
|
||||
.Select(x => ((Lazy<object>)x.Value).Value)
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -46,12 +46,16 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
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);
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x =>
|
||||
{
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
var value = ((Lazy<object>) x.Value).Value;
|
||||
return value == null || value.GetType().ToString().InvariantEquals(typeName); // remove null values as well
|
||||
})
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
MemoryCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +64,16 @@ namespace Umbraco.Core.Cache
|
||||
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);
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x =>
|
||||
{
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
var value = ((Lazy<object>) x.Value).Value;
|
||||
return value == null || value.GetType() == typeOfT; // remove null values as well
|
||||
})
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
MemoryCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +82,18 @@ namespace Umbraco.Core.Cache
|
||||
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);
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x =>
|
||||
{
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
var value = ((Lazy<object>) x.Value).Value;
|
||||
if (value == null) return true; // remove null values as well
|
||||
return value.GetType() == typeOfT
|
||||
&& predicate(x.Key, (T) value);
|
||||
})
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
MemoryCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,11 +101,11 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
var keysToRemove = (from c in MemoryCache where c.Key.InvariantStartsWith(keyStartsWith) select c.Key).ToList();
|
||||
foreach (var k in keysToRemove)
|
||||
{
|
||||
MemoryCache.Remove(k);
|
||||
}
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
MemoryCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,11 +113,11 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
var keysToRemove = (from c in MemoryCache where Regex.IsMatch(c.Key, regexString) select c.Key).ToList();
|
||||
foreach (var k in keysToRemove)
|
||||
{
|
||||
MemoryCache.Remove(k);
|
||||
}
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x => Regex.IsMatch(x.Key, regexString))
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
MemoryCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +128,7 @@ namespace Umbraco.Core.Cache
|
||||
return MemoryCache
|
||||
.Where(x => x.Key.InvariantStartsWith(keyStartsWith))
|
||||
.Select(x => ((Lazy<object>) x.Value).Value)
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -125,6 +140,7 @@ namespace Umbraco.Core.Cache
|
||||
return MemoryCache
|
||||
.Where(x => Regex.IsMatch(x.Key, regexString))
|
||||
.Select(x => ((Lazy<object>) x.Value).Value)
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -133,8 +149,8 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
using (new ReadLock(_locker))
|
||||
{
|
||||
var result = MemoryCache.Get(cacheKey);
|
||||
return result;
|
||||
var result = MemoryCache.Get(cacheKey) as Lazy<object>;
|
||||
return result == null ? null : result.Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +175,7 @@ namespace Umbraco.Core.Cache
|
||||
using (var lck = new UpgradeableReadLock(_locker))
|
||||
{
|
||||
result = MemoryCache.Get(cacheKey) as Lazy<object>;
|
||||
if (result == null /* || (result.IsValueCreated && result.Value == null) */)
|
||||
if (result == null || (result.IsValueCreated && result.Value == null))
|
||||
{
|
||||
lck.UpgradeToWriteLock();
|
||||
|
||||
@@ -174,11 +190,12 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public void InsertCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
{
|
||||
// see notes in HttpRuntimeCacheProvider
|
||||
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
|
||||
// and make sure we don't store a null value.
|
||||
|
||||
var result = new Lazy<object>(getCacheItem);
|
||||
var value = result.Value; // force evaluation now
|
||||
//if (value == null) return;
|
||||
if (value == null) return; // do not store null values (backward compat)
|
||||
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
MemoryCache.Set(cacheKey, result, policy);
|
||||
|
||||
Reference in New Issue
Block a user