Skip to content

Commit 49f3280

Browse files
committed
Collections usage improvements
1 parent a1d4427 commit 49f3280

25 files changed

Lines changed: 121 additions & 127 deletions

Orm/Xtensive.Orm/Collections/Deque.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ public Deque(int initialCapacity, float growFactor)
610610
/// <param name="source">The initial contents of the <see cref="Deque{T}"/>.</param>
611611
public Deque(IEnumerable<T> source)
612612
{
613-
items = new List<T>(source).ToArray();
613+
items = source.ToArray();
614614
headPos = -1;
615615
tailPos = items.Length;
616616
count = items.Length;

Orm/Xtensive.Orm/Linq/ConstantExtractor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public LambdaExpression Process()
4949
if (constantValues != null)
5050
throw new InvalidOperationException();
5151
constantValues = new List<object>();
52-
var parameters = EnumerableUtils.One(ConstantParameter).Concat(lambda.Parameters).ToArray();
52+
var parameters = EnumerableUtils.One(ConstantParameter).Concat(lambda.Parameters).ToArray(lambda.Parameters.Count + 1);
5353
var body = Visit(lambda.Body);
5454
// Preserve original delegate type because it may differ from types of parameters / return value
5555
return FastExpression.Lambda(FixDelegateType(lambda.Type), body, parameters);

Orm/Xtensive.Orm/Linq/SerializableExpressions/Internals/ExpressionToSerializableExpressionConverter.cs

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -192,56 +192,48 @@ protected override SerializableInvocationExpression VisitInvocation(InvocationEx
192192

193193
#region Private / internal methods
194194

195-
private SerializableMemberBinding[] VisitMemberBindingSequence(IEnumerable<MemberBinding> bindings)
196-
{
197-
var result = new List<SerializableMemberBinding>();
198-
foreach (var binding in bindings)
199-
switch (binding.BindingType) {
200-
case MemberBindingType.Assignment:
201-
result.Add(new SerializableMemberAssignment
202-
{
203-
BindingType = MemberBindingType.Assignment,
204-
Member = binding.Member,
205-
Expression = Visit(((MemberAssignment) binding).Expression)
206-
});
207-
break;
208-
case MemberBindingType.ListBinding:
209-
result.Add(new SerializableMemberListBinding
210-
{
211-
BindingType = MemberBindingType.ListBinding,
212-
Member = binding.Member,
213-
Initializers = VisitElementInitSequence(((MemberListBinding) binding).Initializers)
214-
});
215-
break;
216-
case MemberBindingType.MemberBinding:
217-
result.Add(new SerializableMemberMemberBinding
218-
{
219-
BindingType = MemberBindingType.MemberBinding,
220-
Member = binding.Member,
221-
Bindings = VisitMemberBindingSequence(((MemberMemberBinding) binding).Bindings)
222-
});
223-
break;
224-
default:
225-
throw new ArgumentOutOfRangeException();
226-
}
227-
return result.ToArray();
228-
}
229-
230-
private SerializableElementInit[] VisitElementInitSequence(IEnumerable<ElementInit> initializers)
195+
private SerializableMemberBinding[] VisitMemberBindingSequence(IReadOnlyList<MemberBinding> bindings)
196+
{
197+
var arrayResult = new SerializableMemberBinding[bindings.Count];
198+
for (int i = 0, count = bindings.Count; i < count; i++) {
199+
var binding = bindings[i];
200+
arrayResult[i] = binding.BindingType switch {
201+
MemberBindingType.Assignment => new SerializableMemberAssignment() {
202+
BindingType = MemberBindingType.Assignment,
203+
Member = binding.Member,
204+
Expression = Visit(((MemberAssignment) binding).Expression)
205+
},
206+
MemberBindingType.ListBinding => new SerializableMemberListBinding {
207+
BindingType = MemberBindingType.ListBinding,
208+
Member = binding.Member,
209+
Initializers = VisitElementInitSequence(((MemberListBinding) binding).Initializers)
210+
},
211+
MemberBindingType.MemberBinding => new SerializableMemberMemberBinding {
212+
BindingType = MemberBindingType.MemberBinding,
213+
Member = binding.Member,
214+
Bindings = VisitMemberBindingSequence(((MemberMemberBinding) binding).Bindings)
215+
},
216+
_ => throw new ArgumentOutOfRangeException()
217+
218+
};
219+
}
220+
return arrayResult;
221+
}
222+
223+
private SerializableElementInit[] VisitElementInitSequence(IList<ElementInit> initializers)
231224
{
232225
return initializers
233-
.Select(initializer => new SerializableElementInit
226+
.SelectToArray(initializer => new SerializableElementInit
234227
{
235228
AddMethod = initializer.AddMethod,
236229
Arguments = VisitExpressionSequence(initializer.Arguments)
237-
})
238-
.ToArray();
230+
});
239231
}
240232

241-
private SerializableExpression[] VisitExpressionSequence<T>(IEnumerable<T> expressions)
233+
private SerializableExpression[] VisitExpressionSequence<T>(IList<T> expressions)
242234
where T : Expression
243235
{
244-
return expressions.Select(e => Visit(e)).ToArray();
236+
return expressions.SelectToArray(e => Visit(e));
245237
}
246238

247239
#endregion

Orm/Xtensive.Orm/Linq/SerializableExpressions/Internals/SerializableExpressionToExpressionConverter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Linq;
1010
using System.Linq.Expressions;
1111
using System.Reflection;
12+
using Xtensive.Core;
1213

1314
namespace Xtensive.Linq.SerializableExpressions.Internals
1415
{
@@ -177,7 +178,7 @@ private Expression VisitMethodCall(SerializableMethodCallExpression mc)
177178

178179
private Expression VisitLambda(SerializableLambdaExpression l)
179180
{
180-
var parameters = l.Parameters.Select(p => (ParameterExpression) Visit(p)).ToList();
181+
var parameters = l.Parameters.SelectToArray(p => (ParameterExpression) Visit(p));
181182
using (CreateParameterScope(parameters)) {
182183
return FastExpression.Lambda(l.Type, Visit(l.Body), parameters);
183184
}

Orm/Xtensive.Orm/Orm/Building/FixupActionProcessor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System;
88
using System.Collections.Generic;
99
using System.Linq;
10+
using Xtensive.Core;
1011
using Xtensive.Orm.Building.Builders;
1112
using Xtensive.Orm.Building.Definitions;
1213
using Xtensive.Orm.Building.DependencyGraph;
@@ -92,9 +93,8 @@ public void Process(BuildGenericTypeInstancesAction action)
9293
var typeSubstitutions = new Type[arguments.Length][];
9394
for (var i = 0; i < arguments.Length; i++) {
9495
var argument = arguments[i];
95-
var constraints = argument.GetGenericParameterConstraints()
96-
.ToList();
97-
if (constraints.Count==0 || !constraints.Any(c => WellKnownOrmInterfaces.Entity.IsAssignableFrom(c)))
96+
var constraints = argument.GetGenericParameterConstraints();
97+
if (constraints.Length==0 || !constraints.Any(c => WellKnownOrmInterfaces.Entity.IsAssignableFrom(c)))
9898
return; // No IEntity / Entity constraints
9999
var queue = new Queue<Type>(
100100
from hierarchy in hierarchies

Orm/Xtensive.Orm/Orm/Building/PrefetchActionContainer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal sealed class PrefetchActionContainer
2525
public Action<SessionHandler, IEnumerable<Key>> BuildPrefetchAction(IEnumerable<AssociationInfo> associations)
2626
{
2727
fields = associations.Select(static association => new PrefetchFieldDescriptor(association.OwnerField, true, false))
28-
.ToList();
28+
.ToArray();
2929
return fields.Count > 0 ? Prefetch : null;
3030
}
3131

Orm/Xtensive.Orm/Orm/Linq/Expressions/ConstructorExpression.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ public Expression BindParameter(ParameterExpression parameter, Dictionary<Expres
3535
e => GenericExpressionVisitor<IMappedExpression>.Process(e, mapped => mapped.BindParameter(parameter, processedExpressions));
3636
return new ConstructorExpression(
3737
Type,
38-
Bindings.ToDictionary(kvp => kvp.Key, kvp => genericBinder(kvp.Value)),
39-
NativeBindings.ToDictionary(kvp=>kvp.Key, kvp => genericBinder(kvp.Value)),
38+
Bindings.ToDictionary(kvp => kvp.Key, kvp => genericBinder(kvp.Value), Bindings.Count),
39+
NativeBindings.ToDictionary(kvp=>kvp.Key, kvp => genericBinder(kvp.Value), NativeBindings.Count),
4040
Constructor,
41-
ConstructorArguments.Select(genericBinder).ToList());
41+
ConstructorArguments.Select(genericBinder).ToArray());
4242
}
4343

4444
public Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
@@ -50,7 +50,7 @@ public Expression RemoveOuterParameter(Dictionary<Expression, Expression> proces
5050
Bindings.ToDictionary(kvp => kvp.Key, kvp => genericRemover(kvp.Value)),
5151
NativeBindings = NativeBindings.ToDictionary(kvp => kvp.Key, kvp => genericRemover(kvp.Value)),
5252
Constructor,
53-
ConstructorArguments.Select(genericRemover).ToList());
53+
ConstructorArguments.Select(genericRemover).ToArray());
5454
return result;
5555
}
5656

Orm/Xtensive.Orm/Orm/Linq/MemberCompilation/MemberCompilerProvider.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private static (MemberInfo targetMember, Delegate compilerInvoker) ProcessCompil
174174
bool isGenericMethod = attribute.NumberOfGenericArguments > 0;
175175
bool isGenericType = targetType.IsGenericType;
176176
bool isGeneric = isGenericType || isGenericMethod;
177-
177+
178178
string memberName = attribute.TargetMember;
179179

180180
if (memberName.IsNullOrEmpty())
@@ -191,18 +191,21 @@ private static (MemberInfo targetMember, Delegate compilerInvoker) ProcessCompil
191191

192192
if (isCtor)
193193
bindingFlags |= BindingFlags.Instance;
194-
else
194+
else {
195195
if (!isStatic) {
196-
if (parameterTypes.Length==0)
196+
if (parameterTypes.Length == 0)
197197
throw new InvalidOperationException(string.Format(
198198
Strings.ExCompilerXShouldHaveThisParameter,
199199
compiler.GetFullName(true)));
200200

201-
parameterTypes = parameterTypes.Skip(1).ToArray();
201+
var noInstanceParameter = new Type[parameterTypes.Length - 1];
202+
Array.Copy(parameterTypes, 1, noInstanceParameter, 0, noInstanceParameter.Length);
203+
parameterTypes = noInstanceParameter;
202204
bindingFlags |= BindingFlags.Instance;
203205
}
204206
else
205207
bindingFlags |= BindingFlags.Static;
208+
}
206209

207210
if (isPropertyGetter) {
208211
bindingFlags |= BindingFlags.GetProperty;

Orm/Xtensive.Orm/Orm/Upgrade/Internals/CatalogCloner.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public Catalog Clone(Catalog source, MappingResolver mappingResolver, string new
3131

3232
private Dictionary<string, string> CloneSchemas(Catalog newCatalog, Catalog sourceCatalog, MappingResolver mappingResolver)
3333
{
34-
var schemaMap = new Dictionary<string, string>();
34+
var schemaMap = new Dictionary<string, string>(sourceCatalog.Schemas.Count);
3535
foreach (var schema in sourceCatalog.Schemas) {
3636
var complexName = mappingResolver.GetNodeName(newCatalog.Name, schema.Name, "Dummy");
3737
var names = complexName.Split(NameElementSeparator);
@@ -336,16 +336,14 @@ private void CloneTableConstraint(Table newTable, TableConstraint sourceConstrai
336336
return;
337337
}
338338

339-
var uniqueConstraint = sourceConstraint as UniqueConstraint;
340-
if (uniqueConstraint!=null) {
341-
var primaryKey = sourceConstraint as PrimaryKey;
342-
if (primaryKey!=null) {
343-
var columns = primaryKey.Columns.Select(c => newTable.TableColumns[c.Name]).ToArray();
344-
var pk =newTable.CreatePrimaryKey(primaryKey.Name, columns);
339+
if (sourceConstraint is UniqueConstraint uniqueConstraint) {
340+
if (sourceConstraint is PrimaryKey primaryKey) {
341+
var columns = primaryKey.Columns.SelectToArray(c => newTable.TableColumns[c.Name]);
342+
var pk = newTable.CreatePrimaryKey(primaryKey.Name, columns);
345343
CopyDbName(pk, primaryKey);
346344
}
347345
else {
348-
var columns = uniqueConstraint.Columns.Select(c => newTable.TableColumns[c.Name]).ToArray();
346+
var columns = uniqueConstraint.Columns.SelectToArray(c => newTable.TableColumns[c.Name]);
349347
var uc = newTable.CreateUniqueConstraint(uniqueConstraint.Name, columns);
350348
CopyDbName(uc, uniqueConstraint);
351349
}

Orm/Xtensive.Orm/Orm/Upgrade/Internals/DomainModelConverter.cs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,17 @@ protected override StorageModel VisitDomainModel(DomainModel domainModel)
113113
// Build hierarchy foreign keys
114114
var indexPairs = new Dictionary<Pair<IndexInfo>, object>();
115115
foreach (var type in domainModel.Types.Entities) {
116-
if (type.Hierarchy==null || type.Hierarchy.InheritanceSchema==InheritanceSchema.ConcreteTable)
116+
if (type.Hierarchy is null || type.Hierarchy.InheritanceSchema==InheritanceSchema.ConcreteTable)
117117
continue;
118118
if (type.Indexes.PrimaryIndex.IsVirtual) {
119-
Dictionary<TypeInfo, int> typeOrder = type.Ancestors
119+
var typeOrder = type.Ancestors
120120
.Append(type)
121-
.Select((t, i) => (Type: t, Index: i))
122-
.ToDictionary(a => a.Type, a => a.Index);
123-
List<IndexInfo> realPrimaryIndexes = type.Indexes.RealPrimaryIndexes
121+
.Select(static (t, i) => (Type: t, Index: i))
122+
.ToDictionary(static a => a.Type, static a => a.Index, capacity: type.Ancestors.Count);
123+
var realPrimaryIndexes = type.Indexes.RealPrimaryIndexes
124124
.OrderBy(index => typeOrder[index.ReflectedType])
125-
.ToList();
126-
for (int i = 0; i < realPrimaryIndexes.Count - 1; i++) {
125+
.ToArray(type.Indexes.RealPrimaryIndexes.Count);
126+
for (int i = 0, edge = realPrimaryIndexes.Length - 1; i < edge; i++) {
127127
if (realPrimaryIndexes[i]!=realPrimaryIndexes[i + 1]) {
128128
var pair = new Pair<IndexInfo>(realPrimaryIndexes[i], realPrimaryIndexes[i + 1]);
129129
indexPairs[pair] = null;
@@ -137,7 +137,7 @@ protected override StorageModel VisitDomainModel(DomainModel domainModel)
137137
var referencingTable = targetModel.Tables[resolver.GetNodeName(referencingIndex.ReflectedType)];
138138
var referencedTable = targetModel.Tables[resolver.GetNodeName(referencedIndex.ReflectedType)];
139139
var storageReferencingIndex = FindIndex(
140-
referencingTable, referencingIndex.KeyColumns.Select(ci => ci.Key.Name).ToList());
140+
referencingTable, referencingIndex.KeyColumns.Select(static ci => ci.Key.Name).ToArray());
141141

142142
string foreignKeyName = nameBuilder.BuildHierarchyForeignKeyName(referencingIndex.ReflectedType, referencedIndex.ReflectedType);
143143
CreateHierarchyForeignKey(referencingTable, referencedTable, storageReferencingIndex, foreignKeyName);
@@ -320,19 +320,19 @@ private PrimaryIndexInfo VisitPrimaryIndexInfo(IndexInfo index)
320320
return primaryIndex;
321321
}
322322

323-
private IEnumerable<TableInfo> CreateTables(IndexInfo index)
323+
private IReadOnlyList<TableInfo> CreateTables(IndexInfo index)
324324
{
325-
var result = new List<TableInfo>();
326325
var type = index.ReflectedType;
327-
if (configuration.IsMultidatabase && type.UnderlyingType.Namespace==MetadataNamespace) {
326+
if (configuration.IsMultidatabase && type.UnderlyingType.Namespace == MetadataNamespace) {
327+
var parts = new List<TableInfo>(sourceModel.Databases.Count);
328328
foreach (var db in sourceModel.Databases) {
329329
var name = resolver.GetNodeName(db.Name, type.MappingSchema, type.MappingName);
330-
result.Add(new TableInfo(targetModel, name));
330+
parts.Add(new TableInfo(targetModel, name));
331331
}
332+
return parts;
332333
}
333334
else
334-
result.Add(new TableInfo(targetModel, resolver.GetNodeName(type)));
335-
return result;
335+
return new[] { new TableInfo(targetModel, resolver.GetNodeName(type)) };
336336
}
337337

338338
#region Not supported
@@ -401,17 +401,24 @@ private string GetColumnDefaultSqlExpression(ColumnInfo column)
401401

402402
private static StorageIndexInfo FindIndex(TableInfo table, ICollection<string> keyColumns)
403403
{
404-
var primaryKeyColumns = table.PrimaryIndex.KeyColumns.Select(cr => cr.Value.Name).ToList();
404+
var primaryIndex = table.PrimaryIndex;
405+
var primaryKeyColumns = primaryIndex.KeyColumns.Select(ColumnNameSelector).ToList(primaryIndex.KeyColumns.Count);
405406

406407
if (!primaryKeyColumns.Except(keyColumns).Union(keyColumns.Except(primaryKeyColumns)).Any())
407408
return table.PrimaryIndex;
408409

409410
foreach (SecondaryIndexInfo index in table.SecondaryIndexes) {
410-
var secondaryKeyColumns = index.KeyColumns.Select(cr => cr.Value.Name).ToList();
411+
var secondaryKeyColumns = index.KeyColumns.Select(ColumnNameSelector).ToList(index.KeyColumns.Count);
411412
if (!secondaryKeyColumns.Except(keyColumns).Union(keyColumns.Except(secondaryKeyColumns)).Any())
412413
return index;
413414
}
414415
return null;
416+
417+
418+
static string ColumnNameSelector(KeyColumnRef cr)
419+
{
420+
return cr.Value.Name;
421+
}
415422
}
416423

417424
private TableInfo GetTable(TypeInfo type)
@@ -440,7 +447,7 @@ private static string GetPrimaryIndexColumnName(IndexInfo primaryIndex, ColumnIn
440447

441448
private static void CreateReferenceForeignKey(TableInfo referencingTable, TableInfo referencedTable, FieldInfo referencingField, string foreignKeyName)
442449
{
443-
var foreignColumns = referencingField.Columns.Select(column => referencingTable.Columns[column.Name]).ToList();
450+
var foreignColumns = referencingField.Columns.SelectToArray(column => referencingTable.Columns[column.Name]);
444451
var foreignKey = new ForeignKeyInfo(referencingTable, foreignKeyName) {
445452
PrimaryKey = referencedTable.PrimaryIndex,
446453
OnRemoveAction = ReferentialAction.None,

0 commit comments

Comments
 (0)