434 lines
12 KiB
C#
434 lines
12 KiB
C#
|
using NUnit.Framework;
|
||
|
using Unity.Burst;
|
||
|
using Unity.Collections;
|
||
|
using Unity.Collections.Tests;
|
||
|
using Unity.Collections.LowLevel.Unsafe;
|
||
|
using Unity.Jobs;
|
||
|
using Unity.Mathematics;
|
||
|
using Random = Unity.Mathematics.Random;
|
||
|
|
||
|
[TestFixture]
|
||
|
[BurstCompile]
|
||
|
internal class xxHash3Tests : CollectionsTestCommonBase
|
||
|
{
|
||
|
private unsafe void* SanityBuffer;
|
||
|
private unsafe void* DestinationBuffer;
|
||
|
|
||
|
private const int SANITY_BUFFER_SIZE = 2367;
|
||
|
|
||
|
[SetUp]
|
||
|
public unsafe override void Setup()
|
||
|
{
|
||
|
base.Setup();
|
||
|
|
||
|
unchecked
|
||
|
{
|
||
|
uint prime = 2654435761U;
|
||
|
ulong prime64 = 11400714785074694797UL;
|
||
|
ulong byteGen = prime;
|
||
|
|
||
|
SanityBuffer = Memory.Unmanaged.Allocate(SANITY_BUFFER_SIZE, 64, Allocator.Persistent);
|
||
|
byte* buffer = (byte*)SanityBuffer;
|
||
|
|
||
|
DestinationBuffer = Memory.Unmanaged.Allocate(SANITY_BUFFER_SIZE, 64, Allocator.Persistent);
|
||
|
|
||
|
int i;
|
||
|
for (i=0; i<SANITY_BUFFER_SIZE; i++) {
|
||
|
buffer[i] = (byte)(byteGen>>56);
|
||
|
byteGen *= prime64;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[TearDown]
|
||
|
public unsafe override void TearDown()
|
||
|
{
|
||
|
Memory.Unmanaged.Free(SanityBuffer, Allocator.Persistent);
|
||
|
Memory.Unmanaged.Free(DestinationBuffer, Allocator.Persistent);
|
||
|
base.TearDown();
|
||
|
}
|
||
|
|
||
|
[BurstCompile(CompileSynchronously = true)]
|
||
|
struct xxHash3Hash64SanityCheckJob : IJob
|
||
|
{
|
||
|
[NativeDisableUnsafePtrRestriction]
|
||
|
public unsafe void* SanityBuffer;
|
||
|
[NativeDisableUnsafePtrRestriction]
|
||
|
public unsafe void* DestinationBuffer;
|
||
|
|
||
|
public long Length;
|
||
|
public ulong Seed;
|
||
|
|
||
|
public NativeArray<uint2> Result;
|
||
|
|
||
|
public unsafe void Execute()
|
||
|
{
|
||
|
var resultIndex = 1;
|
||
|
// Compute Hash from buffer
|
||
|
Result[resultIndex++] = xxHash3.Hash64(SanityBuffer, Length, Seed);
|
||
|
|
||
|
// Hash & copy and Streaming API is currently not supported with Hash64
|
||
|
|
||
|
// // Compute/Copy (TODO API still not developed)
|
||
|
// if (DestinationBuffer != null)
|
||
|
// {
|
||
|
// CopySingleCallHashResult = xxHash3.Hash64(SanityBuffer, DestinationBuffer, Length, Seed);
|
||
|
// }
|
||
|
|
||
|
// Streaming API Test
|
||
|
{
|
||
|
var state = new xxHash3.StreamingState(true, Seed);
|
||
|
state.Update(SanityBuffer, (int)Length);
|
||
|
Result[resultIndex++] = state.DigestHash64();
|
||
|
}
|
||
|
|
||
|
// 2 updates
|
||
|
if (Length > 3)
|
||
|
{
|
||
|
var state = new xxHash3.StreamingState(true, Seed);
|
||
|
{
|
||
|
state.Update(SanityBuffer, 3);
|
||
|
state.Update((byte*)SanityBuffer+3, (int)Length-3);
|
||
|
Result[resultIndex++] = state.DigestHash64();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// byte per byte update
|
||
|
if (Length > 0) {
|
||
|
var state = new xxHash3.StreamingState(true, Seed);
|
||
|
{
|
||
|
var bBuffer = (byte*) SanityBuffer;
|
||
|
for (int i = 0; i < Length; i++)
|
||
|
{
|
||
|
state.Update(bBuffer + i, 1);
|
||
|
}
|
||
|
Result[resultIndex++] = state.DigestHash64();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Result[0] = new uint2(resultIndex - 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const ulong Prime = 2654435761U;
|
||
|
const ulong Prime64 = 11400714785074694797UL;
|
||
|
|
||
|
private unsafe void TestHash64(long length, ulong seed, ulong result, ulong resultWithSeed)
|
||
|
{
|
||
|
var job = new xxHash3Hash64SanityCheckJob
|
||
|
{
|
||
|
SanityBuffer = SanityBuffer,
|
||
|
DestinationBuffer = DestinationBuffer,
|
||
|
Result = CollectionHelper.CreateNativeArray<uint2>(10, CommonRwdAllocator.Handle),
|
||
|
Seed = 0,
|
||
|
Length = length
|
||
|
};
|
||
|
|
||
|
var b = xxHash3.ToUint2(result);
|
||
|
job.Schedule().Complete();
|
||
|
var resultCount = job.Result[0].x;
|
||
|
for (int i = 0; i < resultCount; i++)
|
||
|
{
|
||
|
var a = job.Result[i+1];
|
||
|
Assert.That(a, Is.EqualTo(b), $"Failed on entry {i}");
|
||
|
}
|
||
|
|
||
|
job.Seed = seed;
|
||
|
job.Schedule().Complete();
|
||
|
|
||
|
b = xxHash3.ToUint2(resultWithSeed);
|
||
|
resultCount = job.Result[0].x;
|
||
|
for (int i = 0; i < resultCount; i++)
|
||
|
{
|
||
|
Assert.That(job.Result[i+1], Is.EqualTo(b), $"Failed on entry {i}");
|
||
|
}
|
||
|
|
||
|
job.Result.Dispose();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0000()
|
||
|
{
|
||
|
TestHash64(0, Prime64, 0x2D06800538D394C2UL, 0xA8A6B918B2F0364AUL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0001()
|
||
|
{
|
||
|
TestHash64(1, Prime64, 0xC44BDFF4074EECDBUL, 0x032BE332DD766EF8UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0006()
|
||
|
{
|
||
|
TestHash64(6, Prime64, 0x27B56A84CD2D7325UL, 0x84589C116AB59AB9UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0012()
|
||
|
{
|
||
|
TestHash64(12, Prime64, 0xA713DAF0DFBB77E7UL, 0xE7303E1B2336DE0EUL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0024()
|
||
|
{
|
||
|
TestHash64(24, Prime64, 0xA3FE70BF9D3510EBUL, 0x850E80FC35BDD690UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0048()
|
||
|
{
|
||
|
TestHash64(48, Prime64, 0x397DA259ECBA1F11UL, 0xADC2CBAA44ACC616UL);
|
||
|
}
|
||
|
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0080()
|
||
|
{
|
||
|
TestHash64(80, Prime64, 0xBCDEFBBB2C47C90AUL, 0xC6DD0CB699532E73UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0195()
|
||
|
{
|
||
|
TestHash64(195, Prime64, 0xCD94217EE362EC3AUL, 0xBA68003D370CB3D9UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0403()
|
||
|
{
|
||
|
TestHash64(403, Prime64, 0xCDEB804D65C6DEA4UL, 0x6259F6ECFD6443FDUL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length0512()
|
||
|
{
|
||
|
TestHash64(512, Prime64, 0x617E49599013CB6BUL, 0x3CE457DE14C27708UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length2048()
|
||
|
{
|
||
|
TestHash64(2048, Prime64, 0xDD59E2C3A5F038E0UL, 0x66F81670669ABABCUL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length2240()
|
||
|
{
|
||
|
TestHash64(2240, Prime64, 0x6E73A90539CF2948UL, 0x757BA8487D1B5247UL);
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_64_Length2243()
|
||
|
{
|
||
|
TestHash64(2367, Prime64, 0xCB37AEB9E5D361EDUL, 0xD2DB3415B942B42AUL);
|
||
|
}
|
||
|
|
||
|
[BurstCompile(CompileSynchronously = true)]
|
||
|
struct xxHash3Hash128SanityCheckJob : IJob
|
||
|
{
|
||
|
[NativeDisableUnsafePtrRestriction]
|
||
|
public unsafe void* SanityBuffer;
|
||
|
[NativeDisableUnsafePtrRestriction]
|
||
|
public unsafe void* DestinationBuffer;
|
||
|
|
||
|
public long Length;
|
||
|
public ulong Seed;
|
||
|
|
||
|
public NativeArray<uint4> Result;
|
||
|
|
||
|
public unsafe void Execute()
|
||
|
{
|
||
|
var resultIndex = 1;
|
||
|
// Compute Hash from buffer
|
||
|
Result[resultIndex++] = xxHash3.Hash128(SanityBuffer, Length, Seed);
|
||
|
|
||
|
// Compute/Copy
|
||
|
if (DestinationBuffer != null)
|
||
|
{
|
||
|
Result[resultIndex++] = xxHash3.Hash128(SanityBuffer, DestinationBuffer, Length, Seed);
|
||
|
}
|
||
|
|
||
|
// Streaming API Test
|
||
|
{
|
||
|
var state = new xxHash3.StreamingState(false, Seed);
|
||
|
state.Update(SanityBuffer, (int)Length);
|
||
|
Result[resultIndex++] = state.DigestHash128();
|
||
|
}
|
||
|
|
||
|
// 2 updates
|
||
|
if (Length > 3)
|
||
|
{
|
||
|
var state = new xxHash3.StreamingState(false, Seed);
|
||
|
{
|
||
|
state.Update(SanityBuffer, 3);
|
||
|
state.Update((byte*)SanityBuffer+3, (int)Length-3);
|
||
|
Result[resultIndex++] = state.DigestHash128();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// byte per byte update
|
||
|
if (Length > 0) {
|
||
|
var state = new xxHash3.StreamingState(false, Seed);
|
||
|
{
|
||
|
var bBuffer = (byte*) SanityBuffer;
|
||
|
for (int i = 0; i < Length; i++)
|
||
|
{
|
||
|
state.Update(bBuffer + i, 1);
|
||
|
}
|
||
|
Result[resultIndex++] = state.DigestHash128();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Result[0] = new uint4(resultIndex - 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private unsafe void TestHash128(long length, ulong seed, uint4 result, uint4 resultWithSeed)
|
||
|
{
|
||
|
var job = new xxHash3Hash128SanityCheckJob
|
||
|
{
|
||
|
SanityBuffer = SanityBuffer,
|
||
|
DestinationBuffer = DestinationBuffer,
|
||
|
Result = CollectionHelper.CreateNativeArray<uint4>(10, CommonRwdAllocator.Handle),
|
||
|
Seed = 0,
|
||
|
Length = length
|
||
|
};
|
||
|
|
||
|
job.Schedule().Complete();
|
||
|
|
||
|
var resultCount = (int)job.Result[0].x;
|
||
|
for (int i = 0; i < resultCount; i++)
|
||
|
{
|
||
|
Assert.That(job.Result[i+1], Is.EqualTo(result), $"Failed on entry {i}");
|
||
|
}
|
||
|
|
||
|
job.Seed = seed;
|
||
|
job.Schedule().Complete();
|
||
|
|
||
|
resultCount = (int)job.Result[0].x;
|
||
|
for (int i = 0; i < resultCount; i++)
|
||
|
{
|
||
|
Assert.That(job.Result[i+1], Is.EqualTo(resultWithSeed), $"Failed on entry {i}");
|
||
|
}
|
||
|
|
||
|
job.Result.Dispose();
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public unsafe void xxHash3_Hash_128_Length0000()
|
||
|
{
|
||
|
TestHash128(0, Prime,
|
||
|
xxHash3.ToUint4(0x6001C324468D497FUL, 0x99AA06D3014798D8UL),
|
||
|
xxHash3.ToUint4(0x5444F7869C671AB0UL, 0x92220AE55E14AB50UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0001()
|
||
|
{
|
||
|
TestHash128(1, Prime,
|
||
|
xxHash3.ToUint4(0xC44BDFF4074EECDBUL, 0xA6CD5E9392000F6AUL),
|
||
|
xxHash3.ToUint4(0xB53D5557E7F76F8DUL, 0x89B99554BA22467CUL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0006()
|
||
|
{
|
||
|
// Length 6
|
||
|
TestHash128(6, Prime,
|
||
|
xxHash3.ToUint4(0x3E7039BDDA43CFC6UL, 0x082AFE0B8162D12AUL),
|
||
|
xxHash3.ToUint4(0x269D8F70BE98856EUL, 0x5A865B5389ABD2B1UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0012()
|
||
|
{
|
||
|
// Length 12
|
||
|
TestHash128(12, Prime,
|
||
|
xxHash3.ToUint4(0x061A192713F69AD9UL, 0x6E3EFD8FC7802B18UL),
|
||
|
xxHash3.ToUint4(0x9BE9F9A67F3C7DFBUL, 0xD7E09D518A3405D3UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0024()
|
||
|
{
|
||
|
// Length 24
|
||
|
TestHash128(24, Prime,
|
||
|
xxHash3.ToUint4(0x1E7044D28B1B901DUL, 0x0CE966E4678D3761UL),
|
||
|
xxHash3.ToUint4(0xD7304C54EBAD40A9UL, 0x3162026714A6A243UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0048()
|
||
|
{
|
||
|
// Length 48
|
||
|
TestHash128(48, Prime,
|
||
|
xxHash3.ToUint4(0xF942219AED80F67BUL, 0xA002AC4E5478227EUL),
|
||
|
xxHash3.ToUint4(0x7BA3C3E453A1934EUL, 0x163ADDE36C072295UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0081()
|
||
|
{
|
||
|
// Length 81
|
||
|
TestHash128(81, Prime,
|
||
|
xxHash3.ToUint4(0x5E8BAFB9F95FB803UL, 0x4952F58181AB0042UL),
|
||
|
xxHash3.ToUint4(0x703FBB3D7A5F755CUL, 0x2724EC7ADC750FB6UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0222()
|
||
|
{
|
||
|
// Length 222
|
||
|
TestHash128(222, Prime,
|
||
|
xxHash3.ToUint4(0xF1AEBD597CEC6B3AUL, 0x337E09641B948717UL),
|
||
|
xxHash3.ToUint4(0xAE995BB8AF917A8DUL, 0x91820016621E97F1UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0403()
|
||
|
{
|
||
|
// Length 403
|
||
|
TestHash128(403, Prime64,
|
||
|
xxHash3.ToUint4(0xCDEB804D65C6DEA4UL, 0x1B6DE21E332DD73DUL),
|
||
|
xxHash3.ToUint4(0x6259F6ECFD6443FDUL, 0xBED311971E0BE8F2UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length0512()
|
||
|
{
|
||
|
// Length 512
|
||
|
TestHash128(512, Prime64,
|
||
|
xxHash3.ToUint4(0x617E49599013CB6BUL, 0x18D2D110DCC9BCA1UL),
|
||
|
xxHash3.ToUint4(0x3CE457DE14C27708UL, 0x925D06B8EC5B8040UL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length2048()
|
||
|
{
|
||
|
// Length 2048
|
||
|
TestHash128(2048, Prime,
|
||
|
xxHash3.ToUint4(0xDD59E2C3A5F038E0UL, 0xF736557FD47073A5UL),
|
||
|
xxHash3.ToUint4(0x230D43F30206260BUL, 0x7FB03F7E7186C3EAUL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length2240()
|
||
|
{
|
||
|
// Length 2240
|
||
|
TestHash128(2240, Prime,
|
||
|
xxHash3.ToUint4(0x6E73A90539CF2948UL, 0xCCB134FBFA7CE49DUL),
|
||
|
xxHash3.ToUint4(0xED385111126FBA6FUL, 0x50A1FE17B338995FUL));
|
||
|
}
|
||
|
|
||
|
[Test]
|
||
|
public void xxHash3_Hash_128_Length2367()
|
||
|
{
|
||
|
// Length 2367
|
||
|
TestHash128(2367, Prime,
|
||
|
xxHash3.ToUint4(0xCB37AEB9E5D361EDUL, 0xE89C0F6FF369B427UL),
|
||
|
xxHash3.ToUint4(0x6F5360AE69C2F406UL, 0xD23AAE4B76C31ECBUL));
|
||
|
}
|
||
|
}
|