Skip to content

Commit db538f3

Browse files
committed
AggregateProvider and CalculateProvider saves some time and memory
Avoid copying descriptors when it is possible by using IReadOnlyList<T> constructor parameter instead of params T[]. Constructors enumerate collections of descriptors, having option to pass List<T> and array of T is benifitial.
1 parent bee6405 commit db538f3

File tree

8 files changed

+92
-30
lines changed

8 files changed

+92
-30
lines changed

Orm/Xtensive.Orm/Orm/Linq/Translator.Queryable.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -726,9 +726,15 @@ private Expression VisitAggregate(Expression source, MethodInfo method, LambdaEx
726726
SubqueryFilterRemover.Process(originDataSource, groupingFilterParameter),
727727
ref aggregateDescriptor);
728728
if (commonOriginDataSource != null) {
729+
var aggregateDescriptors = groupingDataSource.AggregateColumns
730+
.Select(c => c.Descriptor)
731+
.Append(aggregateDescriptor)
732+
.ToArray(groupingDataSource.AggregateColumns.Length + 1);
733+
729734
resultDataSource = new AggregateProvider(
730-
commonOriginDataSource, groupingDataSource.GroupColumnIndexes,
731-
groupingDataSource.AggregateColumns.Select(c => c.Descriptor).Append(aggregateDescriptor).ToArray());
735+
commonOriginDataSource,
736+
groupingDataSource.GroupColumnIndexes,
737+
(IReadOnlyList<AggregateColumnDescriptor>) aggregateDescriptors);
732738
var optimizedItemProjector = groupingProjection.ItemProjector.Remap(resultDataSource, 0);
733739
groupingProjection = new ProjectionExpression(
734740
groupingProjection.Type, optimizedItemProjector,

Orm/Xtensive.Orm/Orm/Rse/CompilableProviderExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ public static class CompilableProviderExtensions
2626
public static CompilableProvider Calculate(this CompilableProvider source,
2727
params CalculatedColumnDescriptor[] columns)
2828
{
29-
return new CalculateProvider(source, columns);
29+
return new CalculateProvider(source, (IReadOnlyList<CalculatedColumnDescriptor>) columns);
3030
}
3131

3232
public static CompilableProvider Calculate(this CompilableProvider source, bool isInlined,
3333
params CalculatedColumnDescriptor[] columns)
3434
{
35-
return new CalculateProvider(source, isInlined, columns);
35+
return new CalculateProvider(source, (IReadOnlyList<CalculatedColumnDescriptor>) columns, isInlined);
3636
}
3737

3838
public static CompilableProvider RowNumber(this CompilableProvider source, string columnName)
@@ -99,7 +99,7 @@ public static CompilableProvider Seek(this CompilableProvider source, Tuple key)
9999
public static CompilableProvider Aggregate(this CompilableProvider recordQuery,
100100
int[] groupIndexes, params AggregateColumnDescriptor[] descriptors)
101101
{
102-
return new AggregateProvider(recordQuery, groupIndexes, descriptors);
102+
return new AggregateProvider(recordQuery, groupIndexes, (IReadOnlyList<AggregateColumnDescriptor>) descriptors);
103103
}
104104

105105
public static CompilableProvider Skip(this CompilableProvider source, Func<ParameterContext, int> count)

Orm/Xtensive.Orm/Orm/Rse/Providers/Compilable/AggregateProvider.cs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2008-2020 Xtensive LLC.
1+
// Copyright (C) 2008-2024 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Elena Vakhtina
@@ -192,21 +192,59 @@ private static NotSupportedException AggregateNotSupported(Type sourceColumnType
192192
/// Initializes a new instance of this class.
193193
/// </summary>
194194
/// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param>
195-
/// <param name="columnDescriptors">The descriptors of <see cref="AggregateColumns"/>.</param>
196195
/// <param name="groupIndexes">The column indexes to group by.</param>
196+
/// <param name="columnDescriptors">The descriptors of <see cref="AggregateColumns"/>.</param>
197+
[Obsolete]
197198
public AggregateProvider(CompilableProvider source, int[] groupIndexes, params AggregateColumnDescriptor[] columnDescriptors)
199+
: this(source, groupIndexes, (IReadOnlyList<AggregateColumnDescriptor>) columnDescriptors)
200+
{
201+
}
202+
203+
/// <summary>
204+
/// Initializes a new instance of this class.
205+
/// </summary>
206+
/// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param>
207+
/// <param name="groupIndexes">The column indexes to group by.</param>
208+
/// <param name="columnDescriptors">The descriptors of <see cref="AggregateColumns"/>.</param>
209+
public AggregateProvider(CompilableProvider source, int[] groupIndexes, IReadOnlyList<AggregateColumnDescriptor> columnDescriptors)
210+
: base(ProviderType.Aggregate, source)
211+
{
212+
ArgumentValidator.EnsureArgumentNotNull(columnDescriptors, nameof(columnDescriptors));
213+
groupIndexes = groupIndexes ?? Array.Empty<int>();
214+
var columns = new AggregateColumn[columnDescriptors.Count];
215+
for (int i = 0, count = columnDescriptors.Count; i < count; i++) {
216+
var descriptor = columnDescriptors[i];
217+
var type = GetAggregateColumnType(Source.Header.Columns[descriptor.SourceIndex].Type, descriptor.AggregateType);
218+
columns[i] = new AggregateColumn(descriptor, groupIndexes.Length + i, type);
219+
}
220+
AggregateColumns = columns;
221+
GroupColumnIndexes = groupIndexes;
222+
Initialize();
223+
}
224+
225+
/// <summary>
226+
/// Initializes a new instance of this class. Internal use only!
227+
/// </summary>
228+
/// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param>
229+
/// <param name="groupIndexes">The column indexes to group by.</param>
230+
/// <param name="descriptorSource">Columns of old AggregateProvider as source of descriptors.</param>
231+
internal AggregateProvider(CompilableProvider source, int[] groupIndexes, IReadOnlyList<AggregateColumn> descriptorSource)
198232
: base(ProviderType.Aggregate, source)
199233
{
200-
groupIndexes = groupIndexes ?? ArrayUtils<int>.EmptyArray;
201-
var columns = new AggregateColumn[columnDescriptors.Length];
202-
for (int i = 0; i < columnDescriptors.Length; i++) {
203-
AggregateColumnDescriptor descriptor = columnDescriptors[i];
234+
// Having this dedicated ctor saves some resources on not having to make
235+
// an array just to pass descriptors for simple enumeration
236+
groupIndexes = groupIndexes ?? Array.Empty<int>();
237+
var columns = new AggregateColumn[descriptorSource.Count];
238+
for (int i = 0, count = descriptorSource.Count; i < count; i++) {
239+
var sourceDescriptor = descriptorSource[i].Descriptor;
240+
var descriptor = new AggregateColumnDescriptor(sourceDescriptor.Name, sourceDescriptor.SourceIndex, sourceDescriptor.AggregateType);
204241
var type = GetAggregateColumnType(Source.Header.Columns[descriptor.SourceIndex].Type, descriptor.AggregateType);
205242
columns[i] = new AggregateColumn(descriptor, groupIndexes.Length + i, type);
206243
}
207244
AggregateColumns = columns;
208245
GroupColumnIndexes = groupIndexes;
209246
Initialize();
210247
}
248+
211249
}
212250
}

Orm/Xtensive.Orm/Orm/Rse/Providers/Compilable/CalculateProvider.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// Copyright (C) 2003-2010 Xtensive LLC.
2-
// All rights reserved.
3-
// For conditions of distribution and use, see license.
1+
// Copyright (C) 2008-2024 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
44
// Created by: Elena Vakhtina
55
// Created: 2008.09.09
66

@@ -9,6 +9,7 @@
99

1010
using Xtensive.Tuples.Transform;
1111
using Xtensive.Collections;
12+
using System.Collections.Generic;
1213

1314
namespace Xtensive.Orm.Rse.Providers
1415
{
@@ -65,6 +66,7 @@ protected override void Initialize()
6566
/// </summary>
6667
/// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param>
6768
/// <param name="columnDescriptors">The descriptors of <see cref="CalculatedColumns"/>.</param>
69+
[Obsolete]
6870
public CalculateProvider(CompilableProvider source, params CalculatedColumnDescriptor[] columnDescriptors)
6971
: this(source, false, columnDescriptors)
7072
{
@@ -76,6 +78,7 @@ public CalculateProvider(CompilableProvider source, params CalculatedColumnDescr
7678
/// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param>
7779
/// <param name="isInlined">The <see cref="IsInlined"/> property value.</param>
7880
/// <param name="columnDescriptors">The descriptors of <see cref="CalculatedColumns"/>.</param>
81+
[Obsolete]
7982
public CalculateProvider(CompilableProvider source, bool isInlined, params CalculatedColumnDescriptor[] columnDescriptors)
8083
: base(ProviderType.Calculate, source)
8184
{
@@ -88,5 +91,26 @@ public CalculateProvider(CompilableProvider source, bool isInlined, params Calcu
8891
CalculatedColumns = columns;
8992
Initialize();
9093
}
94+
95+
/// <summary>
96+
/// Initializes a new instance of this class.
97+
/// </summary>
98+
/// <param name="source">The <see cref="UnaryProvider.Source"/> property value.</param>
99+
/// <param name="isInlined">The <see cref="IsInlined"/> property value.</param>
100+
/// <param name="columnDescriptors">The descriptors of <see cref="CalculatedColumns"/>.</param>
101+
public CalculateProvider(CompilableProvider source, IReadOnlyList<CalculatedColumnDescriptor> columnDescriptors, bool isInlined = false)
102+
: base(ProviderType.Calculate, source)
103+
{
104+
ArgumentValidator.EnsureArgumentNotNull(columnDescriptors, nameof(columnDescriptors));
105+
106+
IsInlined = isInlined;
107+
var columns = new CalculatedColumn[columnDescriptors.Count];
108+
for (int i = 0, count = columnDescriptors.Count; i < count; i++) {
109+
var col = new CalculatedColumn(columnDescriptors[i], Source.Header.Length + i);
110+
columns.SetValue(col, i);
111+
}
112+
CalculatedColumns = columns;
113+
Initialize();
114+
}
91115
}
92116
}

Orm/Xtensive.Orm/Orm/Rse/Providers/CompilableProviderVisitor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ protected override Provider VisitCalculate(CalculateProvider provider)
157157
}
158158
if (!translated && source == provider.Source)
159159
return provider;
160-
return new CalculateProvider(source, descriptors.ToArray());
160+
return new CalculateProvider(source, descriptors);
161161
}
162162

163163
protected override Provider VisitRowNumber(RowNumberProvider provider)
@@ -193,10 +193,10 @@ protected override Provider VisitAggregate(AggregateProvider provider)
193193
if (resultParameters == null) {
194194
var acd = new List<AggregateColumnDescriptor>(provider.AggregateColumns.Length);
195195
acd.AddRange(provider.AggregateColumns.Select(ac => new AggregateColumnDescriptor(ac.Name, ac.SourceIndex, ac.AggregateType)));
196-
return new AggregateProvider(source, provider.GroupColumnIndexes, acd.ToArray());
196+
return new AggregateProvider(source, provider.GroupColumnIndexes, acd);
197197
}
198198
var result = (Pair<int[], AggregateColumnDescriptor[]>) resultParameters;
199-
return new AggregateProvider(source, result.First, result.Second);
199+
return new AggregateProvider(source, result.First, (IReadOnlyList<AggregateColumnDescriptor>) result.Second);
200200
}
201201

