@@ -9,15 +9,22 @@ internal sealed class BitSetStructure<TKey, TValue>(NumericKeyProperties<TKey> p
99{
1010 public BitSetContext < TKey , TValue > Create ( ReadOnlyMemory < TKey > keys , ReadOnlyMemory < TValue > values )
1111 {
12- int range = ( int ) props . Range + 1 ;
13- ulong [ ] bitset = new ulong [ ( range + 63 ) / 64 ] ;
14- TValue [ ] ? denseValues = values . IsEmpty ? null : new TValue [ range ] ;
12+ if ( keyType is KeyType . Single or KeyType . Double )
13+ throw new InvalidOperationException ( "Floating point values are not supported for BitSets" ) ;
14+
1515 ReadOnlySpan < TKey > keySpan = keys . Span ;
1616 ReadOnlySpan < TValue > valueSpan = values . Span ;
1717
18+ int range = ( int ) ( props . Range + 1 ) ;
19+ ulong [ ] bitset = new ulong [ ( range + 63 ) / 64 ] ;
20+ TValue [ ] ? denseValues = values . IsEmpty ? null : new TValue [ range ] ;
21+
22+ Func < TKey , long > func = GetLongConverter ( keyType ) ;
23+ long minKey = func ( props . MinKeyValue ) ;
24+
1825 for ( int i = 0 ; i < keySpan . Length ; i ++ )
1926 {
20- ulong offset = GetOffset ( keyType , keySpan [ i ] , props . MinKeyValue ) ;
27+ ulong offset = ( ulong ) ( func ( keySpan [ i ] ) - minKey ) ;
2128 int word = ( int ) ( offset >> 6 ) ;
2229 bitset [ word ] |= 1UL << ( int ) ( offset & 63 ) ;
2330
@@ -28,17 +35,17 @@ public BitSetContext<TKey, TValue> Create(ReadOnlyMemory<TKey> keys, ReadOnlyMem
2835 return new BitSetContext < TKey , TValue > ( bitset , denseValues ) ;
2936 }
3037
31- private static ulong GetOffset ( KeyType keyType , TKey key , TKey min ) => keyType switch
38+ private static Func < TKey , long > GetLongConverter ( KeyType keyType ) => keyType switch
3239 {
33- KeyType . Char => ( char ) ( object ) key - ( uint ) ( char ) ( object ) min ,
34- KeyType . SByte => ( ulong ) ( ( long ) ( sbyte ) ( object ) key - ( sbyte ) ( object ) min ) ,
35- KeyType . Byte => ( ulong ) ( ( byte ) ( object ) key - ( byte ) ( object ) min ) ,
36- KeyType . Int16 => ( ulong ) ( ( long ) ( short ) ( object ) key - ( short ) ( object ) min ) ,
37- KeyType . UInt16 => ( ulong ) ( ( ushort ) ( object ) key - ( ushort ) ( object ) min ) ,
38- KeyType . Int32 => ( ulong ) ( ( long ) ( int ) ( object ) key - ( int ) ( object ) min ) ,
39- KeyType . UInt32 => ( uint ) ( object ) key - ( uint ) ( object ) min ,
40- KeyType . Int64 => ( ulong ) ( ( long ) ( object ) key - ( long ) ( object ) min ) ,
41- KeyType . UInt64 => ( ulong ) ( object ) key - ( ulong ) ( object ) min ,
40+ KeyType . SByte => static key => ( sbyte ) ( object ) key ,
41+ KeyType . Int16 => static key => ( short ) ( object ) key ,
42+ KeyType . Int32 => static key => ( int ) ( object ) key ,
43+ KeyType . Int64 => static key => ( long ) ( object ) key ,
44+ KeyType . Byte => static key => ( byte ) ( object ) key ,
45+ KeyType . UInt16 => static key => ( ushort ) ( object ) key ,
46+ KeyType . UInt32 => static key => ( uint ) ( object ) key ,
47+ KeyType . UInt64 => static key => ( long ) ( object ) key ,
48+ KeyType . Char => static key => ( ushort ) ( object ) key ,
4249 _ => throw new InvalidOperationException ( $ "Unsupported key type: { keyType } ")
4350 } ;
4451}
0 commit comments