Skip to content

Optimize PersistParameterBinding #345

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 1 commit into from
Jan 24, 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
4 changes: 0 additions & 4 deletions Orm/Xtensive.Orm/Orm/Providers/Requests/ParameterBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
// Created by: Dmitri Maximov
// Created: 2008.09.26

using System;
using System.Collections.Generic;
using System.Linq;
using Xtensive.Core;
using Xtensive.Sql;
using Xtensive.Sql.Dml;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Xtensive.Orm.Providers
/// Possible way of delivering parameter to server
/// for <see cref="QueryParameterBinding"/> and <see cref="PersistParameterBinding"/>.
/// </summary>
public enum ParameterTransmissionType
public enum ParameterTransmissionType : byte
{
/// <summary>
/// Indicates that no special handling of parameter is performed.
Expand All @@ -27,4 +27,4 @@ public enum ParameterTransmissionType
/// </summary>
BinaryLob = 2,
}
}
}
74 changes: 28 additions & 46 deletions Orm/Xtensive.Orm/Orm/Providers/Requests/PersistParameterBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,39 @@
// Created by: Dmitri Maximov
// Created: 2008.09.25

using System;
using Xtensive.Core;
using Xtensive.Sql;

namespace Xtensive.Orm.Providers
namespace Xtensive.Orm.Providers;

/// <summary>
/// A binding of a parameter for <see cref="PersistRequest"/>.
/// </summary>
public sealed class PersistParameterBinding(
TypeMapping typeMapping,
ushort rowIndex,
ColNum fieldIndex,
ParameterTransmissionType transmissionType = ParameterTransmissionType.Regular,
PersistParameterBindingType bindingType = PersistParameterBindingType.Regular
) : ParameterBinding(typeMapping, transmissionType)
{
/// <summary>
/// A binding of a parameter for <see cref="PersistRequest"/>.
/// </summary>
public sealed class PersistParameterBinding : ParameterBinding
{
public int RowIndex { get; private set; }

public int FieldIndex { get; private set; }

public PersistParameterBindingType BindingType { get; private set; }

// Constructors

public PersistParameterBinding(TypeMapping typeMapping, int rowIndex, int fieldIndex,
ParameterTransmissionType transmissionType, PersistParameterBindingType bindingType)
: base(typeMapping, transmissionType)
{
RowIndex = rowIndex;
FieldIndex = fieldIndex;
BindingType = bindingType;
}

public PersistParameterBinding(TypeMapping typeMapping, int fieldIndex, ParameterTransmissionType transmissionType, PersistParameterBindingType bindingType)
: this(typeMapping, 0, fieldIndex, transmissionType, bindingType)
{
}
public ushort RowIndex { get; } = rowIndex;
public ColNum FieldIndex { get; } = fieldIndex;
public PersistParameterBindingType BindingType { get; } = bindingType;

public PersistParameterBinding(TypeMapping typeMapping, int rowIndex, int fieldIndex, ParameterTransmissionType transmissionType)
: this(typeMapping, rowIndex, fieldIndex, transmissionType, PersistParameterBindingType.Regular)
{
}
// Constructors

public PersistParameterBinding(TypeMapping typeMapping, int fieldIndex, ParameterTransmissionType transmissionType)
: this(typeMapping, fieldIndex, transmissionType, PersistParameterBindingType.Regular)
{
}
public PersistParameterBinding(TypeMapping typeMapping, ColNum fieldIndex, ParameterTransmissionType transmissionType, PersistParameterBindingType bindingType)
: this(typeMapping, 0, fieldIndex, transmissionType, bindingType)
{
}

public PersistParameterBinding(TypeMapping typeMapping, int rowIndex, int fieldIndex)
: this(typeMapping, rowIndex, fieldIndex, ParameterTransmissionType.Regular, PersistParameterBindingType.Regular)
{
}
public PersistParameterBinding(TypeMapping typeMapping, ColNum fieldIndex, ParameterTransmissionType transmissionType)
: this(typeMapping, fieldIndex, transmissionType, PersistParameterBindingType.Regular)
{
}

public PersistParameterBinding(TypeMapping typeMapping, int fieldIndex)
: this(typeMapping, fieldIndex, ParameterTransmissionType.Regular, PersistParameterBindingType.Regular)
{
}
public PersistParameterBinding(TypeMapping typeMapping, ColNum fieldIndex)
: this(typeMapping, fieldIndex, ParameterTransmissionType.Regular, PersistParameterBindingType.Regular)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Xtensive.Orm.Providers
/// <summary>
/// Possible types of <see cref="PersistParameterBinding"/>.
/// </summary>
public enum PersistParameterBindingType
public enum PersistParameterBindingType : byte
{
/// <summary>
/// Regular parameter. Parameter value is obtained thru difference tuple.
Expand All @@ -17,4 +17,4 @@ public enum PersistParameterBindingType
/// </summary>
VersionFilter = 1,
}
}
}
29 changes: 12 additions & 17 deletions Orm/Xtensive.Orm/Orm/Providers/Requests/PersistRequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ internal IReadOnlyList<PersistRequest> Build(StorageNode node, PersistRequestBui
return result.AsSafeWrapper();
}

