Commit a1d6b265 authored by mgravell's avatar mgravell

salt the earth if we start getting multiple errors; the risk here is that it...

salt the earth if we start getting multiple errors; the risk here is that it is a schema change that impacts multiple queries
parent 7392a4e3
...@@ -114,6 +114,15 @@ class CacheInfo ...@@ -114,6 +114,15 @@ class CacheInfo
public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); } public int GetHitCount() { return Interlocked.CompareExchange(ref hitCount, 0, 0); }
public void RecordHit() { Interlocked.Increment(ref hitCount); } public void RecordHit() { Interlocked.Increment(ref hitCount); }
} }
private static int totalErrorCount = 0;
private const int PurgeCacheAfterNErrors = 20;
public static event EventHandler QueryCachePurged;
private static void OnQueryCachePurged()
{
var handler = QueryCachePurged;
if (handler != null) handler(null, EventArgs.Empty);
}
#if CSHARP30 #if CSHARP30
private static readonly Dictionary<Identity, CacheInfo> _queryCache = new Dictionary<Identity, CacheInfo>(); private static readonly Dictionary<Identity, CacheInfo> _queryCache = new Dictionary<Identity, CacheInfo>();
// note: conflicts between readers and writers are so short-lived that it isn't worth the overhead of // note: conflicts between readers and writers are so short-lived that it isn't worth the overhead of
...@@ -128,9 +137,31 @@ private static bool TryGetQueryCache(Identity key, out CacheInfo value) ...@@ -128,9 +137,31 @@ private static bool TryGetQueryCache(Identity key, out CacheInfo value)
} }
private static void PurgeQueryCache(Identity key) private static void PurgeQueryCache(Identity key)
{ {
lock (_queryCache) { _queryCache.Remove(key); } bool purged = false;
lock (_queryCache)
{
if (++totalErrorCount >= PurgeCacheAfterNErrors)
{
totalErrorCount = 0;
_queryCache.Clear();
purged = true;
}
else
{
_queryCache.Remove(key);
}
}
if(purged) OnQueryCachePurged();
}
public static void PurgeQueryCache()
{
lock (_queryCache)
{
totalErrorCount = 0;
_queryCache.Clear();
}
OnQueryCachePurged();
} }
#else #else
static readonly System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo> _queryCache = new System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo>(); static readonly System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo> _queryCache = new System.Collections.Concurrent.ConcurrentDictionary<Identity, CacheInfo>();
private static void SetQueryCache(Identity key, CacheInfo value) private static void SetQueryCache(Identity key, CacheInfo value)
...@@ -155,6 +186,7 @@ private static void CollectCacheGarbage() ...@@ -155,6 +186,7 @@ private static void CollectCacheGarbage()
} }
} }
} }
finally finally
{ {
Interlocked.Exchange(ref collect, 0); Interlocked.Exchange(ref collect, 0);
...@@ -175,8 +207,19 @@ private static bool TryGetQueryCache(Identity key, out CacheInfo value) ...@@ -175,8 +207,19 @@ private static bool TryGetQueryCache(Identity key, out CacheInfo value)
} }
private static void PurgeQueryCache(Identity key) private static void PurgeQueryCache(Identity key)
{ {
CacheInfo info; if(Interlocked.Increment(ref totalErrorCount) >= PurgeCacheAfterNErrors)
_queryCache.TryRemove(key, out info); {
PurgeQueryCache();
} else {
CacheInfo info;
_queryCache.TryRemove(key, out info);
}
}
public static void PurgeQueryCache()
{
_queryCache.Clear();
Interlocked.Exchange(ref totalErrorCount, 0);
OnQueryCachePurged();
} }
public static int GetCachedSQLCount() public static int GetCachedSQLCount()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment