Skip to content

Commit edfc564

Browse files
committed
Reduce memory and cpu consumption of types registration in tests
1 parent 1fcd7b9 commit edfc564

458 files changed

Lines changed: 839 additions & 754 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Orm/Xtensive.Orm.Tests.Framework/AssemblyExtensions.cs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,101 @@
44
// Created by: Alexey Kulakov
55
// Created: 2018.08.31
66

7+
using System;
8+
using System.Collections.Concurrent;
9+
using System.Collections.Generic;
710
using System.Configuration;
11+
using System.Linq;
812
using System.Reflection;
13+
using System.Runtime.CompilerServices;
914

1015
namespace Xtensive.Orm.Tests
1116
{
1217
public static class AssemblyExtensions
1318
{
19+
private static readonly Type ObjectType = typeof(object);
20+
private static readonly ConcurrentDictionary<Assembly, Type[]> TypesPerAssembly = new();
21+
1422
public static System.Configuration.Configuration GetAssemblyConfiguration(this Assembly assembly)
1523
{
1624
return ConfigurationManager.OpenExeConfiguration(assembly.Location);
1725
}
26+
27+
public static IReadOnlyList<Type> GetTypesFromNamespaceCaching(this Assembly assembly, string @namespace)
28+
{
29+
// these two dummy mentions to not forget to sync filtration algorithm here and in the classes,
30+
// in particular BaseType property, if the property changed then this algorighm should be changed as well
31+
_ = nameof(Xtensive.IoC.ServiceTypeRegistrationProcessor.BaseType);
32+
_ = nameof(Xtensive.Orm.Configuration.DomainTypeRegistrationHandler.BaseType);
33+
34+
var assemblyTypes = TypesPerAssembly.GetOrAdd(assembly, static (a) => {
35+
var allTypes = a.GetTypes();
36+
var list = new List<Type>(allTypes.Length);
37+
foreach (var t in allTypes) {
38+
// we ignore compiler generated types because usuallty they are
39+
// at the end of sorted types
40+
if (t.IsSubclassOf(ObjectType) && t.GetCustomAttribute<CompilerGeneratedAttribute>()==null)
41+
list.Add(t);
42+
}
43+
return list.ToArray();
44+
});
45+
46+
var range = FindRange(assemblyTypes, @namespace);
47+
return new ArraySegment<Type>(assemblyTypes, range.first, range.last - range.first + 1);
48+
49+
50+
//type.IsSubclassOf(BaseType) && (ns.IsNullOrEmpty() || (type.FullName.IndexOf(ns + ".", StringComparison.InvariantCulture) >= 0));
51+
}
52+
53+
private static (int first, int last) FindRange(Type[] types, string ns)
54+
{
55+
const int windowSize = 10;
56+
57+
// we rely on the fact that types are sorted by full name, that means types of same namespace are go one by one
58+
// which gives us to optimize search - we find first type that has desired namespace, then we try to find last one
59+
// and then we return the part of original array as result
60+
var firstHit = -1;
61+
var lastHit = -1;
62+
63+
for (int headIndex = 0, count = types.Length ; headIndex < count; headIndex++) {
64+
var head = types[headIndex];
65+
if (head.FullName.IndexOf(ns + ".", StringComparison.InvariantCulture) >= 0) {
66+
firstHit = headIndex;
67+
break;
68+
}
69+
}
70+
71+
var isOutOfRange = false;
72+
do {
73+
lastHit = firstHit + windowSize;
74+
if (lastHit > types.Length - 1) {
75+
lastHit = types.Length - 1;
76+
}
77+
var tail = types[lastHit];
78+
if (tail.FullName.IndexOf(ns + ".", StringComparison.InvariantCulture) < 0)
79+
isOutOfRange = true;
80+
}
81+
while (!isOutOfRange);
82+
83+
for (int tailIndex = lastHit; tailIndex > firstHit; tailIndex--) {
84+
var tail = types[tailIndex];
85+
if (tail.FullName.IndexOf(ns + ".", StringComparison.InvariantCulture) >= 0) {
86+
lastHit = tailIndex;
87+
break;
88+
}
89+
}
90+
91+
return (firstHit, lastHit);
92+
}
93+
}
94+
95+
public static class TypeRegistryExtensions
96+
{
97+
public static void RegisterCaching(this Xtensive.Orm.Configuration.DomainTypeRegistry _this, Assembly assembly, string @namespace)
98+
{
99+
foreach (var t in assembly.GetTypesFromNamespaceCaching(@namespace)) {
100+
_this.Register(t);
101+
}
102+
}
18103
}
19104
}

Orm/Xtensive.Orm.Tests/Interfaces/DoubleIndexedInterfaceTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2011 Xtensive LLC.
1+
// Copyright (C) 2011 Xtensive LLC.
22
// All rights reserved.
33
// For conditions of distribution and use, see license.
44
// Created by: Denis Krjuchkov
@@ -59,7 +59,7 @@ public class DoubleIndexedInterfaceTest : AutoBuildTest
5959
protected override DomainConfiguration BuildConfiguration()
6060
{
6161
var config = base.BuildConfiguration();
62-
config.Types.Register(typeof (ITest).Assembly, typeof (ITest).Namespace);
62+
config.Types.RegisterCaching(typeof (ITest).Assembly, typeof (ITest).Namespace);
6363
return config;
6464
}
6565

