Skip to content

Commit 2159545

Browse files
committed
Some code improvements
1 parent d6de718 commit 2159545

1 file changed

Lines changed: 54 additions & 63 deletions

File tree

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

Lines changed: 54 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,16 @@ namespace Xtensive.Orm.Tests
1616
{
1717
public static class AssemblyExtensions
1818
{
19-
private const string MainTestAsseblyNsPrefix = "Xtensive.Orm.Tests."; // keep the dot at the end
20-
private const string IssuesNsPrefix = "Xtensive.Orm.Tests.Issues.";// keep the dot at the end
21-
private const string UpgradeNsPrefix = "Xtensive.Orm.Tests.Upgrade.";// keep the dot at the end
19+
private const string MainTestAsseblyNsPrefix = "Xtensive.Orm.Tests.";
20+
private const string IssuesNsPrefix = "Xtensive.Orm.Tests.Issues.";
21+
private const string UpgradeNsPrefix = "Xtensive.Orm.Tests.Upgrade.";
2222

23-
2423
private static readonly byte[] ThisAssemblyPkt = typeof(AssemblyExtensions).Assembly.GetName().GetPublicKeyToken();
2524

2625
private static readonly ConcurrentDictionary<Assembly, Type[]> TypesPerAssembly = new();
27-
private static readonly ConcurrentDictionary<char, int> XtensiveOrmTestsNsAlphabeticIndex = new();
28-
private static readonly ConcurrentDictionary<char, int> MainTestsForUpgrade = new();
29-
private static readonly ConcurrentDictionary<char, int> MainTestsForIssues = new();
26+
private static readonly ConcurrentDictionary<char, int> MainTestsAssemblyNsAlphabeticIndex = new();
27+
private static readonly ConcurrentDictionary<char, int> MainTestsAssemblyIssuesNsAlphabeticIndex = new();
28+
private static readonly ConcurrentDictionary<char, int> MainTestsAssemblyUpgradeNsAlphabeticIndex = new();
3029

3130
public static System.Configuration.Configuration GetAssemblyConfiguration(this Assembly assembly)
3231
{
@@ -36,7 +35,7 @@ public static System.Configuration.Configuration GetAssemblyConfiguration(this A
3635
public static IReadOnlyList<Type> GetTypesFromNamespaceCaching(this Assembly assembly, string @namespace)
3736
{
3837
if (string.IsNullOrWhiteSpace(@namespace))
39-
throw new ArgumentException("Namespace cannot be null, empty or contains only white spaces");
38+
throw new ArgumentException("Namespace cannot be null, empty or contain only white spaces");
4039

4140
// these two dummy mentionsa are to not forget to sync filtration algorithm here and in the classes,
4241
// in particular BaseType property, if the property changed then this algorighm should be changed as well
@@ -53,24 +52,22 @@ public static IReadOnlyList<Type> GetTypesFromNamespaceCaching(this Assembly ass
5352
var list = new List<Type>(allTypes.Length);
5453
var currentIndex = 0;
5554
foreach (var t in allTypes) {
56-
// we ignore compiler generated types because usuallty they are
57-
// at the end of sorted types
55+
// we ignore compiler generated types because usuallty they are at the end of sorted types' array
5856
if (t.IsSubclassOf(objectType) && t.GetCustomAttribute<CompilerGeneratedAttribute>() == null) {
5957
list.Add(t);
6058
if (isMain) {
6159
var nSpace = t.Namespace;
6260
if (nSpace != null && nSpace.StartsWith(MainTestAsseblyNsPrefix, StringComparison.Ordinal)) {
6361
var firstLetter = nSpace[MainTestAsseblyNsPrefix.Length];
64-
// main test library has 5000+ types, to not enumerate them every type from the beginning
65-
// we try to have parts by first letter
66-
_ = XtensiveOrmTestsNsAlphabeticIndex.TryAdd(firstLetter, currentIndex);
67-
if (firstLetter == 'I'/*ssue*/ && nSpace.StartsWith(IssuesNsPrefix)) {
62+
63+
_ = MainTestsAssemblyNsAlphabeticIndex.TryAdd(firstLetter, currentIndex);
64+
if (firstLetter == 'I'/*ssue*/ && nSpace.StartsWith(IssuesNsPrefix, StringComparison.Ordinal)) {
6865
var firstIssuesLetter = nSpace[IssuesNsPrefix.Length];
69-
_ = MainTestsForIssues.TryAdd(firstIssuesLetter, currentIndex);
66+
_ = MainTestsAssemblyIssuesNsAlphabeticIndex.TryAdd(firstIssuesLetter, currentIndex);
7067
}
71-
if (firstLetter== 'U'/*pdate*/ && nSpace.StartsWith(UpgradeNsPrefix)) {
68+
if (firstLetter == 'U'/*pdate*/ && nSpace.StartsWith(UpgradeNsPrefix, StringComparison.Ordinal)) {
7269
var firstIssuesLetter = nSpace[UpgradeNsPrefix.Length];
73-
_ = MainTestsForUpgrade.TryAdd(firstIssuesLetter, currentIndex);
70+
_ = MainTestsAssemblyUpgradeNsAlphabeticIndex.TryAdd(firstIssuesLetter, currentIndex);
7471
}
7572
}
7673
}
@@ -83,42 +80,6 @@ public static IReadOnlyList<Type> GetTypesFromNamespaceCaching(this Assembly ass
8380
return FindSegment(assemblyTypes, @namespace, isMainTestAssembly);
8481
}
8582

86-
private static int GetSearchStartPosition(string ns, bool isMainAssembly)
87-
{
88-
var searchStart = 0;
89-
if (isMainAssembly) {
90-
if (ns.StartsWith(IssuesNsPrefix)) {
91-
searchStart = MainTestsForIssues[ns[IssuesNsPrefix.Length]];
92-
}
93-
else if (ns.StartsWith(UpgradeNsPrefix)) {
94-
searchStart = MainTestsForUpgrade[ns[UpgradeNsPrefix.Length]];
95-
}
96-
else if (ns.StartsWith(MainTestAsseblyNsPrefix)) {
97-
searchStart = XtensiveOrmTestsNsAlphabeticIndex[ns[MainTestAsseblyNsPrefix.Length]];
98-
}
99-
}
100-
101-
return searchStart;
102-
}
103-
104-
private static int FindFirstEntry(Type[] types, in int serachFrom, in string nsAndDot)
105-
{
106-
var firstHit = -1;
107-
108-
for (int headIndex = serachFrom, count = types.Length; headIndex < count; headIndex++) {
109-
var head = types[headIndex];
110-
if (head.FullName.IndexOf(nsAndDot, StringComparison.InvariantCulture) >= 0) {
111-
firstHit = headIndex;
112-
break;
113-
}
114-
}
115-
116-
if (firstHit == -1)
117-
throw new Exception($"There is no any entry for fiven namespace.");
118-
119-
return firstHit;
120-
}
121-
12283
private static IReadOnlyList<Type> FindSegment(Type[] types, string ns, bool isMainAssembly)
12384
{
12485
// We rely on the fact that types are sorted by full name.
@@ -129,32 +90,62 @@ private static IReadOnlyList<Type> FindSegment(Type[] types, string ns, bool isM
12990

13091
var searchFrom = GetSearchStartPosition(ns, isMainAssembly);
13192

132-
var nsAndDot = ns + ".";
133-
var startSearchBoundary = FindFirstEntry(types, searchFrom, nsAndDot);
93+
var nsWithDot = ns + ".";
94+
var startSearchBoundary = FindFirstEntry(types, searchFrom, nsWithDot);
13495

135-
var wrongNsFound = false;
13696
var endSearchBoundary = startSearchBoundary;
137-
var lastTypeIndex = types.Length - 1;
97+
var lastItemIndex = types.Length - 1;
98+
99+
bool wrongNsFound;
138100
do {
139101
endSearchBoundary += windowSize;
140-
if (endSearchBoundary > lastTypeIndex)
141-
endSearchBoundary = lastTypeIndex;
102+
if (endSearchBoundary > lastItemIndex)
103+
endSearchBoundary = lastItemIndex;
142104

143105
var tail = types[endSearchBoundary];
144-
if (tail.FullName.IndexOf(nsAndDot, StringComparison.InvariantCulture) < 0)
145-
wrongNsFound = true;
106+
wrongNsFound = tail.FullName.IndexOf(nsWithDot, StringComparison.InvariantCulture) < 0;
146107
}
147-
while (!wrongNsFound || endSearchBoundary < lastTypeIndex);
108+
while (!wrongNsFound || endSearchBoundary < lastItemIndex);
148109

149110
for (var tailIndex = endSearchBoundary; tailIndex >= startSearchBoundary; tailIndex--) {
150111
var tail = types[tailIndex];
151112
endSearchBoundary = tailIndex;
152-
if (tail.FullName.IndexOf(nsAndDot, StringComparison.InvariantCulture) >= 0) {
113+
if (tail.FullName.IndexOf(nsWithDot, StringComparison.InvariantCulture) >= 0) {
153114
break;
154115
}
155116
}
156117

157118
return new ArraySegment<Type>(types, startSearchBoundary, endSearchBoundary - startSearchBoundary + 1);
158119
}
120+
121+
private static int GetSearchStartPosition(string ns, bool isMainAssembly)
122+
{
123+
if (!isMainAssembly)
124+
return 0;
125+
if (ns.StartsWith(IssuesNsPrefix, StringComparison.Ordinal))
126+
return MainTestsAssemblyIssuesNsAlphabeticIndex[ns[IssuesNsPrefix.Length]];
127+
else if (ns.StartsWith(UpgradeNsPrefix, StringComparison.Ordinal))
128+
return MainTestsAssemblyUpgradeNsAlphabeticIndex[ns[UpgradeNsPrefix.Length]];
129+
else if (ns.StartsWith(MainTestAsseblyNsPrefix, StringComparison.Ordinal))
130+
return MainTestsAssemblyNsAlphabeticIndex [ns[MainTestAsseblyNsPrefix.Length]];
131+
return 0;
132+
}
133+
134+
private static int FindFirstEntry(Type[] types, in int serachFrom, in string nsAndDot)
135+
{
136+
var firstEntryIndex = -1;
137+
138+
for (int headIndex = serachFrom, count = types.Length; headIndex < count; headIndex++) {
139+
var head = types[headIndex];
140+
if (head.FullName.IndexOf(nsAndDot, StringComparison.InvariantCulture) >= 0) {
141+
firstEntryIndex = headIndex;
142+
break;
143+
}
144+
}
145+
146+
if (firstEntryIndex == -1)
147+
throw new Exception($"There is no any entry for given namespace.");
148+
return firstEntryIndex;
149+
}
159150
}
160151
}

0 commit comments

Comments
 (0)