add lock for cross thread dictionary manip

could use concurrentdictionary but after reading some perf drawbacks vs
manual locks, just do it manually. regex checking is the real slow part,
whatever
add some comments to describe
This commit is contained in:
Kurt 2018-08-25 10:48:37 -07:00
parent 5fe9226c62
commit a9f65a4617

View File

@ -16,7 +16,7 @@ public static class WordFilter
/// <summary>
/// Due to some messages repeating (Trainer names), keep a list of repeated values for faster lookup.
/// </summary>
private static readonly Dictionary<string, string> Lookup = new Dictionary<string, string>();
private static readonly Dictionary<string, string> Lookup = new Dictionary<string, string>(INIT_COUNT);
/// <summary>
/// Checks to see if a phrase contains filtered content.
@ -34,22 +34,37 @@ public static bool IsFiltered(string message, out string regMatch)
var msg = message.ToLower();
// Check dictionary
if (Lookup.TryGetValue(msg, out regMatch))
return regMatch != null;
lock (dictLock)
{
if (Lookup.TryGetValue(msg, out regMatch))
return regMatch != null;
}
// not in dictionary, check patterns
foreach (var pattern in Patterns)
{
if (!Regex.IsMatch(msg, pattern))
continue;
// match found, cache result
regMatch = pattern;
Lookup.Add(msg, regMatch);
lock (dictLock)
Lookup.Add(msg, regMatch);
return true;
}
if (Lookup.Count > 100_000) // arbitrary cap
Lookup.Clear(); // reset
Lookup.Add(msg, regMatch = null);
// didn't match any pattern, cache result
lock (dictLock)
{
if ((Lookup.Count & ~MAX_COUNT) != 0)
Lookup.Clear(); // reset
Lookup.Add(msg, regMatch = null);
}
return false;
}
private static readonly object dictLock = new object();
private const int MAX_COUNT = (1 << 17) - 1; // arbitrary cap for max dictionary size
private const int INIT_COUNT = 1 << 10; // arbitrary init size to limit future doublings
}
}