Skip to content

Commit 3525a34

Browse files
authored
Merge pull request #158 from servicetitan/Optimize_CreateTypeIdAccessor
Optimize TypeId accessors
2 parents 84c8bd5 + 0cdd0e3 commit 3525a34

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

Orm/Xtensive.Orm/Orm/Providers/SqlCompiler.Index.cs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Created: 2009.11.13
66

77
using System;
8+
using System.Collections.Concurrent;
89
using System.Collections.Generic;
910
using System.Linq;
1011
using System.Linq.Expressions;
@@ -17,6 +18,7 @@
1718
using Xtensive.Sql;
1819
using Xtensive.Sql.Dml;
1920
using IndexInfo = Xtensive.Orm.Model.IndexInfo;
21+
using TypeMapping = Xtensive.Sql.TypeMapping;
2022

2123
namespace Xtensive.Orm.Providers
2224
{
@@ -39,6 +41,13 @@ public QueryAndBindings(SqlSelect initialQuery, List<QueryParameterBinding> bind
3941
}
4042
}
4143

44+
private static readonly ConcurrentDictionary<int, Func<ParameterContext, object>> typeIdParameterAccessorCache =
45+
new ConcurrentDictionary<int, Func<ParameterContext, object>>();
46+
47+
private static readonly Func<int, Func<ParameterContext, object>> AccessorFactory = typeId => _ => typeId;
48+
49+
private TypeMapping int32TypeMapping;
50+
4251
protected override SqlProvider VisitFreeText(FreeTextProvider provider)
4352
{
4453
throw new NotSupportedException();
@@ -249,20 +258,15 @@ private QueryAndBindings BuildFilteredQuery(IndexInfo index)
249258
SqlDml.Array(filterByTypes.Select(t => TypeIdRegistry[t]).ToArray(filterByTypes.Count)));
250259
}
251260
else {
252-
var typeMapping = Driver.GetTypeMapping(WellKnownTypes.Int32);
253261
if (filterByTypes.Count == 1) {
254-
var binding = new QueryParameterBinding(typeMapping,
255-
CreateTypeIdAccessor(TypeIdRegistry[type]).CachingCompile(),
256-
QueryParameterBindingType.Regular);
262+
var binding = CreateQueryParameterBinding(type);
257263
bindings.Add(binding);
258264
filter = typeIdColumn == binding.ParameterReference;
259265
}
260266
else {
261267
var typeIdParameters = filterByTypes
262268
.Select(t => {
263-
var binding = new QueryParameterBinding(typeMapping,
264-
CreateTypeIdAccessor(TypeIdRegistry[t]).CachingCompile(),
265-
QueryParameterBindingType.Regular);
269+
var binding = CreateQueryParameterBinding(t);
266270
bindings.Add(binding);
267271
return binding.ParameterReference;
268272
})
@@ -308,8 +312,7 @@ private QueryAndBindings BuildTypedQuery(IndexInfo index)
308312

309313
SqlUserColumn typeIdColumn;
310314
if (useParameterForTypeId) {
311-
var typeMapping = Driver.GetTypeMapping(WellKnownTypes.Int32);
312-
var binding = new QueryParameterBinding(typeMapping, CreateTypeIdAccessor(TypeIdRegistry[type]).CachingCompile(), QueryParameterBindingType.Regular);
315+
var binding = CreateQueryParameterBinding(type);
313316

314317
typeIdColumn = SqlDml.Column(binding.ParameterReference);
315318
bindings.Add(binding);
@@ -352,11 +355,11 @@ private object GetDiscriminatorValue(TypeDiscriminatorMap discriminatorMap, obje
352355
: fieldValue;
353356
}
354357

355-
private Expression<Func<ParameterContext, object>> CreateTypeIdAccessor(int value)
356-
{
357-
var bodyExpression = Expression.Convert(Expression.Constant(value),WellKnownTypes.Object);
358-
var lambdaParemeter = Expression.Parameter(WellKnownOrmTypes.ParameterContext, "context");
359-
return (Expression<Func<ParameterContext, object>>) FastExpression.Lambda(bodyExpression, lambdaParemeter);
360-
}
358+
private QueryParameterBinding CreateQueryParameterBinding(TypeInfo type) =>
359+
new QueryParameterBinding(
360+
int32TypeMapping ??= Driver.GetTypeMapping(WellKnownTypes.Int32),
361+
typeIdParameterAccessorCache.GetOrAdd(TypeIdRegistry[type], AccessorFactory),
362+
QueryParameterBindingType.Regular
363+
);
361364
}
362365
}

0 commit comments

Comments
 (0)