Skip to content

Commit 3ac2ee7

Browse files
Incorporate suggestions to key generation algorithm.
1 parent 1224d11 commit 3ac2ee7

File tree

1 file changed

+17
-21
lines changed
  • src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata

1 file changed

+17
-21
lines changed

src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/PropertyRef.cs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,36 +56,33 @@ public bool Equals(ReadOnlySpan<byte> propertyName, ulong key)
5656

5757
/// <summary>
5858
/// 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.
6060
/// </summary>
6161
[MethodImpl(MethodImplOptions.AggressiveInlining)]
6262
public static ulong GetKey(ReadOnlySpan<byte> name)
6363
{
64-
ulong key;
65-
6664
ref byte reference = ref MemoryMarshal.GetReference(name);
6765
int length = name.Length;
66+
ulong key = (ulong)(byte)length << 56;
6867

69-
if (length > 7)
68+
switch (length)
7069
{
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;
7379
}
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;
8180

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);
8884

85+
ComputedKey:
8986
#if DEBUG
9087
// Verify key contains the embedded bytes as expected.
9188
// Note: the expected properties do not hold true on big-endian platforms
@@ -102,8 +99,7 @@ public static ulong GetKey(ReadOnlySpan<byte> name)
10299
(name.Length < 6 || name[5] == ((key & ((ulong)0xFF << BitsInByte * 5)) >> BitsInByte * 5)) &&
103100
(name.Length < 7 || name[6] == ((key & ((ulong)0xFF << BitsInByte * 6)) >> BitsInByte * 6)) &&
104101
// 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,
107103
"Embedded bytes not as expected");
108104
}
109105
#endif

0 commit comments

Comments
 (0)