protected virtual List<PersistRequest> BuildInsertRequest(PersistRequestBuilderContext context)
protected virtual List<PersistRequest> BuildInsertRequest(in PersistRequestBuilderContext context)
{
var result = new List<PersistRequest>();
foreach (var index in context.AffectedIndexes) {
Expand All @@ -88,7 +88,7 @@ protected virtual List<PersistRequest> BuildInsertRequest(PersistRequestBuilderC
return result;
}

protected virtual List<PersistRequest> BuildUpdateRequest(PersistRequestBuilderContext context)
protected virtual List<PersistRequest> BuildUpdateRequest(in PersistRequestBuilderContext context)
{
var result = new List<PersistRequest>();
foreach (var index in context.AffectedIndexes) {
Expand Down Expand Up @@ -130,7 +130,7 @@ protected virtual List<PersistRequest> BuildUpdateRequest(PersistRequestBuilderC
return result;
}

protected virtual List<PersistRequest> BuildRemoveRequest(PersistRequestBuilderContext context)
protected virtual List<PersistRequest> BuildRemoveRequest(in PersistRequestBuilderContext context)
{
var result = new List<PersistRequest>();
for (var i = context.AffectedIndexes.Count - 1; i >= 0; i--) {
Expand All @@ -147,7 +147,7 @@ protected virtual List<PersistRequest> BuildRemoveRequest(PersistRequestBuilderC
return result;
}

private SqlExpression BuildKeyFilter(PersistRequestBuilderContext context, SqlTableRef filteredTable, List<PersistParameterBinding> currentBindings)
private SqlExpression BuildKeyFilter(in PersistRequestBuilderContext context, SqlTableRef filteredTable, List<PersistParameterBinding> currentBindings)
{
SqlExpression result = null;
foreach (var column in context.PrimaryIndex.KeyColumns.Keys) {
Expand All @@ -163,7 +163,7 @@ private SqlExpression BuildKeyFilter(PersistRequestBuilderContext context, SqlTa
return result;
}

private SqlExpression BuildVersionFilter(PersistRequestBuilderContext context, SqlTableRef filteredTable, List<PersistParameterBinding> currentBindings)
private SqlExpression BuildVersionFilter(in PersistRequestBuilderContext context, SqlTableRef filteredTable, List<PersistParameterBinding> currentBindings)
{
SqlExpression result = null;
foreach (var column in context.Type.GetVersionColumns()) {
Expand Down Expand Up @@ -193,7 +193,7 @@ private SqlExpression BuildVersionFilter(PersistRequestBuilderContext context, S
return result;
}

private bool AddFakeVersionColumnUpdate(PersistRequestBuilderContext context, SqlUpdate update, SqlTableRef filteredTable)
private bool AddFakeVersionColumnUpdate(in PersistRequestBuilderContext context, SqlUpdate update, SqlTableRef filteredTable)
{
foreach (var column in context.Type.GetVersionColumns()) {
var columnExpression = filteredTable[column.Name];
Expand All @@ -210,7 +210,7 @@ private bool AddFakeVersionColumnUpdate(PersistRequestBuilderContext context, Sq
return false;
}

private PersistParameterBinding GetBinding(PersistRequestBuilderContext context, ColumnInfo column, Table table, int fieldIndex)
private PersistParameterBinding GetBinding(PersistRequestBuilderContext context, ColumnInfo column, Table table, ColNum fieldIndex)
{
if (!context.ParameterBindings.TryGetValue(column, out var binding)) {
var typeMapping = driver.GetTypeMapping(column);
Expand All @@ -236,15 +236,10 @@ private ParameterTransmissionType GetTransmissionType(TableColumn column)
: ParameterTransmissionType.Regular;
}

private static int GetFieldIndex(TypeInfo type, ColumnInfo column)
{
if (!type.Fields.TryGetValue(column.Field.Name, out var field)
|| field.Column == null
|| field.Column.ValueType != column.ValueType) {
return -1;
}
return field.MappingInfo.Offset;
}
private static ColNum GetFieldIndex(TypeInfo type, ColumnInfo column) =>
type.Fields.TryGetValue(column.Field.Name, out var field) && field.Column?.ValueType == column.ValueType
? field.MappingInfo.Offset
: (ColNum)(-1);

/// <inheritdoc/>
protected override void Initialize()
Expand All @@ -263,4 +258,4 @@ public PersistRequestBuilder()
{
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
// Created by: Dmitri Maximov
// Created: 2008.08.29

using System.Collections.Generic;
using System.Linq;
using Xtensive.Collections;
using Xtensive.Core;
using Xtensive.Orm.Configuration;
using Xtensive.Orm.Model;
Expand All @@ -16,23 +13,23 @@ namespace Xtensive.Orm.Providers
/// <summary>
/// <see cref="PersistRequestBuilder"/> context.
/// </summary>
public sealed class PersistRequestBuilderContext
public readonly struct PersistRequestBuilderContext
{
public PersistRequestBuilderTask Task { get; private set; }
public PersistRequestBuilderTask Task { get; }

public ModelMapping Mapping { get; private set; }
public ModelMapping Mapping { get; }

public NodeConfiguration NodeConfiguration { get; private set; }
public NodeConfiguration NodeConfiguration { get; }

public TypeInfo Type { get; private set; }
public TypeInfo Type { get; }

public IReadOnlyList<IndexInfo> AffectedIndexes { get; private set;}
public IReadOnlyList<IndexInfo> AffectedIndexes { get; }

public IndexInfo PrimaryIndex { get; private set; }
public IndexInfo PrimaryIndex { get; }

public Dictionary<ColumnInfo, PersistParameterBinding> ParameterBindings { get; private set; }
public Dictionary<ColumnInfo, PersistParameterBinding> ParameterBindings { get; }

public Dictionary<ColumnInfo, PersistParameterBinding> VersionParameterBindings { get; private set; }
public Dictionary<ColumnInfo, PersistParameterBinding> VersionParameterBindings { get; }

// Constructors

Expand Down Expand Up @@ -60,4 +57,4 @@ public PersistRequestBuilderContext(PersistRequestBuilderTask task, ModelMapping
VersionParameterBindings = new Dictionary<ColumnInfo, PersistParameterBinding>();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public TemporaryTableDescriptor BuildDescriptor(ModelMapping modelMapping, strin

return result;

Lazy<PersistRequest> CreateLazyPersistRequest(int batchSize)
Lazy<PersistRequest> CreateLazyPersistRequest(ushort batchSize)
{
return new Lazy<PersistRequest>(() => {
var bindings = new List<PersistParameterBinding>(batchSize);
Expand Down Expand Up @@ -214,16 +214,16 @@ private SqlSelect MakeUpSelectQuery(SqlTableRef temporaryTable, bool hasColumns)
}

private SqlInsert MakeUpInsertQuery(SqlTableRef temporaryTable,
TypeMapping[] typeMappings, List<PersistParameterBinding> storeRequestBindings, bool hasColumns, int rows = 1)
TypeMapping[] typeMappings, List<PersistParameterBinding> storeRequestBindings, bool hasColumns, ushort rows = 1)
{
var insertStatement = SqlDml.Insert(temporaryTable);
if (!hasColumns) {
insertStatement.ValueRows.Add(new Dictionary<SqlColumn, SqlExpression>(1) { { temporaryTable.Columns[0], SqlDml.Literal(0) } });
return insertStatement;
}

for (var rowIndex = 0; rowIndex < rows; ++rowIndex) {
var fieldIndex = 0;
for (ushort rowIndex = 0; rowIndex < rows; ++rowIndex) {
ColNum fieldIndex = 0;
var row = new Dictionary<SqlColumn, SqlExpression>(temporaryTable.Columns.Count);
foreach (var column in temporaryTable.Columns) {
var typeMapping = typeMappings[fieldIndex];
Expand All @@ -249,4 +249,4 @@ protected override void Initialize()
backEnd = new EmulatedTemporaryTableBackEnd();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private IPersistDescriptor CreateDescriptor(string tableName,
var insert = SqlDml.Insert(tableRef);
var bindings = new PersistParameterBinding[columns.Count];
var row = new Dictionary<SqlColumn, SqlExpression>(columns.Count);
for (int i = 0; i < columns.Count; i++) {
for (ColNum i = 0; i < columns.Count; i++) {
var binding = new PersistParameterBinding(mappings[i], i, transmissionTypes[i]);
row.Add(tableRef.Columns[i], binding.ParameterReference);
bindings[i] = binding;
Expand Down
Loading