| 648 | } |
| 649 | |
| 650 | private static ulong ComputeHeaderHashBits(ReadOnlySpan<byte> body, ulong headerLowBits) |
| 651 | { |
| 652 | int hashInputLength = body.Length + sizeof(ushort); |
| 653 | byte[]? rented = null; |
| 654 | Span<byte> hashInput = hashInputLength <= 1024 |
| 655 | ? stackalloc byte[hashInputLength] |
| 656 | : (rented = ArrayPool<byte>.Shared.Rent(hashInputLength)).AsSpan(0, hashInputLength); |
| 657 | try |
| 658 | { |
| 659 | body.CopyTo(hashInput); |
| 660 | hashInput[body.Length] = unchecked((byte)headerLowBits); |
| 661 | hashInput[body.Length + 1] = unchecked((byte)(headerLowBits >> 8)); |
| 662 | (ulong bodyHash, _) = MurmurHash3.X64_128(hashInput, TypeMetaConstants.TypeMetaHashSeed); |
| 663 | ulong shifted = bodyHash << TypeMetaConstants.TypeMetaHashShift; |
| 664 | long signed = unchecked((long)shifted); |
| 665 | long absSigned = signed == long.MinValue ? signed : Math.Abs(signed); |
| 666 | return unchecked((ulong)absSigned) & TypeMetaConstants.TypeMetaHashMask; |
| 667 | } |
| 668 | finally |
| 669 | { |
| 670 | if (rented is not null) |
| 671 | { |
| 672 | ArrayPool<byte>.Shared.Return(rented); |
| 673 | } |
| 674 | } |
| 675 | } |
| 676 | |
| 677 | private static void ValidateParsedTypeMetaHash(ulong header, ReadOnlySpan<byte> body) |
| 678 | { |