From c4c322b183cccafd664d8127e3791239ebd6a006 Mon Sep 17 00:00:00 2001 From: Sanjeev Manickam Date: Mon, 22 Feb 2016 11:10:14 -0500 Subject: [PATCH 1/2] Added lock around adding to _enumCache --- .../Extensions/Extensions.cs | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/src/Nest/CommonAbstractions/Extensions/Extensions.cs b/src/Nest/CommonAbstractions/Extensions/Extensions.cs index f8f62aaad10..486a07abd83 100644 --- a/src/Nest/CommonAbstractions/Extensions/Extensions.cs +++ b/src/Nest/CommonAbstractions/Extensions/Extensions.cs @@ -15,13 +15,13 @@ namespace Nest internal static class Extensions { internal static TReturn InvokeOrDefault(this Func func, T @default) - where T: class, TReturn where TReturn: class => + where T : class, TReturn where TReturn : class => func?.Invoke(@default) ?? @default; - + internal static TReturn InvokeOrDefault(this Func func, T1 @default, T2 param2) - where T1: class, TReturn where TReturn: class => + where T1 : class, TReturn where TReturn : class => func?.Invoke(@default, param2) ?? @default; - + internal static QueryContainer InvokeQuery( this Func, QueryContainer> f, QueryContainerDescriptor container) @@ -33,7 +33,7 @@ internal static QueryContainer InvokeQuery( return c; //query is conditionless but the container is marked as strict, throw exception - if (c != null && c.IsStrict) + if (c != null && c.IsStrict) throw new ArgumentException("Query is conditionless but strict is turned on"); //query is conditionless return an empty container that can later be rewritten @@ -53,7 +53,7 @@ internal static string GetStringValue(this Enum enumValue) return da != null ? da.Value : Enum.GetName(enumValue.GetType(), enumValue); } - + internal static readonly JsonConverter dateConverter = new IsoDateTimeConverter { Culture = CultureInfo.InvariantCulture }; internal static readonly JsonSerializer serializer = new JsonSerializer(); internal static string ToJsonNetString(this DateTime date) @@ -78,32 +78,40 @@ internal static IEnumerable DistinctBy(this IEnumerable items, Fu if (_enumCache.ContainsKey(key)) return (T)_enumCache[key]; - foreach (var name in Enum.GetNames(enumType)) + // make sure that only one thread can be adding to cache + lock (_enumCache) { - if (name.Equals(str, StringComparison.OrdinalIgnoreCase)) return (T)Enum.Parse(enumType, name, true); - - var enumFieldInfo = enumType.GetField(name); - var enumMemberAttribute = enumFieldInfo.GetCustomAttribute(); - - if (enumMemberAttribute != null) + // Just make sure that cache still does not contain key + if (!_enumCache.ContainsKey(key)) { - if (enumMemberAttribute.Value == str) + foreach (var name in Enum.GetNames(enumType)) { - var value = (T)Enum.Parse(enumType, name); - _enumCache.Add(key, value); - return value; - } - } - - var alternativeEnumMemberAttribute = enumFieldInfo.GetCustomAttribute(); - - if (alternativeEnumMemberAttribute != null) - { - if (alternativeEnumMemberAttribute.Value == str) - { - var value = (T)Enum.Parse(enumType, name); - _enumCache.Add(key, value); - return value; + if (name.Equals(str, StringComparison.OrdinalIgnoreCase)) return (T)Enum.Parse(enumType, name, true); + + var enumFieldInfo = enumType.GetField(name); + var enumMemberAttribute = enumFieldInfo.GetCustomAttribute(); + + if (enumMemberAttribute != null) + { + if (enumMemberAttribute.Value == str) + { + var value = (T)Enum.Parse(enumType, name); + _enumCache.Add(key, value); + return value; + } + } + + var alternativeEnumMemberAttribute = enumFieldInfo.GetCustomAttribute(); + + if (alternativeEnumMemberAttribute != null) + { + if (alternativeEnumMemberAttribute.Value == str) + { + var value = (T)Enum.Parse(enumType, name); + _enumCache.Add(key, value); + return value; + } + } } } } From 871b35d92fef5dcbda586fce767ae00fbc25dadd Mon Sep 17 00:00:00 2001 From: Sanjeev Manickam Date: Mon, 22 Feb 2016 11:41:24 -0500 Subject: [PATCH 2/2] returning enum if entering lock and key already in cache --- .../Extensions/Extensions.cs | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/Nest/CommonAbstractions/Extensions/Extensions.cs b/src/Nest/CommonAbstractions/Extensions/Extensions.cs index 486a07abd83..5389ba8f514 100644 --- a/src/Nest/CommonAbstractions/Extensions/Extensions.cs +++ b/src/Nest/CommonAbstractions/Extensions/Extensions.cs @@ -81,39 +81,40 @@ internal static IEnumerable DistinctBy(this IEnumerable items, Fu // make sure that only one thread can be adding to cache lock (_enumCache) { - // Just make sure that cache still does not contain key - if (!_enumCache.ContainsKey(key)) + // Check to see if cache now contains key + if (_enumCache.ContainsKey(key)) + return (T)_enumCache[key]; + + foreach (var name in Enum.GetNames(enumType)) { - foreach (var name in Enum.GetNames(enumType)) - { - if (name.Equals(str, StringComparison.OrdinalIgnoreCase)) return (T)Enum.Parse(enumType, name, true); + if (name.Equals(str, StringComparison.OrdinalIgnoreCase)) return (T)Enum.Parse(enumType, name, true); - var enumFieldInfo = enumType.GetField(name); - var enumMemberAttribute = enumFieldInfo.GetCustomAttribute(); + var enumFieldInfo = enumType.GetField(name); + var enumMemberAttribute = enumFieldInfo.GetCustomAttribute(); - if (enumMemberAttribute != null) + if (enumMemberAttribute != null) + { + if (enumMemberAttribute.Value == str) { - if (enumMemberAttribute.Value == str) - { - var value = (T)Enum.Parse(enumType, name); - _enumCache.Add(key, value); - return value; - } + var value = (T)Enum.Parse(enumType, name); + _enumCache.Add(key, value); + return value; } + } - var alternativeEnumMemberAttribute = enumFieldInfo.GetCustomAttribute(); + var alternativeEnumMemberAttribute = enumFieldInfo.GetCustomAttribute(); - if (alternativeEnumMemberAttribute != null) + if (alternativeEnumMemberAttribute != null) + { + if (alternativeEnumMemberAttribute.Value == str) { - if (alternativeEnumMemberAttribute.Value == str) - { - var value = (T)Enum.Parse(enumType, name); - _enumCache.Add(key, value); - return value; - } + var value = (T)Enum.Parse(enumType, name); + _enumCache.Add(key, value); + return value; } } } + } return null;