@@ -56,36 +56,33 @@ public bool Equals(ReadOnlySpan<byte> propertyName, ulong key)
56
56
57
57
/// <summary>
58
58
/// Get a key from the property name.
59
- /// The key consists of the first 7 bytes of the property name and then the length.
59
+ /// The key consists of the first 7 bytes of the property name and then the least significant bits of the length.
60
60
/// </summary>
61
61
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
62
62
public static ulong GetKey ( ReadOnlySpan < byte > name )
63
63
{
64
- ulong key ;
65
-
66
64
ref byte reference = ref MemoryMarshal . GetReference ( name ) ;
67
65
int length = name . Length ;
66
+ ulong key = ( ulong ) ( byte ) length << 56 ;
68
67
69
- if ( length > 7 )
68
+ switch ( length )
70
69
{
71
- key = Unsafe . ReadUnaligned < ulong > ( ref reference ) & 0x00ffffffffffffffL ;
72
- key |= ( ulong ) Math . Min ( length , 0xff ) << 56 ;
70
+ case 0 : goto ComputedKey ;
71
+ case 1 : goto OddLength ;
72
+ case 2 : key |= Unsafe . ReadUnaligned < ushort > ( ref reference ) ; goto ComputedKey ;
73
+ case 3 : key |= Unsafe . ReadUnaligned < ushort > ( ref reference ) ; goto OddLength ;
74
+ case 4 : key |= Unsafe . ReadUnaligned < uint > ( ref reference ) ; goto ComputedKey ;
75
+ case 5 : key |= Unsafe . ReadUnaligned < uint > ( ref reference ) ; goto OddLength ;
76
+ case 6 : key |= Unsafe . ReadUnaligned < uint > ( ref reference ) | ( ulong ) Unsafe . ReadUnaligned < ushort > ( ref Unsafe . Add ( ref reference , 4 ) ) << 32 ; goto ComputedKey ;
77
+ case 7 : key |= Unsafe . ReadUnaligned < uint > ( ref reference ) | ( ulong ) Unsafe . ReadUnaligned < ushort > ( ref Unsafe . Add ( ref reference , 4 ) ) << 32 ; goto OddLength ;
78
+ default : key |= ( Unsafe . ReadUnaligned < ulong > ( ref reference ) & 0x00ffffffffffffffL ) ; goto ComputedKey ;
73
79
}
74
- else
75
- {
76
- key =
77
- length > 5 ? Unsafe . ReadUnaligned < uint > ( ref reference ) | ( ulong ) Unsafe . ReadUnaligned < ushort > ( ref Unsafe . Add ( ref reference , 4 ) ) << 32 :
78
- length > 3 ? Unsafe . ReadUnaligned < uint > ( ref reference ) :
79
- length > 1 ? Unsafe . ReadUnaligned < ushort > ( ref reference ) : 0UL ;
80
- key |= ( ulong ) length << 56 ;
81
80
82
- if ( ( length & 1 ) != 0 )
83
- {
84
- int offset = length - 1 ;
85
- key |= ( ulong ) Unsafe . Add ( ref reference , offset ) << ( offset * 8 ) ;
86
- }
87
- }
81
+ OddLength :
82
+ int offset = length - 1 ;
83
+ key |= ( ulong ) Unsafe . Add ( ref reference , offset ) << ( offset * 8 ) ;
88
84
85
+ ComputedKey :
89
86
#if DEBUG
90
87
// Verify key contains the embedded bytes as expected.
91
88
// Note: the expected properties do not hold true on big-endian platforms
@@ -102,8 +99,7 @@ public static ulong GetKey(ReadOnlySpan<byte> name)
102
99
( name . Length < 6 || name [ 5 ] == ( ( key & ( ( ulong ) 0xFF << BitsInByte * 5 ) ) >> BitsInByte * 5 ) ) &&
103
100
( name . Length < 7 || name [ 6 ] == ( ( key & ( ( ulong ) 0xFF << BitsInByte * 6 ) ) >> BitsInByte * 6 ) ) &&
104
101
// Verify embedded length.
105
- ( name . Length >= 0xFF || ( key & ( ( ulong ) 0xFF << BitsInByte * 7 ) ) >> BitsInByte * 7 == ( ulong ) name . Length ) &&
106
- ( name . Length < 0xFF || ( key & ( ( ulong ) 0xFF << BitsInByte * 7 ) ) >> BitsInByte * 7 == 0xFF ) ,
102
+ ( key & ( ( ulong ) 0xFF << BitsInByte * 7 ) ) >> BitsInByte * 7 == ( byte ) name . Length ,
107
103
"Embedded bytes not as expected" ) ;
108
104
}
109
105
#endif
0 commit comments