Hashing
using System.Buffers;
using System.Numerics;
using System.Runtime.InteropServices;
namespace System.Collections.Frozen
{
internal static class Hashing
{
public unsafe static int GetHashCodeOrdinal(ReadOnlySpan<char> s)
{
int num = s.Length;
fixed (char* ptr = &MemoryMarshal.GetReference(s)) {
switch (num) {
case 0:
return 757602046;
case 1: {
uint num3 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ *ptr;
return (int)(352654597 + num3 * 1566083941);
}
case 2: {
uint num3 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ *ptr;
num3 = ((BitOperations.RotateLeft(num3, 5) + num3) ^ ptr[1]);
return (int)(352654597 + num3 * 1566083941);
}
case 3: {
uint num3 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ *ptr;
num3 = ((BitOperations.RotateLeft(num3, 5) + num3) ^ ptr[1]);
num3 = ((BitOperations.RotateLeft(num3, 5) + num3) ^ ptr[2]);
return (int)(352654597 + num3 * 1566083941);
}
case 4: {
uint num2 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ *(uint*)ptr;
uint num3 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ *(uint*)(ptr + 2);
return (int)(num2 + num3 * 1566083941);
}
default: {
uint num2 = 352654597;
uint num3 = num2;
uint* ptr2 = (uint*)ptr;
while (num >= 4) {
num2 = ((BitOperations.RotateLeft(num2, 5) + num2) ^ *ptr2);
num3 = ((BitOperations.RotateLeft(num3, 5) + num3) ^ ptr2[1]);
ptr2 += 2;
num -= 4;
}
char* ptr3 = (char*)ptr2;
while (num-- > 0) {
uint num5 = BitOperations.RotateLeft(num3, 5) + num3;
char* intPtr = ptr3;
ptr3 = intPtr + 1;
num3 = (num5 ^ *intPtr);
}
return (int)(num2 + num3 * 1566083941);
}
}
}
}
public unsafe static int GetHashCodeOrdinalIgnoreCaseAscii(ReadOnlySpan<char> s)
{
int num = s.Length;
fixed (char* ptr = &MemoryMarshal.GetReference(s)) {
switch (num) {
case 0:
return 757602046;
case 1: {
uint num3 = (uint)((int)(BitOperations.RotateLeft(352654597, 5) + 352654597) ^ (*ptr | 32));
return (int)(352654597 + num3 * 1566083941);
}
case 2: {
uint num3 = (uint)((int)(BitOperations.RotateLeft(352654597, 5) + 352654597) ^ (*ptr | 32));
num3 = (uint)((int)(BitOperations.RotateLeft(num3, 5) + num3) ^ (ptr[1] | 32));
return (int)(352654597 + num3 * 1566083941);
}
case 3: {
uint num3 = (uint)((int)(BitOperations.RotateLeft(352654597, 5) + 352654597) ^ (*ptr | 32));
num3 = (uint)((int)(BitOperations.RotateLeft(num3, 5) + num3) ^ (ptr[1] | 32));
num3 = (uint)((int)(BitOperations.RotateLeft(num3, 5) + num3) ^ (ptr[2] | 32));
return (int)(352654597 + num3 * 1566083941);
}
case 4: {
uint num2 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ (*(uint*)ptr | 2097184);
uint num3 = (BitOperations.RotateLeft(352654597, 5) + 352654597) ^ (*(uint*)(ptr + 2) | 2097184);
return (int)(num2 + num3 * 1566083941);
}
default: {
uint num2 = 352654597;
uint num3 = num2;
uint* ptr2 = (uint*)ptr;
while (num >= 4) {
num2 = ((BitOperations.RotateLeft(num2, 5) + num2) ^ (*ptr2 | 2097184));
num3 = ((BitOperations.RotateLeft(num3, 5) + num3) ^ (ptr2[1] | 2097184));
ptr2 += 2;
num -= 4;
}
char* ptr3 = (char*)ptr2;
while (num-- > 0) {
num3 = (uint)((int)(BitOperations.RotateLeft(num3, 5) + num3) ^ (*ptr3 | 2097184));
ptr3++;
}
return (int)(num2 + num3 * 1566083941);
}
}
}
}
public unsafe static int GetHashCodeOrdinalIgnoreCase(ReadOnlySpan<char> s)
{
int length = s.Length;
char[] array = null;
Span<char> span2;
if (length <= 256) {
Span<char> span = new Span<char>(stackalloc byte[512], 256);
span2 = span;
} else
span2 = (array = ArrayPool<char>.Shared.Rent(length));
Span<char> destination = span2;
length = s.ToUpperInvariant(destination);
int hashCodeOrdinal = GetHashCodeOrdinal(destination.Slice(0, length));
if (array != null)
ArrayPool<char>.Shared.Return(array, false);
return hashCodeOrdinal;
}
}
}