Orm/Xtensive.Orm.Tests/Interfaces/InterfaceImplementationTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public class InterfaceImplementationTest
7070
public void CompsiteIndexTest()
7171
{
7272
var config = DomainConfigurationFactory.Create();
73-
config.Types.Register(typeof(IHasName).Assembly, typeof(IHasName).Namespace);
73+
config.Types.RegisterCaching(typeof(IHasName).Assembly, typeof(IHasName).Namespace);
7474
var domain = GetClassTableDomain(config);
7575
using (var session = domain.OpenSession())
7676
using (var t = session.OpenTransaction()) {
@@ -99,7 +99,7 @@ public void CombinedTest()
9999
public void InternalTest(Func<DomainConfiguration, Domain> generator)
100100
{
101101
var config = DomainConfigurationFactory.Create();
102-
config.Types.Register(typeof(IHasName).Assembly, typeof(IHasName).Namespace);
102+
config.Types.RegisterCaching(typeof(IHasName).Assembly, typeof(IHasName).Namespace);
103103
var domain = generator(config);
104104
using (var session = domain.OpenSession())
105105
using (var t = session.OpenTransaction()) {

Orm/Xtensive.Orm.Tests/Interfaces/InterfaceTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public class InterfaceTest : AutoBuildTest
109109
protected override DomainConfiguration BuildConfiguration()
110110
{
111111
var config = base.BuildConfiguration();
112-
config.Types.Register(typeof (Person1).Assembly, typeof (Person1).Namespace);
112+
config.Types.RegisterCaching(typeof (Person1).Assembly, typeof (Person1).Namespace);
113113
return config;
114114
}
115115

Orm/Xtensive.Orm.Tests/Interfaces/KeyStructureConflictTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class KeyStructureConflictTest : AutoBuildTest
5050
protected override DomainConfiguration BuildConfiguration()
5151
{
5252
var config = base.BuildConfiguration();
53-
config.Types.Register(typeof (Root1).Assembly, typeof (Root1).Namespace);
53+
config.Types.RegisterCaching(typeof (Root1).Assembly, typeof (Root1).Namespace);
5454
return config;
5555
}
5656

Orm/Xtensive.Orm.Tests/Interfaces/TypeIdModeConflictTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class TypeIdModeConflictTest : AutoBuildTest
3939
protected override DomainConfiguration BuildConfiguration()
4040
{
4141
var config = base.BuildConfiguration();
42-
config.Types.Register(typeof (Root1).Assembly, typeof (Root1).Namespace);
42+
config.Types.RegisterCaching(typeof (Root1).Assembly, typeof (Root1).Namespace);
4343
return config;
4444
}
4545

Orm/Xtensive.Orm.Tests/Interfaces/UnusedTypeRemovalTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public void MainTest()
6262
protected override DomainConfiguration BuildConfiguration()
6363
{
6464
var config = base.BuildConfiguration();
65-
config.Types.Register(typeof (IFirst).Assembly, typeof (IFirst).Namespace);
65+
config.Types.RegisterCaching(typeof (IFirst).Assembly, typeof (IFirst).Namespace);
6666
return config;
6767
}
6868

Orm/Xtensive.Orm.Tests/Issues/BatchingCommandProcessorFrenzy.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2012 Xtensive LLC.
1+
// Copyright (C) 2012 Xtensive LLC.
22
// All rights reserved.
33
// For conditions of distribution and use, see license.
44
// Created by: Denis Krjuchkov
@@ -27,7 +27,7 @@ public class BatchingCommandProcessorFrenzy : AutoBuildTest
2727
protected override DomainConfiguration BuildConfiguration()
2828
{
2929
var configuration = base.BuildConfiguration();
30-
configuration.Types.Register(typeof (FrenzyEntity).Assembly, typeof (FrenzyEntity).Namespace);
30+
configuration.Types.RegisterCaching(typeof (FrenzyEntity).Assembly, typeof (FrenzyEntity).Namespace);
3131
return configuration;
3232
}
3333

Orm/Xtensive.Orm.Tests/Issues/ClientProfileEntitySetTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2012 Xtensive LLC.
1+
// Copyright (C) 2012 Xtensive LLC.
22
// All rights reserved.
33
// For conditions of distribution and use, see license.
44
// Created by: Denis Krjuchkov
@@ -48,7 +48,7 @@ public class ClientProfileEntitySetTest : AutoBuildTest
4848
protected override DomainConfiguration BuildConfiguration()
4949
{
5050
var configuration = base.BuildConfiguration();
51-
configuration.Types.Register(typeof (Owner).Assembly, typeof (Owner).Namespace);
51+
configuration.Types.RegisterCaching(typeof (Owner).Assembly, typeof (Owner).Namespace);
5252
configuration.Sessions.Default.Options = SessionOptions.ClientProfile;
5353
return configuration;
5454
}

Orm/Xtensive.Orm.Tests/Issues/CustomCompilerException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public class CustomCompilerException : AutoBuildTest
116116
protected override DomainConfiguration BuildConfiguration()
117117
{
118118
var config = base.BuildConfiguration();
119-
config.Types.Register(typeof (FundBase).Assembly, typeof (FundBase).Namespace);
119+
config.Types.RegisterCaching(typeof (FundBase).Assembly, typeof (FundBase).Namespace);
120120
return config;
121121
}
122122

0 commit comments

Comments
 (0)