Skip to content

Commit ba73c43

Browse files
AlexanderKothazzik
andauthored
Improve some sparse arrays (#3649)
Co-authored-by: Alex Zaytsev <[email protected]>
1 parent 9289d29 commit ba73c43

File tree

7 files changed

+47
-62
lines changed

7 files changed

+47
-62
lines changed

src/NHibernate/Loader/Loader.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ public sealed class QueryCacheInfo
8282
/// <summary>
8383
/// Caches subclass entity aliases for given persister index in <see cref="EntityPersisters"/> and subclass entity name
8484
/// </summary>
85-
private readonly ConcurrentDictionary<Tuple<int, string>, string[][]> _subclassEntityAliasesMap = new ConcurrentDictionary<Tuple<int, string>, string[][]>();
85+
private readonly Lazy<ConcurrentDictionary<Tuple<int, string>, string[][]>> _subclassEntityAliasesMap =
86+
new(() => new ConcurrentDictionary<Tuple<int, string>, string[][]>());
8687

8788
protected Loader(ISessionFactoryImplementor factory)
8889
{
@@ -1322,7 +1323,7 @@ private void LoadFromResultSet(DbDataReader rs, int i, object obj, ILoadable per
13221323
private string[][] GetSubclassEntityAliases(int i, ILoadable persister)
13231324
{
13241325
var cacheKey = System.Tuple.Create(i, persister.EntityName);
1325-
return _subclassEntityAliasesMap.GetOrAdd(
1326+
return _subclassEntityAliasesMap.Value.GetOrAdd(
13261327
cacheKey,
13271328
k => EntityAliases[i].GetSuffixedPropertyAliases(persister));
13281329
}

src/NHibernate/Mapping/Constraint.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace NHibernate.Mapping
1515
public abstract class Constraint : IRelationalModel
1616
{
1717
private string name;
18-
private readonly List<Column> columns = new List<Column>();
18+
private readonly List<Column> columns = new List<Column>(1);
1919
private Table table;
2020

2121
/// <summary>

src/NHibernate/Mapping/ForeignKey.cs

+35-57
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Text;
33
using NHibernate.Util;
44
using System;
5+
using System.Linq;
56

67
namespace NHibernate.Mapping
78
{
@@ -14,7 +15,7 @@ public class ForeignKey : Constraint
1415
private Table referencedTable;
1516
private string referencedEntityName;
1617
private bool cascadeDeleteEnabled;
17-
private readonly List<Column> referencedColumns = new List<Column>();
18+
private List<Column> referencedColumns;
1819

1920
/// <summary>
2021
/// Generates the SQL string to create the named Foreign Key Constraint in the database.
@@ -26,29 +27,26 @@ public class ForeignKey : Constraint
2627
/// <returns>
2728
/// A string that contains the SQL to create the named Foreign Key Constraint.
2829
/// </returns>
29-
public override string SqlConstraintString(Dialect.Dialect d, string constraintName, string defaultCatalog, string defaultSchema)
30-
{
31-
string[] cols = new string[ColumnSpan];
32-
string[] refcols = new string[ColumnSpan];
33-
int i = 0;
34-
IEnumerable<Column> refiter;
35-
if (IsReferenceToPrimaryKey)
36-
refiter = referencedTable.PrimaryKey.ColumnIterator;
37-
else
38-
refiter = referencedColumns;
39-
foreach (Column column in ColumnIterator)
40-
{
41-
cols[i] = column.GetQuotedName(d);
42-
i++;
43-
}
30+
public override string SqlConstraintString(
31+
Dialect.Dialect d,
32+
string constraintName,
33+
string defaultCatalog,
34+
string defaultSchema)
35+
{
36+
var refiter = IsReferenceToPrimaryKey
37+
? referencedTable.PrimaryKey.Columns
38+
: referencedColumns;
39+
40+
var cols = Columns.ToArray(column => column.GetQuotedName(d));
41+
var refcols = refiter.ToArray(column => column.GetQuotedName(d));
42+
43+
string result = d.GetAddForeignKeyConstraintString(
44+
constraintName,
45+
cols,
46+
referencedTable.GetQualifiedName(d, defaultCatalog, defaultSchema),
47+
refcols,
48+
IsReferenceToPrimaryKey);
4449

45-
i = 0;
46-
foreach (Column column in refiter)
47-
{
48-
refcols[i] = column.GetQuotedName(d);
49-
i++;
50-
}
51-
string result = d.GetAddForeignKeyConstraintString(constraintName, cols, referencedTable.GetQualifiedName(d, defaultCatalog, defaultSchema), refcols, IsReferenceToPrimaryKey);
5250
return cascadeDeleteEnabled && d.SupportsCascadeDelete ? result + " on delete cascade" : result;
5351
}
5452

@@ -172,40 +170,24 @@ public virtual void AddReferencedColumns(IEnumerable<Column> referencedColumnsIt
172170

173171
private void AddReferencedColumn(Column column)
174172
{
173+
referencedColumns ??= new List<Column>(1);
175174
if (!referencedColumns.Contains(column))
176175
referencedColumns.Add(column);
177176
}
178177

179178
internal void AddReferencedTable(PersistentClass referencedClass)
180179
{
181-
if (referencedColumns.Count > 0)
182-
{
183-
referencedTable = referencedColumns[0].Value.Table;
184-
}
185-
else
186-
{
187-
referencedTable = referencedClass.Table;
188-
}
180+
referencedTable = IsReferenceToPrimaryKey ? referencedClass.Table : referencedColumns[0].Value.Table;
189181
}
190182

191183
public override string ToString()
192184
{
193-
if (!IsReferenceToPrimaryKey)
194-
{
195-
var result = new StringBuilder();
196-
result.Append(GetType().FullName)
197-
.Append('(')
198-
.Append(Table.Name)
199-
.Append(string.Join(", ", Columns))
200-
.Append(" ref-columns:")
201-
.Append('(')
202-
.Append(string.Join(", ", ReferencedColumns))
203-
.Append(") as ")
204-
.Append(Name);
205-
return result.ToString();
206-
}
185+
if (IsReferenceToPrimaryKey)
186+
return base.ToString();
207187

208-
return base.ToString();
188+
var columns = string.Join(", ", Columns);
189+
var refColumns = string.Join(", ", referencedColumns);
190+
return $"{GetType().FullName}({Table.Name}{columns} ref-columns:({refColumns}) as {Name}";
209191
}
210192

211193
public bool HasPhysicalConstraint
@@ -218,7 +200,11 @@ public bool HasPhysicalConstraint
218200

219201
public IList<Column> ReferencedColumns
220202
{
221-
get { return referencedColumns; }
203+
get
204+
{
205+
referencedColumns ??= new List<Column>(1);
206+
return referencedColumns;
207+
}
222208
}
223209

224210
public string ReferencedEntityName
@@ -228,10 +214,7 @@ public string ReferencedEntityName
228214
}
229215

230216
/// <summary>Does this foreignkey reference the primary key of the reference table </summary>
231-
public bool IsReferenceToPrimaryKey
232-
{
233-
get { return referencedColumns.Count == 0; }
234-
}
217+
public bool IsReferenceToPrimaryKey => referencedColumns == null || referencedColumns.Count == 0;
235218

236219
public string GeneratedConstraintNamePrefix => "FK_";
237220

@@ -242,12 +225,7 @@ public override bool IsGenerated(Dialect.Dialect dialect)
242225
if (dialect.SupportsNullInUnique || IsReferenceToPrimaryKey)
243226
return true;
244227

245-
foreach (var column in ReferencedColumns)
246-
{
247-
if (column.IsNullable)
248-
return false;
249-
}
250-
return true;
228+
return referencedColumns.All(column => !column.IsNullable);
251229
}
252230
}
253231
}

src/NHibernate/Mapping/Index.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace NHibernate.Mapping
1414
public class Index : IRelationalModel
1515
{
1616
private Table table;
17-
private readonly List<Column> columns = new List<Column>();
17+
private readonly List<Column> columns = new List<Column>(1);
1818
private string name;
1919

2020
public static string BuildSqlCreateIndexString(Dialect.Dialect dialect, string name, Table table,

src/NHibernate/Mapping/SimpleValue.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace NHibernate.Mapping
1515
[Serializable]
1616
public class SimpleValue : IKeyValue
1717
{
18-
private readonly List<ISelectable> columns = new List<ISelectable>();
18+
private readonly List<ISelectable> columns = new List<ISelectable>(1);
1919
private IType type;
2020
private IDictionary<string, string> typeParameters;
2121

src/NHibernate/Mapping/Table.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1064,9 +1064,12 @@ internal ForeignKeyKey(IEnumerable<Column> columns, string referencedClassName,
10641064
{
10651065
this.referencedClassName = referencedClassName;
10661066
this.columns = new List<Column>(columns);
1067+
this.columns.TrimExcess();
1068+
10671069
if (referencedColumns != null)
10681070
{
10691071
this.referencedColumns = new List<Column>(referencedColumns);
1072+
this.referencedColumns.TrimExcess();
10701073
}
10711074
else
10721075
{

src/NHibernate/SqlCommand/SqlString.cs

+3
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ internal SqlString(IEnumerable<object> parts)
215215
_firstPartIndex = _parts.Count > 0 ? 0 : -1;
216216
_lastPartIndex = _parts.Count - 1;
217217
_length = sqlIndex;
218+
219+
_parts.TrimExcess();
220+
_parameters.TrimExcess();
218221
}
219222

220223
#endregion

0 commit comments

Comments
 (0)