From a9f65a4617f6febfb9b77120517ff35f9f29ec92 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 25 Aug 2018 10:48:37 -0700 Subject: [PATCH] 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 --- PKHeX.Core/Legality/WordFilter.cs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/PKHeX.Core/Legality/WordFilter.cs b/PKHeX.Core/Legality/WordFilter.cs index 5710c8f46..e304ae017 100644 --- a/PKHeX.Core/Legality/WordFilter.cs +++ b/PKHeX.Core/Legality/WordFilter.cs @@ -16,7 +16,7 @@ public static class WordFilter /// /// Due to some messages repeating (Trainer names), keep a list of repeated values for faster lookup. /// - private static readonly Dictionary Lookup = new Dictionary(); + private static readonly Dictionary Lookup = new Dictionary(INIT_COUNT); /// /// 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 } }