Skip to content

Improve some sparse arrays #3649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/NHibernate/Loader/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public sealed class QueryCacheInfo
/// <summary>
/// Caches subclass entity aliases for given persister index in <see cref="EntityPersisters"/> and subclass entity name
/// </summary>
private readonly ConcurrentDictionary<Tuple<int, string>, string[][]> _subclassEntityAliasesMap = new ConcurrentDictionary<Tuple<int, string>, string[][]>();
private readonly Lazy<ConcurrentDictionary<Tuple<int, string>, string[][]>> _subclassEntityAliasesMap =
new(() => new ConcurrentDictionary<Tuple<int, string>, string[][]>());

protected Loader(ISessionFactoryImplementor factory)
{
Expand Down Expand Up @@ -1322,7 +1323,7 @@ private void LoadFromResultSet(DbDataReader rs, int i, object obj, ILoadable per
private string[][] GetSubclassEntityAliases(int i, ILoadable persister)
{
var cacheKey = System.Tuple.Create(i, persister.EntityName);
return _subclassEntityAliasesMap.GetOrAdd(
return _subclassEntityAliasesMap.Value.GetOrAdd(
cacheKey,
k => EntityAliases[i].GetSuffixedPropertyAliases(persister));
}
Expand Down
2 changes: 1 addition & 1 deletion src/NHibernate/Mapping/Constraint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace NHibernate.Mapping
public abstract class Constraint : IRelationalModel
{
private string name;
private readonly List<Column> columns = new List<Column>();
private readonly List<Column> columns = new List<Column>(1);
private Table table;

/// <summary>
Expand Down
92 changes: 35 additions & 57 deletions src/NHibernate/Mapping/ForeignKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Text;
using NHibernate.Util;
using System;
using System.Linq;

namespace NHibernate.Mapping
{
Expand All @@ -14,7 +15,7 @@ public class ForeignKey : Constraint
private Table referencedTable;
private string referencedEntityName;
private bool cascadeDeleteEnabled;
private readonly List<Column> referencedColumns = new List<Column>();
private List<Column> referencedColumns;

/// <summary>
/// Generates the SQL string to create the named Foreign Key Constraint in the database.
Expand All @@ -26,29 +27,26 @@ public class ForeignKey : Constraint
/// <returns>
/// A string that contains the SQL to create the named Foreign Key Constraint.
/// </returns>
public override string SqlConstraintString(Dialect.Dialect d, string constraintName, string defaultCatalog, string defaultSchema)
{
string[] cols = new string[ColumnSpan];
string[] refcols = new string[ColumnSpan];
int i = 0;
IEnumerable<Column> refiter;
if (IsReferenceToPrimaryKey)
refiter = referencedTable.PrimaryKey.ColumnIterator;
else
refiter = referencedColumns;
foreach (Column column in ColumnIterator)
{
cols[i] = column.GetQuotedName(d);
i++;
}
public override string SqlConstraintString(
Dialect.Dialect d,
string constraintName,
string defaultCatalog,
string defaultSchema)
{
var refiter = IsReferenceToPrimaryKey
? referencedTable.PrimaryKey.Columns
: referencedColumns;

var cols = Columns.ToArray(column => column.GetQuotedName(d));
var refcols = refiter.ToArray(column => column.GetQuotedName(d));

string result = d.GetAddForeignKeyConstraintString(
constraintName,
cols,
referencedTable.GetQualifiedName(d, defaultCatalog, defaultSchema),
refcols,
IsReferenceToPrimaryKey);

i = 0;
foreach (Column column in refiter)
{
refcols[i] = column.GetQuotedName(d);
i++;
}
string result = d.GetAddForeignKeyConstraintString(constraintName, cols, referencedTable.GetQualifiedName(d, defaultCatalog, defaultSchema), refcols, IsReferenceToPrimaryKey);
return cascadeDeleteEnabled && d.SupportsCascadeDelete ? result + " on delete cascade" : result;
}

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

private void AddReferencedColumn(Column column)
{
referencedColumns ??= new List<Column>(1);
if (!referencedColumns.Contains(column))
referencedColumns.Add(column);
}

internal void AddReferencedTable(PersistentClass referencedClass)
{
if (referencedColumns.Count > 0)
{
referencedTable = referencedColumns[0].Value.Table;
}
else
{
referencedTable = referencedClass.Table;
}
referencedTable = IsReferenceToPrimaryKey ? referencedClass.Table : referencedColumns[0].Value.Table;
}

public override string ToString()
{
if (!IsReferenceToPrimaryKey)
{
var result = new StringBuilder();
result.Append(GetType().FullName)
.Append('(')
.Append(Table.Name)
.Append(string.Join(", ", Columns))
.Append(" ref-columns:")
.Append('(')
.Append(string.Join(", ", ReferencedColumns))
.Append(") as ")
.Append(Name);
return result.ToString();
}
if (IsReferenceToPrimaryKey)
return base.ToString();

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

public bool HasPhysicalConstraint
Expand All @@ -218,7 +200,11 @@ public bool HasPhysicalConstraint

public IList<Column> ReferencedColumns
{
get { return referencedColumns; }
get
{
referencedColumns ??= new List<Column>(1);
return referencedColumns;
}
}

public string ReferencedEntityName
Expand All @@ -228,10 +214,7 @@ public string ReferencedEntityName
}

/// <summary>Does this foreignkey reference the primary key of the reference table </summary>
public bool IsReferenceToPrimaryKey
{
get { return referencedColumns.Count == 0; }
}
public bool IsReferenceToPrimaryKey => referencedColumns == null || referencedColumns.Count == 0;

public string GeneratedConstraintNamePrefix => "FK_";

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

foreach (var column in ReferencedColumns)
{
if (column.IsNullable)
return false;
}
return true;
return referencedColumns.All(column => !column.IsNullable);
}
}
}
2 changes: 1 addition & 1 deletion src/NHibernate/Mapping/Index.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace NHibernate.Mapping
public class Index : IRelationalModel
{
private Table table;
private readonly List<Column> columns = new List<Column>();
private readonly List<Column> columns = new List<Column>(1);
private string name;

public static string BuildSqlCreateIndexString(Dialect.Dialect dialect, string name, Table table,
Expand Down
2 changes: 1 addition & 1 deletion src/NHibernate/Mapping/SimpleValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace NHibernate.Mapping
[Serializable]
public class SimpleValue : IKeyValue
{
private readonly List<ISelectable> columns = new List<ISelectable>();
private readonly List<ISelectable> columns = new List<ISelectable>(1);
private IType type;
private IDictionary<string, string> typeParameters;

Expand Down
3 changes: 3 additions & 0 deletions src/NHibernate/Mapping/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,9 +1064,12 @@ internal ForeignKeyKey(IEnumerable<Column> columns, string referencedClassName,
{
this.referencedClassName = referencedClassName;
this.columns = new List<Column>(columns);
this.columns.TrimExcess();

if (referencedColumns != null)
{
this.referencedColumns = new List<Column>(referencedColumns);
this.referencedColumns.TrimExcess();
}
else
{
Expand Down
3 changes: 3 additions & 0 deletions src/NHibernate/SqlCommand/SqlString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ internal SqlString(IEnumerable<object> parts)
_firstPartIndex = _parts.Count > 0 ? 0 : -1;
_lastPartIndex = _parts.Count - 1;
_length = sqlIndex;

_parts.TrimExcess();
_parameters.TrimExcess();
}

#endregion
Expand Down
Loading