202202
/// <inheritdoc/>

Orm/Xtensive.Orm/Orm/Rse/Transformation/ColumnMappingInspector.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ protected override Provider VisitAggregate(AggregateProvider provider)
272272
.Select(index => sourceMap.IndexOf(index))
273273
.ToArray(provider.GroupColumnIndexes.Length);
274274

275-
return new AggregateProvider(source, groupColumnIndexes, columns.ToArray());
275+
return new AggregateProvider(source, groupColumnIndexes, columns);
276276
}
277277

278278
protected override Provider VisitCalculate(CalculateProvider provider)
@@ -309,7 +309,7 @@ protected override Provider VisitCalculate(CalculateProvider provider)
309309

310310
return !translated && newSourceProvider == provider.Source && descriptors.Count == provider.CalculatedColumns.Length
311311
? provider
312-
: new CalculateProvider(newSourceProvider, descriptors.ToArray());
312+
: new CalculateProvider(newSourceProvider, descriptors);
313313
}
314314

315315
protected override Provider VisitRowNumber(RowNumberProvider provider)
@@ -444,7 +444,7 @@ private static List<int> Merge(List<int> leftMap, IEnumerable<int> rightMap)
444444
return preReturn;
445445
}
446446

447-
private static List<int> Merge(List<int> leftMap, List<int> rightMap)
447+
private static List<int> Merge(List<int> leftMap, IList<int> rightMap)
448448
{
449449
var preReturn = leftMap.Union(rightMap).ToList(leftMap.Count + rightMap.Count);
450450
preReturn.Sort();

Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/ApplyProviderCorrectorRewriter.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,19 +391,15 @@ private void EnsureAbsenceOfApplyProviderRequiringConversion()
391391

392392
private static AggregateProvider RecreateAggregate(AggregateProvider provider, CompilableProvider source)
393393
{
394-
var columnCount = provider.AggregateColumns.Length;
395-
var acds = provider.AggregateColumns.SelectToArray(
396-
ac => new AggregateColumnDescriptor(ac.Name, ac.SourceIndex, ac.AggregateType));
397-
return new AggregateProvider(source, provider.GroupColumnIndexes, acds);
394+
return new AggregateProvider(source, provider.GroupColumnIndexes, provider.AggregateColumns);
398395
}
399396

400397
private static CalculateProvider RecreateCalculate(CalculateProvider provider, CompilableProvider source)
401398
{
402-
var columnsCount = provider.CalculatedColumns.Length;
403399
var ccds = provider.CalculatedColumns
404400
.SelectToArray(
405401
column => new CalculatedColumnDescriptor(column.Name, column.Type, column.Expression));
406-
return new CalculateProvider(source, ccds);
402+
return new CalculateProvider(source, (IReadOnlyList<CalculatedColumnDescriptor>) ccds);
407403
}
408404

409405
private CalculateProvider RewriteCalculateColumnExpressions(
@@ -419,7 +415,7 @@ private CalculateProvider RewriteCalculateColumnExpressions(
419415
var currentName = columnCollection.Single(c => c.Index==column.Index).Name;
420416
return new CalculatedColumnDescriptor(currentName, column.Type, newColumnExpression);
421417
});
422-
return new CalculateProvider(source, ccd);
418+
return new CalculateProvider(source, (IReadOnlyList<CalculatedColumnDescriptor>) ccd);
423419
}
424420

425421
#endregion

Orm/Xtensive.Orm/Orm/Rse/Transformation/Internals/OrderingRewriter.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,7 @@ protected override Provider VisitAggregate(AggregateProvider provider)
9898
var result = provider;
9999
var source = VisitCompilable(provider.Source);
100100
if (source != provider.Source) {
101-
var acds =provider.AggregateColumns
102-
.Select(ac => new AggregateColumnDescriptor(ac.Name, ac.SourceIndex, ac.AggregateType));
103-
result = new AggregateProvider(source, provider.GroupColumnIndexes, acds.ToArray());
101+
result = new AggregateProvider(source, provider.GroupColumnIndexes, provider.AggregateColumns);
104102
}
105103
if (sortOrder.Count > 0) {
106104
var selectOrdering = new DirectionCollection<int>();

0 commit comments

Comments
 (0)