U4-4931 - fixing & refactoring

Conflicts:
	src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
This commit is contained in:
Stephan
2014-05-26 15:56:29 +02:00
parent 2c9a287bda
commit 72f53e4645
2 changed files with 99 additions and 97 deletions

View File

@@ -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();
}

View File

@@ -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);