@@ -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