Skip to content

Commit 6af7e82

Browse files
authored
Merge pull request #5 from servicetitan/name-builder-concurrency-issue
NameBuilder concurrency issue fix
2 parents 2d13f38 + 8ef08cb commit 6af7e82

1 file changed

Lines changed: 9 additions & 19 deletions

File tree

Orm/Xtensive.Orm/Orm/Providers/NameBuilder.cs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
// Created: 2007.08.27
66

77
using System;
8+
using System.Collections.Concurrent;
89
using System.Collections.Generic;
910
using System.Linq;
1011
using System.Reflection;
12+
using System.Runtime.CompilerServices;
1113
using System.Security.Cryptography;
1214
using System.Text;
1315
using Xtensive.Core;
@@ -36,12 +38,15 @@ public sealed class NameBuilder
3638
private const string ReferenceForeignKeyFormat = "FK_{0}_{1}_{2}";
3739
private const string HierarchyForeignKeyFormat = "FK_{0}_{1}";
3840

39-
private readonly Dictionary<Pair<Type, string>, string> fieldNameCache = new Dictionary<Pair<Type, string>, string>();
40-
private readonly object _lock = new object();
41+
private static readonly Func<PropertyInfo, string> fieldNameCacheValueFactory =
42+
field => field.GetAttribute<OverrideFieldNameAttribute>()?.Name ?? field.Name;
43+
4144
private readonly int maxIdentifierLength;
4245
private readonly NamingConvention namingConvention;
4346
private readonly bool isMultidatabase;
4447
private readonly string defaultDatabase;
48+
private readonly ConcurrentDictionary<PropertyInfo, string> fieldNameCache =
49+
new ConcurrentDictionary<PropertyInfo, string>();
4550

4651
/// <summary>
4752
/// Gets the <see cref="Entity.TypeId"/> column name.
@@ -181,24 +186,9 @@ public string BuildFieldName(FieldDef field)
181186
return result;
182187
}
183188

189+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
184190
private string BuildFieldNameInternal(PropertyInfo propertyInfo)
185-
{
186-
var key = new Pair<Type, string>(propertyInfo.ReflectedType, propertyInfo.Name);
187-
188-
lock (fieldNameCache) {
189-
string result;
190-
if (fieldNameCache.TryGetValue(key, out result))
191-
return result;
192-
var attribute = propertyInfo.GetAttribute<OverrideFieldNameAttribute>();
193-
if (attribute!=null) {
194-
result = attribute.Name;
195-
fieldNameCache.Add(key, result);
196-
return result;
197-
}
198-
}
199-
200-
return propertyInfo.Name;
201-
}
191+
=> fieldNameCache.GetOrAdd(propertyInfo, fieldNameCacheValueFactory);
202192

203193
/// <summary>
204194
/// Builds the name of the field.

0 commit comments

Comments
 (0)