@@ -22,24 +22,59 @@ internal static class SortHelpers
2222 /// <param name="inputs">The inputs.</param>
2323 /// <param name="keySelector">The key selector.</param>
2424 /// <returns></returns>
25- internal static Dictionary < TKey , IList < TValue > > BucketSort < TValue , TKey > ( IList < TValue > inputs , KeySelector < TValue , TKey > keySelector ) where TKey : IEquatable < TKey >
25+ internal static ICollection < KeyValuePair < TKey , IList < TValue > > > BucketSort < TValue , TKey > ( IList < TValue > inputs , KeySelector < TValue , TKey > keySelector ) where TKey : IEquatable < TKey >
2626 {
27- var retVal = new Dictionary < TKey , IList < TValue > > ( ) ;
27+ if ( inputs . Count == 0 )
28+ return Array . Empty < KeyValuePair < TKey , IList < TValue > > > ( ) ;
2829
29- for ( int i = 0 ; i < inputs . Count ; ++ i )
30+ Dictionary < TKey , IList < TValue > > buckets = null ;
31+ TKey firstBucketKey = keySelector ( inputs [ 0 ] ) ;
32+ for ( int i = 1 ; i < inputs . Count ; ++ i )
3033 {
31- var input = inputs [ i ] ;
32- var keyValue = keySelector ( input ) ;
33- if ( ! retVal . TryGetValue ( keyValue , out var eventsInBucket ) )
34+ TKey keyValue = keySelector ( inputs [ i ] ) ;
35+ if ( buckets is null )
3436 {
35- eventsInBucket = new List < TValue > ( inputs . Count - i ) ;
36- retVal . Add ( keyValue , eventsInBucket ) ;
37+ if ( ! firstBucketKey . Equals ( keyValue ) )
38+ {
39+ // Multiple buckets needed, allocate full dictionary
40+ buckets = CreateBucketDictionaryWithValue ( inputs , i , firstBucketKey , keyValue ) ;
41+ }
3742 }
43+ else
44+ {
45+ if ( ! buckets . TryGetValue ( keyValue , out var eventsInBucket ) )
46+ {
47+ eventsInBucket = new List < TValue > ( ) ;
48+ buckets . Add ( keyValue , eventsInBucket ) ;
49+ }
50+ eventsInBucket . Add ( inputs [ i ] ) ;
51+ }
52+ }
3853
39- eventsInBucket . Add ( input ) ;
54+ if ( buckets is null )
55+ {
56+ // All inputs belong to the same bucket
57+ return new [ ] { new KeyValuePair < TKey , IList < TValue > > ( firstBucketKey , inputs ) } ;
58+ }
59+ else
60+ {
61+ return buckets ;
62+ }
63+ }
64+
65+ private static Dictionary < TKey , IList < TValue > > CreateBucketDictionaryWithValue < TValue , TKey > ( IList < TValue > inputs , int currentIndex , TKey firstBucketKey , TKey nextBucketKey )
66+ {
67+ var buckets = new Dictionary < TKey , IList < TValue > > ( ) ;
68+ var firstBucket = new List < TValue > ( currentIndex ) ;
69+ for ( int i = 0 ; i < currentIndex ; i ++ )
70+ {
71+ firstBucket . Add ( inputs [ i ] ) ;
4072 }
73+ buckets [ firstBucketKey ] = firstBucket ;
4174
42- return retVal ;
75+ var nextBucket = new List < TValue > { inputs [ currentIndex ] } ;
76+ buckets [ nextBucketKey ] = nextBucket ;
77+ return buckets ;
4378 }
4479 }
4580}
0 commit comments