YooAsset/Assets/YooAsset/Runtime/xxHash/xxHash64.XXH64.cs

107 lines
3.3 KiB
C#

// ReSharper disable InconsistentNaming
namespace Standart.Hash.xxHash
{
using System.Runtime.CompilerServices;
public static partial class xxHash64
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe ulong XXH64(byte* input, int len, ulong seed)
{
ulong h64;
if (len >= 32)
{
byte* end = input + len;
byte* limit = end - 31;
ulong v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
ulong v2 = seed + XXH_PRIME64_2;
ulong v3 = seed + 0;
ulong v4 = seed - XXH_PRIME64_1;
do
{
v1 = XXH64_round(v1, *(ulong*) input); input += 8;
v2 = XXH64_round(v2, *(ulong*) input); input += 8;
v3 = XXH64_round(v3, *(ulong*) input); input += 8;
v4 = XXH64_round(v4, *(ulong*) input); input += 8;
} while (input < limit);
h64 = XXH_rotl64(v1, 1) +
XXH_rotl64(v2, 7) +
XXH_rotl64(v3, 12) +
XXH_rotl64(v4, 18);
h64 = XXH64_mergeRound(h64, v1);
h64 = XXH64_mergeRound(h64, v2);
h64 = XXH64_mergeRound(h64, v3);
h64 = XXH64_mergeRound(h64, v4);
}
else
{
h64 = seed + XXH_PRIME64_5;
}
h64 += (ulong)len;
return XXH64_finalize(h64, input, len);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong XXH64_round(ulong acc, ulong input)
{
acc += input * XXH_PRIME64_2;
acc = XXH_rotl64(acc, 31);
acc *= XXH_PRIME64_1;
return acc;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong XXH64_mergeRound(ulong acc, ulong val)
{
val = XXH64_round(0, val);
acc ^= val;
acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
return acc;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ulong XXH64_avalanche(ulong hash)
{
hash ^= hash >> 33;
hash *= XXH_PRIME64_2;
hash ^= hash >> 29;
hash *= XXH_PRIME64_3;
hash ^= hash >> 32;
return hash;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe ulong XXH64_finalize(ulong hash, byte* ptr, int len)
{
len &= 31;
while (len >= 8) {
ulong k1 = XXH64_round(0, *(ulong*)ptr);
ptr += 8;
hash ^= k1;
hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
len -= 8;
}
if (len >= 4) {
hash ^= *(uint*)ptr * XXH_PRIME64_1;
ptr += 4;
hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
len -= 4;
}
while (len > 0) {
hash ^= (*ptr++) * XXH_PRIME64_5;
hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1;
--len;
}
return XXH64_avalanche(hash);
}
}
}