Browse Source

xxhash: Add XXH3_128 + test vectors.

Jeroen van Rijn 4 years ago
parent
commit
eaefbc43cb

+ 21 - 3
core/hash/xxhash/common.odin

@@ -11,7 +11,9 @@ package xxhash
 
 import "core:intrinsics"
 import "core:runtime"
-mem_copy :: runtime.mem_copy
+import "core:sys/llvm"
+mem_copy  :: runtime.mem_copy
+byte_swap :: intrinsics.byte_swap
 
 /*
 	Version definition
@@ -43,6 +45,22 @@ Error :: enum {
 	Error,
 }
 
+XXH_DISABLE_PREFETCH :: #config(XXH_DISABLE_PREFETCH, false)
+
+when !XXH_DISABLE_PREFETCH {
+	prefetch_address :: #force_inline proc(address: rawptr) {
+		llvm.prefetch(address, .Read, .High, .Data)
+	}
+	prefetch_offset  :: #force_inline proc(address: rawptr, auto_cast offset: uintptr) {
+		ptr := rawptr(uintptr(address) + offset)
+		prefetch_address(ptr)
+	}
+} else {
+	prefetch_address :: #force_inline proc(address: rawptr) {}
+	prefetch_offset  :: #force_inline proc(address: rawptr, auto_cast offset: uintptr) {}
+}
+prefetch :: proc { prefetch_address, prefetch_offset, }
+
 @(optimization_mode="speed")
 XXH_rotl32 :: #force_inline proc(x, r: u32) -> (res: u32) {
 	return ((x << r) | (x >> (32 - r)))
@@ -54,7 +72,7 @@ XXH_rotl64 :: #force_inline proc(x, r: u64) -> (res: u64) {
 }
 
 @(optimization_mode="speed")
-XXH32_read32 :: #force_inline proc(buf: []u8, alignment: Alignment) -> (res: u32) {
+XXH32_read32 :: #force_inline proc(buf: []u8, alignment := Alignment.Unaligned) -> (res: u32) {
 	if XXH_FORCE_MEMORY_ACCESS == 2 || alignment == .Aligned {
 		#no_bounds_check b := (^u32le)(&buf[0])^
 		return u32(b)
@@ -66,7 +84,7 @@ XXH32_read32 :: #force_inline proc(buf: []u8, alignment: Alignment) -> (res: u32
 }
 
 @(optimization_mode="speed")
-XXH64_read64 :: #force_inline proc(buf: []u8, alignment: Alignment) -> (res: u64) {
+XXH64_read64 :: #force_inline proc(buf: []u8, alignment := Alignment.Unaligned) -> (res: u64) {
 	if XXH_FORCE_MEMORY_ACCESS == 2 || alignment == .Aligned {
 		#no_bounds_check b := (^u64le)(&buf[0])^
 		return u64(b)

+ 914 - 0
core/hash/xxhash/xxhash_3.odin

@@ -0,0 +1,914 @@
+/*
+	An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/).
+	Copyright 2021 Jeroen van Rijn <[email protected]>.
+
+	Made available under Odin's BSD-3 license, based on the original C code.
+
+	List of contributors:
+		Jeroen van Rijn: Initial implementation.
+*/
+package xxhash
+import "core:intrinsics"
+
+/* *********************************************************************
+*  XXH3
+*  New generation hash designed for speed on small keys and vectorization
+************************************************************************
+* One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while
+* remaining a true 64-bit/128-bit hash function.
+*
+* This is done by prioritizing a subset of 64-bit operations that can be
+* emulated without too many steps on the average 32-bit machine.
+*
+* For example, these two lines seem similar, and run equally fast on 64-bit:
+*
+*   xxh_u64 x;
+*   x ^= (x >> 47); // good
+*   x ^= (x >> 13); // bad
+*
+* However, to a 32-bit machine, there is a major difference.
+*
+* x ^= (x >> 47) looks like this:
+*
+*   x.lo ^= (x.hi >> (47 - 32));
+*
+* while x ^= (x >> 13) looks like this:
+*
+*   // note: funnel shifts are not usually cheap.
+*   x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13));
+*   x.hi ^= (x.hi >> 13);
+*
+* The first one is significantly faster than the second, simply because the
+* shift is larger than 32. This means:
+*  - All the bits we need are in the upper 32 bits, so we can ignore the lower
+*    32 bits in the shift.
+*  - The shift result will always fit in the lower 32 bits, and therefore,
+*    we can ignore the upper 32 bits in the xor.
+*
+* Thanks to this optimization, XXH3 only requires these features to be efficient:
+*
+*  - Usable unaligned access
+*  - A 32-bit or 64-bit ALU
+*      - If 32-bit, a decent ADC instruction
+*  - A 32 or 64-bit multiply with a 64-bit result
+*  - For the 128-bit variant, a decent byteswap helps short inputs.
+*
+* The first two are already required by XXH32, and almost all 32-bit and 64-bit
+* platforms which can run XXH32 can run XXH3 efficiently.
+*
+* Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one
+* notable exception.
+*
+* First of all, Thumb-1 lacks support for the UMULL instruction which
+* performs the important long multiply. This means numerous __aeabi_lmul
+* calls.
+*
+* Second of all, the 8 functional registers are just not enough.
+* Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need
+* Lo registers, and this shuffling results in thousands more MOVs than A32.
+*
+* A32 and T32 don't have this limitation. They can access all 14 registers,
+* do a 32->64 multiply with UMULL, and the flexible operand allowing free
+* shifts is helpful, too.
+*
+* Therefore, we do a quick sanity check.
+*
+* If compiling Thumb-1 for a target which supports ARM instructions, we will
+* emit a warning, as it is not a "sane" platform to compile for.
+*
+* Usually, if this happens, it is because of an accident and you probably need
+* to specify -march, as you likely meant to compile for a newer architecture.
+*
+* Credit: large sections of the vectorial and asm source code paths
+*         have been contributed by @easyaspi314
+*/
+
+XXH_ACC_ALIGN :: 8                 /* scalar */
+
+/* ==========================================
+ * XXH3 default settings
+ * ========================================== */
+
+XXH3_SECRET_SIZE_MIN    :: 136
+XXH_SECRET_DEFAULT_SIZE :: max(XXH3_SECRET_SIZE_MIN, #config(XXH_SECRET_DEFAULT_SIZE, 192))
+
+XXH3_kSecret :: [?]u8{
+	0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
+	0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
+	0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
+	0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
+	0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
+	0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
+	0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
+	0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
+	0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
+	0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
+	0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
+	0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
+}
+#assert(size_of(XXH3_kSecret) == 192)
+
+
+/************************************************************************
+*  XXH3 128-bit variant
+************************************************************************/
+
+/*
+	Stored in little endian order, although the fields themselves are in native endianness.
+*/
+xxh_u128              :: u128
+XXH3_128_hash         :: u128
+XXH3_128_DEFAULT_SEED :: xxh_u64(0)
+
+XXH128_hash_t :: struct #raw_union {
+	using raw: struct {
+		low:  XXH64_hash, /*!< `value & 0xFFFFFFFFFFFFFFFF` */
+		high: XXH64_hash, /*!< `value >> 64` */
+	},
+	h: xxh_u128,
+}
+#assert(size_of(xxh_u128) == size_of(XXH128_hash_t))
+
+@(optimization_mode="speed")
+XXH_mul_32_to_64 :: #force_inline proc(x, y: xxh_u32) -> (res: xxh_u64) {
+	return u64(x) * u64(y)
+}
+
+@(optimization_mode="speed")
+XXH_mul_64_to_128 :: #force_inline proc(lhs, rhs: xxh_u64) -> (res: xxh_u128) {
+	return xxh_u128(lhs) * xxh_u128(rhs)
+}
+
+/*
+	The reason for the separate function is to prevent passing too many structs
+	around by value. This will hopefully inline the multiply, but we don't force it.
+
+	@param lhs, rhs The 64-bit integers to multiply
+	@return The low 64 bits of the product XOR'd by the high 64 bits.
+*/
+@(optimization_mode="speed")
+XXH_mul_64_to_128_fold_64 :: #force_inline proc(lhs, rhs: xxh_u64) -> (res: xxh_u64) {
+	t  := XXH128_hash_t{}
+	t.h = #force_inline XXH_mul_64_to_128(lhs, rhs)
+	return t.low ~ t.high
+}
+
+@(optimization_mode="speed")
+XXH_xorshift_64 :: #force_inline proc(v: xxh_u64, auto_cast shift: uint) -> (res: xxh_u64) {
+	return v ~ (v >> shift)
+}
+
+/*
+	This is a fast avalanche stage, suitable when input bits are already partially mixed
+*/
+@(optimization_mode="speed")
+XXH3_avalanche :: #force_inline proc(h64: xxh_u64) -> (res: xxh_u64) {
+	res = XXH_xorshift_64(h64, 37)
+	res *= 0x165667919E3779F9
+	res = XXH_xorshift_64(res, 32)
+	return
+}
+
+/*
+	This is a stronger avalanche, inspired by Pelle Evensen's rrmxmx
+	preferable when input has not been previously mixed
+*/
+@(optimization_mode="speed")
+XXH3_rrmxmx :: #force_inline proc(h64, length: xxh_u64) -> (res: xxh_u64) {
+	/* this mix is inspired by Pelle Evensen's rrmxmx */
+	res = h64
+	res ~= XXH_rotl64(res, 49) ~ XXH_rotl64(res, 24)
+	res *= 0x9FB21C651E98DF25
+	res ~= (res >> 35) + length 
+	res *= 0x9FB21C651E98DF25
+	return XXH_xorshift_64(res, 28)
+}
+
+/*
+	==========================================
+	       XXH3 128 bits (a.k.a XXH128)
+	==========================================
+	XXH3's 128-bit variant has better mixing and strength than the 64-bit variant,
+	even without counting the significantly larger output size.
+
+ 	For example, extra steps are taken to avoid the seed-dependent collisions
+	in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B).
+
+	This strength naturally comes at the cost of some speed, especially on short
+	lengths. Note that longer hashes are about as fast as the 64-bit version
+	due to it using only a slight modification of the 64-bit loop.
+
+	XXH128 is also more oriented towards 64-bit machines. It is still extremely
+	fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
+*/
+
+@(optimization_mode="speed")
+XXH3_len_1to3_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	/* A doubled version of 1to3_64b with different constants. */
+	length := len(input)
+	/*
+	 * len = 1: combinedl = { input[0], 0x01, input[0], input[0] }
+	 * len = 2: combinedl = { input[1], 0x02, input[0], input[1] }
+	 * len = 3: combinedl = { input[2], 0x03, input[0], input[1] }
+	 */
+	#no_bounds_check {
+		c1 := input[          0]
+		c2 := input[length >> 1]
+		c3 := input[length  - 1]
+		combinedl := (u32(c1) << 16) | (u32(c2) << 24) | (u32(c3) << 0) | (u32(length) << 8)
+		combinedh := XXH_rotl32(byte_swap(combinedl), 13)
+		bitflipl  := u64(XXH32_read32(secret[0:]) ~ XXH32_read32(secret[4: ])) + seed
+		bitfliph  := u64(XXH32_read32(secret[8:]) ~ XXH32_read32(secret[12:])) - seed
+		keyed_lo  := u64(combinedl) ~ bitflipl
+		keyed_hi  := u64(combinedh) ~ bitfliph
+		
+		return xxh_u128(XXH64_avalanche(keyed_lo)) | xxh_u128(XXH64_avalanche(keyed_hi)) << 64
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_len_4to8_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	length := len(input)
+	seed   := seed
+
+	seed ~= u64(byte_swap(u32(seed))) << 32
+	#no_bounds_check {
+		input_lo := u64(XXH32_read32(input[0:]))
+		input_hi := u64(XXH32_read32(input[length - 4:]))
+		input_64 := u64(input_lo) + u64(input_hi) << 32
+		bitflip  := (XXH64_read64(secret[16:]) ~ XXH64_read64(secret[24:])) + seed
+		keyed    := input_64 ~ bitflip
+
+		/* Shift len to the left to ensure it is even, this avoids even multiplies. */
+		m128 := XXH128_hash_t{
+			h = XXH_mul_64_to_128(keyed, u64(XXH_PRIME64_1) + (u64(length) << 2)),
+		}
+		m128.high += (m128.low  << 1)
+		m128.low  ~= (m128.high >> 3)
+
+		m128.low   = XXH_xorshift_64(m128.low, 35)
+		m128.low  *= 0x9FB21C651E98DF25
+		m128.low   = XXH_xorshift_64(m128.low, 28)
+		m128.high  = XXH3_avalanche(m128.high)
+
+		return m128.h
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_len_9to16_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	length := len(input)
+
+	#no_bounds_check {
+		bitflipl := (XXH64_read64(secret[32:]) ~ XXH64_read64(secret[40:])) - seed
+		bitfliph := (XXH64_read64(secret[48:]) ~ XXH64_read64(secret[56:])) + seed
+		input_lo := XXH64_read64(input[0:])
+		input_hi := XXH64_read64(input[length - 8:])
+		m128     := XXH128_hash_t{
+			h = XXH_mul_64_to_128(input_lo ~ input_hi ~ bitflipl, XXH_PRIME64_1),
+		}
+		/*
+		 * Put len in the middle of m128 to ensure that the length gets mixed to
+		 * both the low and high bits in the 128x64 multiply below.
+		 */
+		m128.low += u64(length - 1) << 54
+		input_hi ~= bitfliph
+		/*
+		 * Add the high 32 bits of input_hi to the high 32 bits of m128, then
+		 * add the long product of the low 32 bits of input_hi and XXH_XXH_PRIME32_2 to
+		 * the high 64 bits of m128.
+		 *
+		 * The best approach to this operation is different on 32-bit and 64-bit.
+		 */
+		when size_of(rawptr) == 4 { /* 32-bit */
+			/*
+			 * 32-bit optimized version, which is more readable.
+			 *
+			 * On 32-bit, it removes an ADC and delays a dependency between the two
+			 * halves of m128.high64, but it generates an extra mask on 64-bit.
+			 */
+			m128.high += (input_hi & 0xFFFFFFFF00000000) + XXH_mul_32_to_64(u32(input_hi), XXH_PRIME32_2)
+		} else {
+			/*
+			 * 64-bit optimized (albeit more confusing) version.
+			 *
+			 * Uses some properties of addition and multiplication to remove the mask:
+			 *
+			 * Let:
+			 *    a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF)
+			 *    b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000)
+			 *    c = XXH_XXH_PRIME32_2
+			 *
+			 *    a + (b * c)
+			 * Inverse Property: x + y - x == y
+			 *    a + (b * (1 + c - 1))
+			 * Distributive Property: x * (y + z) == (x * y) + (x * z)
+			 *    a + (b * 1) + (b * (c - 1))
+			 * Identity Property: x * 1 == x
+			 *    a + b + (b * (c - 1))
+			 *
+			 * Substitute a, b, and c:
+			 *    input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_XXH_PRIME32_2 - 1))
+			 *
+			 * Since input_hi.hi + input_hi.lo == input_hi, we get this:
+			 *    input_hi + ((xxh_u64)input_hi.lo * (XXH_XXH_PRIME32_2 - 1))
+			 */
+			m128.high += input_hi + XXH_mul_32_to_64(u32(input_hi), XXH_PRIME32_2 - 1)
+		}
+		/* m128 ^= XXH_swap64(m128 >> 64); */
+		m128.low ~= byte_swap(m128.high)
+		{   /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */
+			h128 := XXH128_hash_t{
+				h = XXH_mul_64_to_128(m128.low, XXH_PRIME64_2),
+			}
+			h128.high += m128.high * XXH_PRIME64_2
+			h128.low   = XXH3_avalanche(h128.low)
+			h128.high  = XXH3_avalanche(h128.high)
+			return h128.h
+		}
+	}
+}
+
+/*
+	Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
+*/
+@(optimization_mode="speed")
+XXH3_len_0to16_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	length := len(input)
+
+	switch {
+	case length  > 8: return XXH3_len_9to16_128b(input, secret, seed)
+	case length >= 4: return XXH3_len_4to8_128b (input, secret, seed)
+	case length  > 0: return XXH3_len_1to3_128b (input, secret, seed)
+	case:
+		#no_bounds_check bitflipl := XXH64_read64(secret[64:]) ~ XXH64_read64(secret[72:])
+		#no_bounds_check bitfliph := XXH64_read64(secret[80:]) ~ XXH64_read64(secret[88:])
+		return xxh_u128(XXH64_avalanche(seed ~ bitflipl)) | xxh_u128(XXH64_avalanche(seed ~ bitfliph)) << 64
+	}
+}
+
+/*
+	A bit slower than XXH3_mix16B, but handles multiply by zero better.
+*/
+@(optimization_mode="speed")
+XXH128_mix32B :: #force_inline proc(acc: xxh_u128, input_1: []u8, input_2: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	acc128 := XXH128_hash_t{
+		h = acc,
+	}
+	#no_bounds_check {
+		acc128.low  += XXH3_mix16B (input_1, secret[0:], seed)
+		acc128.low  ~= XXH64_read64(input_2[0:]) + XXH64_read64(input_2[8:])
+		acc128.high += XXH3_mix16B (input_2, secret[16:], seed)
+		acc128.high ~= XXH64_read64(input_1) + XXH64_read64(input_1[8:])
+		return acc128.h
+	}
+}
+
+
+
+
+@(optimization_mode="speed")
+XXH3_len_17to128_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	length := len(input)
+
+	acc  := XXH128_hash_t{}
+	acc.low = xxh_u64(length) * XXH_PRIME64_1
+
+	switch{
+	case length > 96:
+		#no_bounds_check acc.h = XXH128_mix32B(acc.h, input[48:], input[length - 64:], secret[96:], seed)
+		fallthrough
+	case length > 64:
+		#no_bounds_check acc.h = XXH128_mix32B(acc.h, input[32:], input[length - 48:], secret[64:], seed)
+		fallthrough
+	case length > 32:
+		#no_bounds_check acc.h = XXH128_mix32B(acc.h, input[16:], input[length - 32:], secret[32:], seed)
+		fallthrough
+	case:
+		#no_bounds_check acc.h = XXH128_mix32B(acc.h, input,      input[length - 16:], secret,      seed)
+
+		h128     := XXH128_hash_t{}
+		h128.low  = acc.low + acc.high
+		h128.high = (acc.low * XXH_PRIME64_1) + (acc.high * XXH_PRIME64_4) + ((u64(length) - seed) * XXH_PRIME64_2)
+		h128.low  = XXH3_avalanche(h128.low)
+		h128.high = u64(i64(0) - i64(XXH3_avalanche(h128.high)))
+		return h128.h
+	}
+	unreachable()
+}
+
+@(optimization_mode="speed")
+XXH3_len_129to240_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
+	length := len(input)
+
+	#no_bounds_check {
+		acc := XXH128_hash_t{}
+		acc.low = u64(length) * XXH_PRIME64_1
+
+		nbRounds := length / 32
+
+		i: int
+		#no_bounds_check for i = 0; i < 4; i += 1 {
+			acc.h = XXH128_mix32B(acc.h,
+				                  input[32 * i:],
+				                  input [32 * i + 16:],
+				                  secret[32 * i:],
+				                  seed)
+		}
+		acc.low  = XXH3_avalanche(acc.low)
+		acc.high = XXH3_avalanche(acc.high)
+
+		#no_bounds_check for i = 4; i < nbRounds; i += 1 {
+			acc.h = XXH128_mix32B(acc.h,
+				                  input[32 * i:], input[32 * i + 16:],
+				                  secret[XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)):],
+								  seed)
+		}
+		/* last bytes */
+		#no_bounds_check acc.h = XXH128_mix32B(acc.h,
+							input[length - 16:],
+							input[length - 32:],
+							secret[XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16:],
+							u64(i64(0) - i64(seed)))
+
+		#no_bounds_check {
+			h128 := XXH128_hash_t{}
+			h128.low  = acc.low + acc.high
+			h128.high = u64(
+				        u128(acc.low  * XXH_PRIME64_1) \
+			          + u128(acc.high * XXH_PRIME64_4) \
+			          + u128((u64(length) - seed) * XXH_PRIME64_2))
+			h128.low  = XXH3_avalanche(h128.low)
+			h128.high = u64(i64(0) - i64(XXH3_avalanche(h128.high)))
+			return h128.h
+		}
+	}
+	unreachable()
+}
+
+XXH3_INIT_ACC :: [XXH_ACC_NB]xxh_u64{
+	XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3,
+	XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1,
+}
+
+XXH_SECRET_MERGEACCS_START :: 11
+
+@(optimization_mode="speed")
+XXH3_hashLong_128b_internal :: #force_inline proc(
+			input: []u8,
+			secret: []u8,
+			f_acc512: XXH3_accumulate_512_f,
+			f_scramble: XXH3_scramble_accumulator_f) -> (res: XXH3_128_hash) {
+
+	acc := XXH3_INIT_ACC
+	#assert(size_of(acc) == 64)
+
+	XXH3_hashLong_internal_loop(acc[:], input, secret, f_acc512, f_scramble)
+
+	/* converge into final hash */
+	{
+		length      := len(input)
+		secret_size := len(secret)
+
+		h128 := XXH128_hash_t{}
+		h128.low  = XXH3_mergeAccs(acc[:], secret[XXH_SECRET_MERGEACCS_START:], u64(length) * XXH_PRIME64_1)
+		h128.high = XXH3_mergeAccs(acc[:], secret[secret_size - size_of(acc) - XXH_SECRET_MERGEACCS_START:],
+				~(u64(length) * XXH_PRIME64_2))
+		return h128.h
+	}
+}
+
+/*
+ * It's important for performance that XXH3_hashLong is not inlined.
+ */
+XXH3_hashLong_128b_default :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash) {
+	k_secret := XXH3_kSecret
+	return XXH3_hashLong_128b_internal(input, k_secret[:], XXH3_accumulate_512, XXH3_scramble_accumulator)
+}
+
+/*
+ * It's important for performance that XXH3_hashLong is not inlined.
+ */
+XXH3_hashLong_128b_withSecret :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash) {
+	return XXH3_hashLong_128b_internal(input, secret, XXH3_accumulate_512, XXH3_scramble_accumulator)
+}
+
+XXH3_hashLong_128b_withSeed_internal :: #force_inline proc(
+								input: []u8, seed: xxh_u64, secret: []u8,
+								f_acc512: XXH3_accumulate_512_f,
+								f_scramble: XXH3_scramble_accumulator_f,
+								f_initSec: XXH3_init_custom_secret_f) -> (res: XXH3_128_hash) {
+
+	if seed == 0 {
+		k := XXH3_kSecret
+		return XXH3_hashLong_128b_internal(input, k[:], f_acc512, f_scramble)
+	}
+
+	{
+		secret := [XXH_SECRET_DEFAULT_SIZE]u8{}
+		f_initSec(secret[:], seed)
+		return XXH3_hashLong_128b_internal(input, secret[:], f_acc512, f_scramble)
+	}
+}
+
+/*
+ * It's important for performance that XXH3_hashLong is not inlined.
+ */
+XXH3_hashLong_128b_withSeed :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash) {
+	return XXH3_hashLong_128b_withSeed_internal(input, seed, secret, XXH3_accumulate_512, XXH3_scramble_accumulator , XXH3_init_custom_secret)
+}
+
+XXH3_hashLong128_f :: #type proc(input: []u8, seed: xxh_u64, secret: []u8)  -> (res: XXH3_128_hash)
+
+XXH3_128bits_internal :: #force_inline proc(
+	input: []u8, seed: xxh_u64, secret: []u8, f_hl128: XXH3_hashLong128_f) -> (res: XXH3_128_hash) {
+
+	assert(len(secret) >= XXH3_SECRET_SIZE_MIN)
+	/*
+	 * If an action is to be taken if `secret` conditions are not respected,
+	 * it should be done here.
+	 * For now, it's a contract pre-condition.
+	 * Adding a check and a branch here would cost performance at every hash.
+	 */
+	length := len(input)
+
+	switch {
+	case length <= 16:
+		return XXH3_len_0to16_128b(input, secret, seed)
+	case length <= 128:
+		return XXH3_len_17to128_128b(input, secret, seed)
+	case length <= XXH3_MIDSIZE_MAX:
+		return XXH3_len_129to240_128b(input, secret, seed)
+	case:
+		return f_hl128(input, seed, secret)
+	}
+}
+
+/* ===   Public XXH128 API   === */
+
+XXH3_128bits :: proc(input: []u8) -> (hash: XXH3_128_hash) {
+	k := XXH3_kSecret
+	return XXH3_128bits_internal(input, XXH3_128_DEFAULT_SEED, k[:], XXH3_hashLong_128b_default)
+}
+
+
+
+/*
+	==========================================
+	Short keys
+	==========================================
+	One of the shortcomings of XXH32 and XXH64 was that their performance was
+	sub-optimal on short lengths. It used an iterative algorithm which strongly
+	favored lengths that were a multiple of 4 or 8.
+
+	Instead of iterating over individual inputs, we use a set of single shot
+	functions which piece together a range of lengths and operate in constant time.
+	Additionally, the number of multiplies has been significantly reduced. This
+	reduces latency, especially when emulating 64-bit multiplies on 32-bit.
+
+	Depending on the platform, this may or may not be faster than XXH32, but it
+	is almost guaranteed to be faster than XXH64.
+*/
+
+/*
+	At very short lengths, there isn't enough input to fully hide secrets, or use the entire secret.
+
+	There is also only a limited amount of mixing we can do before significantly impacting performance.
+
+	Therefore, we use different sections of the secret and always mix two secret samples with an XOR.
+	This should have no effect on performance on the seedless or withSeed variants because everything
+	_should_ be constant folded by modern compilers.
+
+	The XOR mixing hides individual parts of the secret and increases entropy.
+	This adds an extra layer of strength for custom secrets.
+*/
+@(optimization_mode="speed")
+XXH3_len_1to3_64b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	length := u32(len(input))
+	assert(input != nil)
+	assert(1 <= length && length <= 3)
+	assert(secret != nil)
+	/*
+		len = 1: combined = { input[0], 0x01, input[0], input[0] }
+		len = 2: combined = { input[1], 0x02, input[0], input[1] }
+		len = 3: combined = { input[2], 0x03, input[0], input[1] }
+	*/
+	#no_bounds_check {
+		c1 := u32(input[0          ])
+		c2 := u32(input[length >> 1])
+		c3 := u32(input[length  - 1])
+
+		combined := c1 << 16 | c2  << 24 | c3 << 0 | length << 8
+		bitflip  := (u64(XXH32_read32(secret)) ~ u64(XXH32_read32(secret[4:]))) + seed
+		keyed    := u64(combined) ~ bitflip
+		return XXH64_avalanche(keyed)
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_len_4to8_64b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	length := u32(len(input))
+	assert(input != nil)
+	assert(4 <= length && length <= 8)
+	assert(secret != nil)
+	seed := seed
+
+	seed ~= u64(byte_swap(u32(seed) << 32))
+	#no_bounds_check {
+		input1  := XXH32_read32(input)
+		input2  := XXH32_read32(input[length - 4:])
+		bitflip := (XXH64_read64(secret[8:]) ~ XXH64_read64(secret[16:])) - seed
+		input64 := u64(input2) + (u64(input1) << 32)
+		keyed   := input64 ~ bitflip
+		return XXH3_rrmxmx(keyed, u64(length))
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_len_9to16_64b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	length := u64(len(input))
+	assert(input != nil)
+	assert(9 <= length && length <= 16)
+	assert(secret != nil)
+	#no_bounds_check {
+		bitflip1 := (XXH64_read64(secret[24:]) ~ XXH64_read64(secret[32:])) + seed
+		bitflip2 := (XXH64_read64(secret[40:]) ~ XXH64_read64(secret[48:])) - seed
+		input_lo := XXH64_read64(input)              ~ bitflip1
+		input_hi := XXH64_read64(input[length - 8:]) ~ bitflip2
+		acc      := length + byte_swap(input_lo) + input_hi \
+					+ XXH_mul_64_to_128_fold_64(input_lo, input_hi)
+		return XXH3_avalanche(acc)
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_len_0to16_64b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	length := u64(len(input))
+	assert(input != nil)
+	assert(length <= 16)
+	#no_bounds_check {
+		switch {
+		case length  > 8: return #force_inline XXH3_len_9to16_64b(input, secret, seed)
+		case length >= 4: return #force_inline XXH3_len_4to8_64b (input, secret, seed)
+		case length  > 0: return #force_inline XXH3_len_1to3_64b (input, secret, seed)
+		case:
+			return #force_inline XXH64_avalanche(seed ~ (XXH64_read64(secret[56:]) ~ XXH64_read64(secret[64:])))
+		}
+	}
+}
+
+/*
+	DISCLAIMER: There are known *seed-dependent* multicollisions here due to
+	multiplication by zero, affecting hashes of lengths 17 to 240.
+
+	However, they are very unlikely.
+
+	Keep this in mind when using the unseeded XXH3_64bits() variant: As with all
+	unseeded non-cryptographic hashes, it does not attempt to defend itself
+	against specially crafted inputs, only random inputs.
+
+	Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes
+	cancelling out the secret is taken an arbitrary number of times (addressed
+	in XXH3_accumulate_512), this collision is very unlikely with random inputs
+	and/or proper seeding:
+
+	This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a
+	function that is only called up to 16 times per hash with up to 240 bytes of
+	input.
+
+	This is not too bad for a non-cryptographic hash function, especially with
+	only 64 bit outputs.
+
+	The 128-bit variant (which trades some speed for strength) is NOT affected
+	by this, although it is always a good idea to use a proper seed if you care
+	about strength.
+*/
+@(optimization_mode="speed")
+XXH3_mix16B :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	input_lo := XXH64_read64(input[0:])
+	input_hi := XXH64_read64(input[8:])
+
+	input_lo ~= (XXH64_read64(secret[0:]) + seed)
+	input_hi ~= (XXH64_read64(secret[8:]) - seed)
+	return XXH_mul_64_to_128_fold_64(input_lo, input_hi)
+}
+
+/* For mid range keys, XXH3 uses a Mum-hash variant. */
+@(optimization_mode="speed")
+XXH3_len_17to128_64b :: proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	assert(len(secret) >= XXH3_SECRET_SIZE_MIN)
+	length := len(input)
+	assert(16 < length && length <= 128)
+
+	#no_bounds_check {
+		acc := u64(length) * XXH_PRIME64_1
+		switch {
+		case length > 96:
+			acc += XXH3_mix16B(input[48:         ], secret[96: ], seed)
+			acc += XXH3_mix16B(input[length - 64:], secret[112:], seed)
+			fallthrough
+		case length > 64:
+			acc += XXH3_mix16B(input[32:         ], secret[64: ], seed)
+			acc += XXH3_mix16B(input[length - 48:], secret[80: ], seed)
+			fallthrough
+		case length > 32:
+			acc += XXH3_mix16B(input[16:         ], secret[32: ], seed)
+			acc += XXH3_mix16B(input[length - 32:], secret[48: ], seed)
+			fallthrough
+		case:
+			acc += XXH3_mix16B(input[0:          ], secret[0:  ], seed)
+			acc += XXH3_mix16B(input[length - 16:], secret[16: ], seed)
+		}
+		return XXH3_avalanche(acc)
+	}
+}
+
+XXH3_MIDSIZE_MAX         :: 240
+XXH3_MIDSIZE_STARTOFFSET :: 3
+XXH3_MIDSIZE_LASTOFFSET  :: 17
+
+@(optimization_mode="speed")
+XXH3_len_129to240_64b :: proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u64) {
+	assert(len(secret) >= XXH3_SECRET_SIZE_MIN)
+	length := len(input)
+	assert(128 < length && length <= XXH3_MIDSIZE_MAX)
+
+	#no_bounds_check {
+		acc := u64(length) * XXH_PRIME64_1
+		nbRounds := length / 16
+
+		i: int
+		for i = 0; i < 8; i += 1 {
+			acc += XXH3_mix16B(input[16 * i:], secret[16 * i:], seed)
+		}
+
+		acc = XXH3_avalanche(acc)
+		assert(nbRounds >= 8)
+
+		for i = 8; i < nbRounds; i += 1 {
+			acc += XXH3_mix16B(input[16 * i:], secret[(16 * (i - 8)) + XXH3_MIDSIZE_STARTOFFSET:], seed)
+		}
+		/* last bytes */
+		acc += XXH3_mix16B(input[length - 16:], secret[XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET:], seed)
+		return XXH3_avalanche(acc)
+	}
+}
+
+/* =======     Long Keys     ======= */
+
+XXH_STRIPE_LEN          :: 64
+XXH_SECRET_CONSUME_RATE :: 8 /* nb of secret bytes consumed at each accumulation */
+XXH_ACC_NB              :: (XXH_STRIPE_LEN / size_of(xxh_u64))
+
+@(optimization_mode="speed")
+XXH_writeLE64 :: #force_inline proc(dst: []u8, v64: u64le) {
+	v := v64
+	mem_copy(raw_data(dst), &v, size_of(v64))
+}
+
+/*
+ * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized.
+ *
+ * It is a hardened version of UMAC, based off of FARSH's implementation.
+ *
+ * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD
+ * implementations, and it is ridiculously fast.
+ *
+ * We harden it by mixing the original input to the accumulators as well as the product.
+ *
+ * This means that in the (relatively likely) case of a multiply by zero, the
+ * original input is preserved.
+ *
+ * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve
+ * cross-pollination, as otherwise the upper and lower halves would be
+ * essentially independent.
+ *
+ * This doesn't matter on 64-bit hashes since they all get merged together in
+ * the end, so we skip the extra step.
+ *
+ * Both XXH3_64bits and XXH3_128bits use this subroutine.
+ */
+
+XXH3_accumulate_512_f       :: #type proc(acc: []xxh_u64, input:  []u8, secret: []u8)
+XXH3_scramble_accumulator_f :: #type proc(acc: []xxh_u64, secret: []u8)
+XXH3_init_custom_secret_f   :: #type proc(custom_secret: []u8, seed64: xxh_u64)
+
+XXH3_accumulate_512       : XXH3_accumulate_512_f       = XXH3_accumulate_512_scalar
+XXH3_scramble_accumulator : XXH3_scramble_accumulator_f = XXH3_scramble_accumulator_scalar
+XXH3_init_custom_secret   : XXH3_init_custom_secret_f   = XXH3_init_custom_secret_scalar
+
+/* scalar variants - universal */
+@(optimization_mode="speed")
+XXH3_accumulate_512_scalar :: #force_inline proc(acc: []xxh_u64, input: []u8, secret: []u8) {
+	xacc    := acc     /* presumed aligned */
+	xinput  := input   /* no alignment restriction */
+	xsecret := secret  /* no alignment restriction */
+
+	assert(uintptr(raw_data(acc)) & uintptr(XXH_ACC_ALIGN - 1) == 0)
+
+	#no_bounds_check for i := uint(0); i < XXH_ACC_NB; i += 1 {
+		data_val    := XXH64_read64(xinput[8 * i:])
+		data_key    := data_val ~ XXH64_read64(xsecret[8 * i:])
+		xacc[i ~ 1] += data_val /* swap adjacent lanes */
+		xacc[i    ] += XXH_mul_32_to_64(u32(data_key & 0xFFFFFFFF), u32(data_key >> 32))
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_scramble_accumulator_scalar :: #force_inline proc(acc: []xxh_u64, secret: []u8) {
+	xacc    := acc     /* presumed aligned */
+	xsecret := secret  /* no alignment restriction */
+
+	assert(uintptr(raw_data(acc)) & uintptr(XXH_ACC_ALIGN - 1) == 0)
+
+	#no_bounds_check for i := uint(0); i < XXH_ACC_NB; i += 1 {
+		key64   := XXH64_read64(xsecret[8 * i:])
+		acc64   := xacc[i]
+		acc64    = XXH_xorshift_64(acc64, 47)
+		acc64   ~= key64
+		acc64   *= u64(XXH_PRIME32_1)
+		xacc[i]  = acc64
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_init_custom_secret_scalar :: #force_inline proc(custom_secret: []u8, seed64: xxh_u64) {
+	#assert((XXH_SECRET_DEFAULT_SIZE & 15) == 0)
+
+	kSecretPtr := XXH3_kSecret
+
+	nbRounds := XXH_SECRET_DEFAULT_SIZE / 16
+	#no_bounds_check for i := 0; i < nbRounds; i += 1 {
+		lo := XXH64_read64(kSecretPtr[16 * i:    ]) + seed64
+		hi := XXH64_read64(kSecretPtr[16 * i + 8:]) - seed64
+		XXH_writeLE64(custom_secret[16 * i:    ], u64le(lo))
+		XXH_writeLE64(custom_secret[16 * i + 8:], u64le(hi))
+	}
+}
+
+XXH_PREFETCH_DIST :: 320
+
+/*
+ * XXH3_accumulate()
+ * Loops over XXH3_accumulate_512().
+ * Assumption: nbStripes will not overflow the secret size
+ */
+@(optimization_mode="speed")
+XXH3_accumulate :: #force_inline proc(acc: []xxh_u64, input: []u8, secret: []u8, nbStripes: uint,
+	f_acc512: XXH3_accumulate_512_f) {
+
+	for n := uint(0); n < nbStripes; n += 1 {
+		when !XXH_DISABLE_PREFETCH {
+			in_ptr := &input[n * XXH_STRIPE_LEN]
+			prefetch(in_ptr, XXH_PREFETCH_DIST)
+		}
+		f_acc512(acc, input[n * XXH_STRIPE_LEN:], secret[n * XXH_SECRET_CONSUME_RATE:])
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_hashLong_internal_loop :: #force_inline proc(acc: []xxh_u64, input: []u8, secret: []u8,
+	f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) {
+
+	length      := uint(len(input))
+	secret_size := uint(len(secret))
+	stripes_per_block := (secret_size - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE
+
+	block_len   := XXH_STRIPE_LEN * stripes_per_block
+	blocks      := (length - 1) / block_len
+
+	#no_bounds_check for n := uint(0); n < blocks; n += 1 {
+		XXH3_accumulate(acc, input[n * block_len:], secret, stripes_per_block, f_acc512)
+		f_scramble(acc, secret[secret_size - XXH_STRIPE_LEN:])
+	}
+
+	/* last partial block */
+	#no_bounds_check {
+		stripes := ((length - 1) - (block_len * blocks)) / XXH_STRIPE_LEN
+
+		XXH3_accumulate(acc, input[blocks * block_len:], secret, stripes, f_acc512)
+
+		/* last stripe */
+		#no_bounds_check {
+			p := input[length - XXH_STRIPE_LEN:]
+			XXH_SECRET_LASTACC_START :: 7  /* not aligned on 8, last secret is different from acc & scrambler */
+			f_acc512(acc, p, secret[secret_size - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START:])
+		}
+	}
+}
+
+@(optimization_mode="speed")
+XXH3_mix2Accs :: #force_inline proc(acc: []xxh_u64, secret: []u8) -> (res: xxh_u64) {
+	return XXH_mul_64_to_128_fold_64(
+		acc[0] ~ XXH64_read64(secret),
+		acc[1] ~ XXH64_read64(secret[8:]))
+}
+
+@(optimization_mode="speed")
+XXH3_mergeAccs :: #force_inline proc(acc: []xxh_u64, secret: []u8, start: xxh_u64) -> (res: xxh_u64) {
+	result64 := start
+	#no_bounds_check for i := 0; i < 4; i += 1 {
+		result64 += XXH3_mix2Accs(acc[2 * i:], secret[16 * i:])
+	}
+	return XXH3_avalanche(result64)
+}

+ 2 - 1
core/hash/xxhash/xxhash_32.odin

@@ -15,6 +15,7 @@ import "core:intrinsics"
 	32-bit hash functions
 */
 XXH32_hash :: u32
+xxh_u32    :: u32
 XXH32_DEFAULT_SEED :: XXH32_hash(0)
 
 XXH32_state :: struct {
@@ -153,7 +154,7 @@ XXH32_endian_align :: #force_inline proc(input: []u8, seed := XXH32_DEFAULT_SEED
 		v3 := seed + 0
 		v4 := seed - XXH_PRIME32_1
 
-		for len(buf) >= 15 {
+		for len(buf) >= 16 {
 			#no_bounds_check v1 = XXH32_round(v1, XXH32_read32(buf, alignment)); buf = buf[4:]
 			#no_bounds_check v2 = XXH32_round(v2, XXH32_read32(buf, alignment)); buf = buf[4:]
 			#no_bounds_check v3 = XXH32_round(v3, XXH32_read32(buf, alignment)); buf = buf[4:]

+ 63 - 9
tests/core/hash/test_core_hash.odin

@@ -1,4 +1,4 @@
-package test_core_image
+package test_core_hash
 
 import "core:hash/xxhash"
 import "core:time"
@@ -31,6 +31,7 @@ when ODIN_TEST {
 main :: proc() {
     t := testing.T{}
     test_benchmark_runner(&t)
+    test_xxhash_vectors(&t)
     fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
 }
 
@@ -52,7 +53,7 @@ teardown_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.a
     return nil
 }
 
-benchmark_xxhash32 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
+benchmark_xxh32 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
     buf := options.input
 
     h: u32
@@ -65,7 +66,7 @@ benchmark_xxhash32 :: proc(options: ^time.Benchmark_Options, allocator := contex
     return nil
 }
 
-benchmark_xxhash64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
+benchmark_xxh64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
     buf := options.input
 
     h: u64
@@ -78,6 +79,19 @@ benchmark_xxhash64 :: proc(options: ^time.Benchmark_Options, allocator := contex
     return nil
 }
 
+benchmark_xxh3_128 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
+    buf := options.input
+
+    h: u128
+    for _ in 0..=options.rounds {
+        h = xxhash.XXH3_128bits(buf)
+    }
+    options.count     = options.rounds
+    options.processed = options.rounds * options.bytes
+    options.hash      = h
+    return nil
+}
+
 benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
     fmt.printf("\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
         name,
@@ -93,12 +107,12 @@ benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
 test_benchmark_runner :: proc(t: ^testing.T) {
     fmt.println("Starting benchmarks:")
 
-    name    := "xxhash32 100 zero bytes"
+    name    := "XXH32 100 zero bytes"
     options := &time.Benchmark_Options{
         rounds   = 1_000,
         bytes    = 100,
         setup    = setup_xxhash,
-        bench    = benchmark_xxhash32,
+        bench    = benchmark_xxh32,
         teardown = teardown_xxhash,
     }
 
@@ -107,25 +121,65 @@ test_benchmark_runner :: proc(t: ^testing.T) {
     expect(t, options.hash == 0x85f6413c, name)
     benchmark_print(name, options)
 
-    name = "xxhash32 1 MiB zero bytes"
+    name = "XXH32 1 MiB zero bytes"
     options.bytes = 1_048_576
     err = time.benchmark(options, context.allocator)
     expect(t, err == nil, name)
     expect(t, options.hash == 0x9430f97f, name)
     benchmark_print(name, options)
 
-    name = "xxhash64 100 zero bytes"
+    name = "XXH64 100 zero bytes"
     options.bytes  = 100
-    options.bench = benchmark_xxhash64
+    options.bench = benchmark_xxh64
     err = time.benchmark(options, context.allocator)
     expect(t, err == nil, name)
     expect(t, options.hash == 0x17bb1103c92c502f, name)
     benchmark_print(name, options)
 
-    name = "xxhash64 1 MiB zero bytes"
+    name = "XXH64 1 MiB zero bytes"
     options.bytes = 1_048_576
     err = time.benchmark(options, context.allocator)
     expect(t, err == nil, name)
     expect(t, options.hash == 0x87d2a1b6e1163ef1, name)
     benchmark_print(name, options)
+
+    name = "XXH3_128 100 zero bytes"
+    options.bytes  = 100
+    options.bench = benchmark_xxh3_128
+    err = time.benchmark(options, context.allocator)
+    expect(t, err == nil, name)
+    expect(t, options.hash == 0x6ba30a4e9dffe1ff801fedc74ccd608c, name)
+    benchmark_print(name, options)
+
+    name = "XXH3_128 1 MiB zero bytes"
+    options.bytes = 1_048_576
+    err = time.benchmark(options, context.allocator)
+    expect(t, err == nil, name)
+    expect(t, options.hash == 0xb6ef17a3448492b6918780b90550bf34, name)
+    benchmark_print(name, options)
+}
+
+@test
+test_xxhash_vectors :: proc(t: ^testing.T) {
+    fmt.println("Verifying against XXHASH_TEST_VECTOR_ZERO:")
+
+    buf := make([]u8, 256)
+    defer delete(buf)
+
+    for v, i in XXHASH_TEST_VECTOR_ZERO[:] {
+        b := buf[:i]
+
+        xxh32    := xxhash.XXH32(b)
+        xxh64    := xxhash.XXH64(b)
+        xxh3_128 := xxhash.XXH3_128bits(b)
+
+        xxh32_error    := fmt.tprintf("[   XXH32(%03d] Expected: %08x. Got: %08x.", i,   v.xxh_32, xxh32)
+        xxh64_error    := fmt.tprintf("[   XXH64(%03d] Expected: %16x. Got: %16x.", i,   v.xxh_64, xxh64)
+        xxh3_128_error := fmt.tprintf("[XXH3_128(%03d] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
+
+        expect(t, xxh32     == v.xxh_32,   xxh32_error)
+        expect(t, xxh64     == v.xxh_64,   xxh64_error)
+        expect(t, xxh3_128  == v.xxh3_128, xxh3_128_error)
+    }
+
 }

+ 1568 - 0
tests/core/hash/test_vectors_xxhash.odin

@@ -0,0 +1,1568 @@
+/*
+	Hash Test Vectors
+*/
+package test_core_hash
+
+XXHASH_Test_Vectors :: struct #packed {
+	/*
+		Old hashes
+	*/
+	xxh_32:   u32,
+	xxh_64:   u64,
+
+	/*
+		XXH3 hashes
+	*/
+	xxh3_64:  u64,
+	xxh3_128: u128,
+}
+
+/*
+	Generated table. Do not edit.
+
+	Contains the hashes of an empty string and varying lengths of zero bytes.
+*/
+XXHASH_TEST_VECTOR_ZERO := [?]XXHASH_Test_Vectors{
+	{ // Length: 000
+		/* XXH32    */ 0x02cc5d05,
+		/* XXH64    */ 0xef46db3751d8e999,
+		/* XXH3_64  */ 0x2d06800538d394c2,
+		/* XXH3_128 */ 0x99aa06d3014798d86001c324468d497f,
+	},
+	{ // Length: 001
+		/* XXH32    */ 0xcf65b03e,
+		/* XXH64    */ 0xe934a84adb052768,
+		/* XXH3_64  */ 0xc44bdff4074eecdb,
+		/* XXH3_128 */ 0xa6cd5e9392000f6ac44bdff4074eecdb,
+	},
+	{ // Length: 002
+		/* XXH32    */ 0xb5aa6af5,
+		/* XXH64    */ 0x9aaba41ffa2da101,
+		/* XXH3_64  */ 0x3325230e1f285505,
+		/* XXH3_128 */ 0x4758ddac5f9ee9383325230e1f285505,
+	},
+	{ // Length: 003
+		/* XXH32    */ 0xfe8990bc,
+		/* XXH64    */ 0x31886f2e7daf8ca4,
+		/* XXH3_64  */ 0xeb5d658bb22f286b,
+		/* XXH3_128 */ 0xf21da334f2869f1beb5d658bb22f286b,
+	},
+	{ // Length: 004
+		/* XXH32    */ 0x08d6d969,
+		/* XXH64    */ 0x3aefa6fd5cf2deb4,
+		/* XXH3_64  */ 0x48b2c92616fc193d,
+		/* XXH3_128 */ 0x2a33816ed7e0c373dbe563c737220b65,
+	},
+	{ // Length: 005
+		/* XXH32    */ 0x1295514d,
+		/* XXH64    */ 0x00f4f72fb7a8c648,
+		/* XXH3_64  */ 0xe864e5893a273242,
+		/* XXH3_128 */ 0xc61571a9fa58278456b1430ea9e34626,
+	},
+	{ // Length: 006
+		/* XXH32    */ 0x5a8b29ae,
+		/* XXH64    */ 0xc0dcf27516acb324,
+		/* XXH3_64  */ 0x06df73813892fde7,
+		/* XXH3_128 */ 0xd549b1ebc4f70c3a3f4ece58ec0e5d0b,
+	},
+	{ // Length: 007
+		/* XXH32    */ 0xf690e79e,
+		/* XXH64    */ 0x694bb0caf1a4a679,
+		/* XXH3_64  */ 0xa6918fec1ae65b70,
+		/* XXH3_128 */ 0x10c3b38808feb67121630b6dfa675bc8,
+	},
+	{ // Length: 008
+		/* XXH32    */ 0xdeb39513,
+		/* XXH64    */ 0x34c96acdcadb1bbb,
+		/* XXH3_64  */ 0xc77b3abb6f87acd9,
+		/* XXH3_128 */ 0x2c0a8a99dc147d5445c3b49d035665b2,
+	},
+	{ // Length: 009
+		/* XXH32    */ 0xefd04b91,
+		/* XXH64    */ 0x5149774f0dcd2f3d,
+		/* XXH3_64  */ 0x34499569f0391857,
+		/* XXH3_128 */ 0xbe637bf2e7ab4aec17dbb924bfd111e6,
+	},
+	{ // Length: 010
+		/* XXH32    */ 0x7dd9f4a7,
+		/* XXH64    */ 0xa86a71f0ad20261a,
+		/* XXH3_64  */ 0x4a9ffcfb2837fbcc,
+		/* XXH3_128 */ 0x6b7b76bcbcfa7c6bfd5485081f482dca,
+	},
+	{ // Length: 011
+		/* XXH32    */ 0x25ae4e0d,
+		/* XXH64    */ 0x6992ce3f48c82aaa,
+		/* XXH3_64  */ 0xae432800a1609968,
+		/* XXH3_128 */ 0x1a23c76f2d0158d8ab9c6caab332c468,
+	},
+	{ // Length: 012
+		/* XXH32    */ 0x31b8da82,
+		/* XXH64    */ 0xef6eb604187a17fa,
+		/* XXH3_64  */ 0xc4998f9169c2a4f0,
+		/* XXH3_128 */ 0xe6674c25262712b2faca856ad20a2da8,
+	},
+	{ // Length: 013
+		/* XXH32    */ 0xf5ed7079,
+		/* XXH64    */ 0xa0537b08c36938b4,
+		/* XXH3_64  */ 0xdaeff723917d5279,
+		/* XXH3_128 */ 0x8804b1c74117dca722fb57a9a0a9ff6b,
+	},
+	{ // Length: 014
+		/* XXH32    */ 0x7974215b,
+		/* XXH64    */ 0x92e8d4a7f7f25fa1,
+		/* XXH3_64  */ 0xf1465eb4188c41e7,
+		/* XXH3_128 */ 0x0ad0aa4823cee1d60874238db4108b4f,
+	},
+	{ // Length: 015
+		/* XXH32    */ 0x4e74a649,
+		/* XXH64    */ 0x00d320899107bed7,
+		/* XXH3_64  */ 0xba5002d3c3ed6bc7,
+		/* XXH3_128 */ 0x2b6b8e16c81bde412071580ae887f0c8,
+	},
+	{ // Length: 016
+		/* XXH32    */ 0x8e022b3a,
+		/* XXH64    */ 0xaf09f71516247c32,
+		/* XXH3_64  */ 0xd0a66a65c7528968,
+		/* XXH3_128 */ 0xe5189a9599e3f86205ea23ef06e28b2d,
+	},
+	{ // Length: 017
+		/* XXH32    */ 0xb56f16ff,
+		/* XXH64    */ 0x9439ed185e5550fa,
+		/* XXH3_64  */ 0xc2915ca0df7ad4c1,
+		/* XXH3_128 */ 0xa3d7e4cef35b1f44c2915ca0df7ad4c1,
+	},
+	{ // Length: 018
+		/* XXH32    */ 0x4a1ba10a,
+		/* XXH64    */ 0x41b4d1c910c1a58d,
+		/* XXH3_64  */ 0xff7821ddf836d020,
+		/* XXH3_128 */ 0xc7f568b6986be940ff7821ddf836d020,
+	},
+	{ // Length: 019
+		/* XXH32    */ 0x3e4f38a4,
+		/* XXH64    */ 0xa16d44d762b22272,
+		/* XXH3_64  */ 0x871128246eb452b8,
+		/* XXH3_128 */ 0xd76aec6dd4f27d34871128246eb452b8,
+	},
+	{ // Length: 020
+		/* XXH32    */ 0x4f7af1bb,
+		/* XXH64    */ 0x5c41df61e8f6b241,
+		/* XXH3_64  */ 0x16773ceb7fe497b1,
+		/* XXH3_128 */ 0x9098098c9951f3d716773ceb7fe497b1,
+	},
+	{ // Length: 021
+		/* XXH32    */ 0x05236995,
+		/* XXH64    */ 0x787668eb63709dbc,
+		/* XXH3_64  */ 0x179bf729d80ef336,
+		/* XXH3_128 */ 0x5feaa38006f558d7179bf729d80ef336,
+	},
+	{ // Length: 022
+		/* XXH32    */ 0xe7e83293,
+		/* XXH64    */ 0x697adbf510633d99,
+		/* XXH3_64  */ 0x416655d91873f97a,
+		/* XXH3_128 */ 0x9edfa049976b041c416655d91873f97a,
+	},
+	{ // Length: 023
+		/* XXH32    */ 0x9ea069d2,
+		/* XXH64    */ 0x642be7d432193f12,
+		/* XXH3_64  */ 0xaa7f1cb1d402d3ef,
+		/* XXH3_128 */ 0xc022a675d8403513aa7f1cb1d402d3ef,
+	},
+	{ // Length: 024
+		/* XXH32    */ 0x417a81cb,
+		/* XXH64    */ 0xbb3302e8a9608868,
+		/* XXH3_64  */ 0x743df94ee4c78a2a,
+		/* XXH3_128 */ 0x10e45c7ce2292320743df94ee4c78a2a,
+	},
+	{ // Length: 025
+		/* XXH32    */ 0xb35af511,
+		/* XXH64    */ 0x07a318ba9cfa1a62,
+		/* XXH3_64  */ 0x5f51d22ec7704ee3,
+		/* XXH3_128 */ 0x2ffffbdfa6f2c4815f51d22ec7704ee3,
+	},
+	{ // Length: 026
+		/* XXH32    */ 0x6029c1d7,
+		/* XXH64    */ 0x080bf51a321e7d45,
+		/* XXH3_64  */ 0xeb71ed3c7b489882,
+		/* XXH3_128 */ 0x14d8300472ada469eb71ed3c7b489882,
+	},
+	{ // Length: 027
+		/* XXH32    */ 0x38a03df1,
+		/* XXH64    */ 0x3a18105d958b005c,
+		/* XXH3_64  */ 0x2b95da75314c046d,
+		/* XXH3_128 */ 0x4029572cfc2a18452b95da75314c046d,
+	},
+	{ // Length: 028
+		/* XXH32    */ 0x572dc7b1,
+		/* XXH64    */ 0x0f4c009c9804ec77,
+		/* XXH3_64  */ 0xce61ca9d7b6f0bb2,
+		/* XXH3_128 */ 0x68ea838a2dee7fefce61ca9d7b6f0bb2,
+	},
+	{ // Length: 029
+		/* XXH32    */ 0xdc4ae301,
+		/* XXH64    */ 0xc143871a3eb50079,
+		/* XXH3_64  */ 0xec9ee2320b33b9e1,
+		/* XXH3_128 */ 0x0fa8b0c4bb0c7aa5ec9ee2320b33b9e1,
+	},
+	{ // Length: 030
+		/* XXH32    */ 0x875e230f,
+		/* XXH64    */ 0xa76530f96ba6820d,
+		/* XXH3_64  */ 0x793986593fa9f4a5,
+		/* XXH3_128 */ 0x3fe570f468069182793986593fa9f4a5,
+	},
+	{ // Length: 031
+		/* XXH32    */ 0x0dafe948,
+		/* XXH64    */ 0xfaf43dd52deb083a,
+		/* XXH3_64  */ 0x46968602e8f3e5e0,
+		/* XXH3_128 */ 0x1836257ae1714c0c46968602e8f3e5e0,
+	},
+	{ // Length: 032
+		/* XXH32    */ 0x2ca90bd2,
+		/* XXH64    */ 0xf6e9be5d70632cf5,
+		/* XXH3_64  */ 0xa057271c9071c99d,
+		/* XXH3_128 */ 0x9a026d96b3c0f0fca057271c9071c99d,
+	},
+	{ // Length: 033
+		/* XXH32    */ 0x6d64bd7f,
+		/* XXH64    */ 0x1dcdf75a2320fb61,
+		/* XXH3_64  */ 0xb04859b19481d612,
+		/* XXH3_128 */ 0x94fd2298a3e11910b04859b19481d612,
+	},
+	{ // Length: 034
+		/* XXH32    */ 0x6c15ede5,
+		/* XXH64    */ 0xb939324150a020e0,
+		/* XXH3_64  */ 0xde25847822ca64cf,
+		/* XXH3_128 */ 0xbc923c6eec2a52fede25847822ca64cf,
+	},
+	{ // Length: 035
+		/* XXH32    */ 0x637ce2a2,
+		/* XXH64    */ 0xe2e009843a88754c,
+		/* XXH3_64  */ 0xdc5cadabf5713573,
+		/* XXH3_128 */ 0xbe77ce8b0a064b1edc5cadabf5713573,
+	},
+	{ // Length: 036
+		/* XXH32    */ 0xba49aa46,
+		/* XXH64    */ 0x65b3a875a2520cd1,
+		/* XXH3_64  */ 0xa2072842cc0b0784,
+		/* XXH3_128 */ 0xde7d71112ba8a784a2072842cc0b0784,
+	},
+	{ // Length: 037
+		/* XXH32    */ 0x90cf9be1,
+		/* XXH64    */ 0x4a4623374a95327f,
+		/* XXH3_64  */ 0xd02fa372aef37ad7,
+		/* XXH3_128 */ 0x459c3747b68e30cad02fa372aef37ad7,
+	},
+	{ // Length: 038
+		/* XXH32    */ 0x58220018,
+		/* XXH64    */ 0xb838fe6493df494e,
+		/* XXH3_64  */ 0x9e0b2c9421a55768,
+		/* XXH3_128 */ 0xd55bd7225227c8a99e0b2c9421a55768,
+	},
+	{ // Length: 039
+		/* XXH32    */ 0xa28c0e25,
+		/* XXH64    */ 0x483c0d7d8f0a0c35,
+		/* XXH3_64  */ 0x85215de948375fbf,
+		/* XXH3_128 */ 0x522a4ad80b50855685215de948375fbf,
+	},
+	{ // Length: 040
+		/* XXH32    */ 0x9a77cf33,
+		/* XXH64    */ 0xf628aee62df1d172,
+		/* XXH3_64  */ 0x114ddfda264d5aa9,
+		/* XXH3_128 */ 0xce62b44e257dbdc8114ddfda264d5aa9,
+	},
+	{ // Length: 041
+		/* XXH32    */ 0x2ce57620,
+		/* XXH64    */ 0x997f90e996d48321,
+		/* XXH3_64  */ 0x7adbc8ba9ffaf49d,
+		/* XXH3_128 */ 0xbcac8a17609a25937adbc8ba9ffaf49d,
+	},
+	{ // Length: 042
+		/* XXH32    */ 0x3e02ab9c,
+		/* XXH64    */ 0x60b98e93296826a4,
+		/* XXH3_64  */ 0xf4cb491eb3696e04,
+		/* XXH3_128 */ 0x415598f1527c707af4cb491eb3696e04,
+	},
+	{ // Length: 043
+		/* XXH32    */ 0xf2985cf9,
+		/* XXH64    */ 0xcb87e16dbdc8b7fd,
+		/* XXH3_64  */ 0x55c2d27079d731f4,
+		/* XXH3_128 */ 0xbe6472cbe5f5db5055c2d27079d731f4,
+	},
+	{ // Length: 044
+		/* XXH32    */ 0x831e8dda,
+		/* XXH64    */ 0x3e572f302424ea4e,
+		/* XXH3_64  */ 0xf8ccce12b9b44227,
+		/* XXH3_128 */ 0x54085206a438aa87f8ccce12b9b44227,
+	},
+	{ // Length: 045
+		/* XXH32    */ 0x2c8eae78,
+		/* XXH64    */ 0x3c67e0223671cbd4,
+		/* XXH3_64  */ 0x60160973aa67f452,
+		/* XXH3_128 */ 0x5922351d5386e86260160973aa67f452,
+	},
+	{ // Length: 046
+		/* XXH32    */ 0x0fbd4ef4,
+		/* XXH64    */ 0x2c3a906e14ca47ed,
+		/* XXH3_64  */ 0xa0cff001705f6231,
+		/* XXH3_128 */ 0xe999bc7b456d2505a0cff001705f6231,
+	},
+	{ // Length: 047
+		/* XXH32    */ 0x349da64d,
+		/* XXH64    */ 0x8c086ccb15b0ebf9,
+		/* XXH3_64  */ 0x09ea32bae18b89b0,
+		/* XXH3_128 */ 0xfef20032bab2834a09ea32bae18b89b0,
+	},
+	{ // Length: 048
+		/* XXH32    */ 0xb94691a7,
+		/* XXH64    */ 0x6417e2a002851674,
+		/* XXH3_64  */ 0xe255222d4cbbadba,
+		/* XXH3_128 */ 0x505cd4e066810498e255222d4cbbadba,
+	},
+	{ // Length: 049
+		/* XXH32    */ 0xd3ac78a9,
+		/* XXH64    */ 0x4b96cd9a29fd1847,
+		/* XXH3_64  */ 0xdadbdbba36be011e,
+		/* XXH3_128 */ 0x8ad91a2b91ed3152dadbdbba36be011e,
+	},
+	{ // Length: 050
+		/* XXH32    */ 0xdae401a1,
+		/* XXH64    */ 0xfe42daab5b49e8e3,
+		/* XXH3_64  */ 0x34123513a8226af5,
+		/* XXH3_128 */ 0xa997728a1e9d02fd34123513a8226af5,
+	},
+	{ // Length: 051
+		/* XXH32    */ 0xaa7a302a,
+		/* XXH64    */ 0x4278e49e8e28a504,
+		/* XXH3_64  */ 0xd27a9ef83c2beb31,
+		/* XXH3_128 */ 0x130e637da5525e10d27a9ef83c2beb31,
+	},
+	{ // Length: 052
+		/* XXH32    */ 0xe4da7644,
+		/* XXH64    */ 0xed247cafb7abe0c1,
+		/* XXH3_64  */ 0x03f4e2387fe12749,
+		/* XXH3_128 */ 0x509cdb4740ea882a03f4e2387fe12749,
+	},
+	{ // Length: 053
+		/* XXH32    */ 0x05e92415,
+		/* XXH64    */ 0x0eebb75605c963e6,
+		/* XXH3_64  */ 0xb5498f8c58ccdf3a,
+		/* XXH3_128 */ 0xaad46ceb440f2d9bb5498f8c58ccdf3a,
+	},
+	{ // Length: 054
+		/* XXH32    */ 0x2636f802,
+		/* XXH64    */ 0x7e94f2d0c81ae7c2,
+		/* XXH3_64  */ 0x89a5f3c8f994848c,
+		/* XXH3_128 */ 0xe936394de8b0942189a5f3c8f994848c,
+	},
+	{ // Length: 055
+		/* XXH32    */ 0x9b2ca6b9,
+		/* XXH64    */ 0xd1b1e0402c747a83,
+		/* XXH3_64  */ 0xc1d3d99620cc3ad1,
+		/* XXH3_128 */ 0xc3f6765f660b5d37c1d3d99620cc3ad1,
+	},
+	{ // Length: 056
+		/* XXH32    */ 0x475465a2,
+		/* XXH64    */ 0x980d0b8e72041fe5,
+		/* XXH3_64  */ 0xa09fd01dacf4d826,
+		/* XXH3_128 */ 0x09fcf90ff543876ba09fd01dacf4d826,
+	},
+	{ // Length: 057
+		/* XXH32    */ 0x68b79773,
+		/* XXH64    */ 0x4b4d61bb10aee480,
+		/* XXH3_64  */ 0xc8a653c88b0afd80,
+		/* XXH3_128 */ 0x4151153d9548d856c8a653c88b0afd80,
+	},
+	{ // Length: 058
+		/* XXH32    */ 0xec391d71,
+		/* XXH64    */ 0x60f2249f8b7a9a72,
+		/* XXH3_64  */ 0x9ee195652fac565c,
+		/* XXH3_128 */ 0x448103ce597a6fab9ee195652fac565c,
+	},
+	{ // Length: 059
+		/* XXH32    */ 0xf1850d79,
+		/* XXH64    */ 0x100b0cb03afaf4a6,
+		/* XXH3_64  */ 0x3193ca9ff7a1073a,
+		/* XXH3_128 */ 0xa8bc5741d90116223193ca9ff7a1073a,
+	},
+	{ // Length: 060
+		/* XXH32    */ 0x745fc665,
+		/* XXH64    */ 0x1927c0b67f2f4a87,
+		/* XXH3_64  */ 0x543396b68d640202,
+		/* XXH3_128 */ 0x162f4563e5e15201543396b68d640202,
+	},
+	{ // Length: 061
+		/* XXH32    */ 0xb790a626,
+		/* XXH64    */ 0x71d999e69dfa9118,
+		/* XXH3_64  */ 0xef39e3b7ab6c4e95,
+		/* XXH3_128 */ 0x94af216889420e38ef39e3b7ab6c4e95,
+	},
+	{ // Length: 062
+		/* XXH32    */ 0x369444de,
+		/* XXH64    */ 0x80c81b08d512ab4a,
+		/* XXH3_64  */ 0x76a237b80bdeb0cf,
+		/* XXH3_128 */ 0x94fb99d048a1438c76a237b80bdeb0cf,
+	},
+	{ // Length: 063
+		/* XXH32    */ 0x0d1b416a,
+		/* XXH64    */ 0xd81772f2c42d7324,
+		/* XXH3_64  */ 0x92f7676966fb0922,
+		/* XXH3_128 */ 0x3ed179345c16a26492f7676966fb0922,
+	},
+	{ // Length: 064
+		/* XXH32    */ 0x56328790,
+		/* XXH64    */ 0x257b09a147b82a19,
+		/* XXH3_64  */ 0x2ffb6918c12c256e,
+		/* XXH3_128 */ 0xb388416ffd4823362ffb6918c12c256e,
+	},
+	{ // Length: 065
+		/* XXH32    */ 0x8cdac082,
+		/* XXH64    */ 0xd033cd270447f937,
+		/* XXH3_64  */ 0x366a5eb034af8f31,
+		/* XXH3_128 */ 0xf28016b3da3c2678366a5eb034af8f31,
+	},
+	{ // Length: 066
+		/* XXH32    */ 0x8f89069d,
+		/* XXH64    */ 0x1f3015449a5a2480,
+		/* XXH3_64  */ 0x8f21e531bcb46e31,
+		/* XXH3_128 */ 0x115c167b9e97e17c8f21e531bcb46e31,
+	},
+	{ // Length: 067
+		/* XXH32    */ 0xd5fa1152,
+		/* XXH64    */ 0xf8f20e020412c80a,
+		/* XXH3_64  */ 0x66da31b516f8dfbf,
+		/* XXH3_128 */ 0x98d52d2cf2554be166da31b516f8dfbf,
+	},
+	{ // Length: 068
+		/* XXH32    */ 0x29f14397,
+		/* XXH64    */ 0x0a679d6f6e1d084c,
+		/* XXH3_64  */ 0xe083361f27eb4e08,
+		/* XXH3_128 */ 0x4a0e35c850e440c1e083361f27eb4e08,
+	},
+	{ // Length: 069
+		/* XXH32    */ 0x8deef591,
+		/* XXH64    */ 0x221b3e9c66ed049b,
+		/* XXH3_64  */ 0x165f43a96bc5a87d,
+		/* XXH3_128 */ 0x7bc4f46b77560b91165f43a96bc5a87d,
+	},
+	{ // Length: 070
+		/* XXH32    */ 0x96de4f90,
+		/* XXH64    */ 0xcc19586bc6b6659e,
+		/* XXH3_64  */ 0xc941a33c3ba07dca,
+		/* XXH3_128 */ 0x7c3463f21e31dd36c941a33c3ba07dca,
+	},
+	{ // Length: 071
+		/* XXH32    */ 0x80027956,
+		/* XXH64    */ 0x462b2c1d5cc67d0d,
+		/* XXH3_64  */ 0xe9edfd1707cc358e,
+		/* XXH3_128 */ 0xd34f102dd6ab6c2fe9edfd1707cc358e,
+	},
+	{ // Length: 072
+		/* XXH32    */ 0x0c31a45d,
+		/* XXH64    */ 0xd2c15e19901d658e,
+		/* XXH3_64  */ 0xd19b67b2d77d4003,
+		/* XXH3_128 */ 0x0442236975e8eee0d19b67b2d77d4003,
+	},
+	{ // Length: 073
+		/* XXH32    */ 0xc950dfa3,
+		/* XXH64    */ 0xbe88019ce5de71b6,
+		/* XXH3_64  */ 0x5e6d2de403751e82,
+		/* XXH3_128 */ 0x034dd917e57539e65e6d2de403751e82,
+	},
+	{ // Length: 074
+		/* XXH32    */ 0x5eea2d63,
+		/* XXH64    */ 0x122d7e563f7ebe53,
+		/* XXH3_64  */ 0x0ef709990ca519ad,
+		/* XXH3_128 */ 0xbaa9b60e6db0beb10ef709990ca519ad,
+	},
+	{ // Length: 075
+		/* XXH32    */ 0x42168423,
+		/* XXH64    */ 0xdfb1b23670a37f6b,
+		/* XXH3_64  */ 0xa57cd051a6e3fcd6,
+		/* XXH3_128 */ 0x8c1779031f464bfaa57cd051a6e3fcd6,
+	},
+	{ // Length: 076
+		/* XXH32    */ 0x1fbd86ce,
+		/* XXH64    */ 0x6d4dc250a2d71dd8,
+		/* XXH3_64  */ 0x8e694e45cd27d5ee,
+		/* XXH3_128 */ 0x4a60c13c5297b3d28e694e45cd27d5ee,
+	},
+	{ // Length: 077
+		/* XXH32    */ 0x230d83c4,
+		/* XXH64    */ 0x767323aa514a4b3e,
+		/* XXH3_64  */ 0x9788dabfa1d2ae77,
+		/* XXH3_128 */ 0xb12256f9dd6658d19788dabfa1d2ae77,
+	},
+	{ // Length: 078
+		/* XXH32    */ 0x02ecfbb3,
+		/* XXH64    */ 0xd02a55fbcdd78515,
+		/* XXH3_64  */ 0x4df4ad960b3e1b74,
+		/* XXH3_128 */ 0x4dc89a9587b5ca614df4ad960b3e1b74,
+	},
+	{ // Length: 079
+		/* XXH32    */ 0x0db8d5a2,
+		/* XXH64    */ 0x4b8cef055d638a36,
+		/* XXH3_64  */ 0xfde0005d51d1cd18,
+		/* XXH3_128 */ 0x3eef8814ff101e2dfde0005d51d1cd18,
+	},
+	{ // Length: 080
+		/* XXH32    */ 0x3a5d2533,
+		/* XXH64    */ 0xee6d208b78ba5eaa,
+		/* XXH3_64  */ 0x86da9cd1ba60ecd5,
+		/* XXH3_128 */ 0x7b86d8edc64b380a86da9cd1ba60ecd5,
+	},
+	{ // Length: 081
+		/* XXH32    */ 0x16e839ff,
+		/* XXH64    */ 0x31e926817a39841b,
+		/* XXH3_64  */ 0x639f20646a1ec336,
+		/* XXH3_128 */ 0xb0aba49cb33917bd639f20646a1ec336,
+	},
+	{ // Length: 082
+		/* XXH32    */ 0x3527a7a1,
+		/* XXH64    */ 0x9ff396b3135b456c,
+		/* XXH3_64  */ 0x7e0d4ea2f9b38895,
+		/* XXH3_128 */ 0xcebcb909f4016fe67e0d4ea2f9b38895,
+	},
+	{ // Length: 083
+		/* XXH32    */ 0x845c1100,
+		/* XXH64    */ 0x5c0413dac1b3b939,
+		/* XXH3_64  */ 0x9d8e9abea0346d85,
+		/* XXH3_128 */ 0x7a1369ae3b804a729d8e9abea0346d85,
+	},
+	{ // Length: 084
+		/* XXH32    */ 0xc8a40881,
+		/* XXH64    */ 0x1498e3f1d1af7e35,
+		/* XXH3_64  */ 0xc7fe7f15eee279d3,
+		/* XXH3_128 */ 0xbaff84a7692e0fbdc7fe7f15eee279d3,
+	},
+	{ // Length: 085
+		/* XXH32    */ 0x8fa79421,
+		/* XXH64    */ 0x4e6fe85182d48a10,
+		/* XXH3_64  */ 0x5a2fa3a17c1a89cd,
+		/* XXH3_128 */ 0x25a39fbcef12385c5a2fa3a17c1a89cd,
+	},
+	{ // Length: 086
+		/* XXH32    */ 0xc24bbaa3,
+		/* XXH64    */ 0x023314074cb17f3a,
+		/* XXH3_64  */ 0xb09cfedc0bdceb69,
+		/* XXH3_128 */ 0x9d41bac9f97f79ebb09cfedc0bdceb69,
+	},
+	{ // Length: 087
+		/* XXH32    */ 0x5da4a679,
+		/* XXH64    */ 0xa5fa1a57f86e2821,
+		/* XXH3_64  */ 0xfe5cf9ae412dffaf,
+		/* XXH3_128 */ 0xf786e12e374037f9fe5cf9ae412dffaf,
+	},
+	{ // Length: 088
+		/* XXH32    */ 0xb24aae1d,
+		/* XXH64    */ 0x90544ddf7f0428eb,
+		/* XXH3_64  */ 0xaf60304232a17df2,
+		/* XXH3_128 */ 0xbba37fa61872a2b5af60304232a17df2,
+	},
+	{ // Length: 089
+		/* XXH32    */ 0xcf249009,
+		/* XXH64    */ 0xfad4f662b43ce68c,
+		/* XXH3_64  */ 0x144a66b7de2cdc59,
+		/* XXH3_128 */ 0x204b02d851f79e07144a66b7de2cdc59,
+	},
+	{ // Length: 090
+		/* XXH32    */ 0xa1ef7a0a,
+		/* XXH64    */ 0xbfc627f903045881,
+		/* XXH3_64  */ 0x5db99259fd39cf12,
+		/* XXH3_128 */ 0xad2649ee51439ed05db99259fd39cf12,
+	},
+	{ // Length: 091
+		/* XXH32    */ 0x8fbf5e70,
+		/* XXH64    */ 0x5f6042db52039ba9,
+		/* XXH3_64  */ 0xb0625b71cf232b75,
+		/* XXH3_128 */ 0x831f9afa91893af8b0625b71cf232b75,
+	},
+	{ // Length: 092
+		/* XXH32    */ 0x0b18dce2,
+		/* XXH64    */ 0x4808152f82cfb223,
+		/* XXH3_64  */ 0xa0d485ba4cedbbb0,
+		/* XXH3_128 */ 0x98dd103807adc772a0d485ba4cedbbb0,
+	},
+	{ // Length: 093
+		/* XXH32    */ 0x48b77989,
+		/* XXH64    */ 0xf3d57b3fcfda5974,
+		/* XXH3_64  */ 0x7416078bf3671262,
+		/* XXH3_128 */ 0xc0802004b52546127416078bf3671262,
+	},
+	{ // Length: 094
+		/* XXH32    */ 0xde6d95c7,
+		/* XXH64    */ 0x5e2157cc7eabc1c6,
+		/* XXH3_64  */ 0x68ca5c51b84de5a0,
+		/* XXH3_128 */ 0x25138b7dd7abb12668ca5c51b84de5a0,
+	},
+	{ // Length: 095
+		/* XXH32    */ 0xc8f599fc,
+		/* XXH64    */ 0x59f913c719e77988,
+		/* XXH3_64  */ 0x1b70b9418b88feb3,
+		/* XXH3_128 */ 0x5c4b7d2ed38ec22b1b70b9418b88feb3,
+	},
+	{ // Length: 096
+		/* XXH32    */ 0xe5511959,
+		/* XXH64    */ 0xc088fb75504a22bf,
+		/* XXH3_64  */ 0xea99cbf87674b914,
+		/* XXH3_128 */ 0x656814aebcb78defea99cbf87674b914,
+	},
+	{ // Length: 097
+		/* XXH32    */ 0x6ef1bc75,
+		/* XXH64    */ 0x2f3a12dcabb0f60b,
+		/* XXH3_64  */ 0xf6cf4c7db61c3b63,
+		/* XXH3_128 */ 0x076178843ca982daf6cf4c7db61c3b63,
+	},
+	{ // Length: 098
+		/* XXH32    */ 0x693455ee,
+		/* XXH64    */ 0x61073071c55be290,
+		/* XXH3_64  */ 0x3a7c052469600378,
+		/* XXH3_128 */ 0x5895e69f6a25a12f3a7c052469600378,
+	},
+	{ // Length: 099
+		/* XXH32    */ 0xbddcbdab,
+		/* XXH64    */ 0x64e2cf15c497f09e,
+		/* XXH3_64  */ 0xceb184f52c2de55a,
+		/* XXH3_128 */ 0x932c158155f9e6feceb184f52c2de55a,
+	},
+	{ // Length: 100
+		/* XXH32    */ 0x85f6413c,
+		/* XXH64    */ 0x17bb1103c92c502f,
+		/* XXH3_64  */ 0x801fedc74ccd608c,
+		/* XXH3_128 */ 0x6ba30a4e9dffe1ff801fedc74ccd608c,
+	},
+	{ // Length: 101
+		/* XXH32    */ 0x3e00a9e1,
+		/* XXH64    */ 0x94bae49d01dd6841,
+		/* XXH3_64  */ 0xef45c44b8d2a4bb3,
+		/* XXH3_128 */ 0x108d2290160fbde5ef45c44b8d2a4bb3,
+	},
+	{ // Length: 102
+		/* XXH32    */ 0xd8cad2f2,
+		/* XXH64    */ 0xa522fdba04591c5c,
+		/* XXH3_64  */ 0x43bad6ee7776646c,
+		/* XXH3_128 */ 0x28add2814bf1b50a43bad6ee7776646c,
+	},
+	{ // Length: 103
+		/* XXH32    */ 0x4351a054,
+		/* XXH64    */ 0x3eab95965ce6036d,
+		/* XXH3_64  */ 0x160e9dd27b46707f,
+		/* XXH3_128 */ 0xed3f08c043d31a4c160e9dd27b46707f,
+	},
+	{ // Length: 104
+		/* XXH32    */ 0xc6a6a0a5,
+		/* XXH64    */ 0x8a60bf2778472f62,
+		/* XXH3_64  */ 0xd007001b1d5ce4ce,
+		/* XXH3_128 */ 0x0da3ff04990e5c4cd007001b1d5ce4ce,
+	},
+	{ // Length: 105
+		/* XXH32    */ 0x21ee1809,
+		/* XXH64    */ 0x048b9ad1ef48d50d,
+		/* XXH3_64  */ 0x1c2a810b353d37b9,
+		/* XXH3_128 */ 0x6eb5f85a9c8517fa1c2a810b353d37b9,
+	},
+	{ // Length: 106
+		/* XXH32    */ 0x86267d98,
+		/* XXH64    */ 0x0c395a48888efdb0,
+		/* XXH3_64  */ 0x86a91b0cf16b0853,
+		/* XXH3_128 */ 0x30f09bbcb65dc2d386a91b0cf16b0853,
+	},
+	{ // Length: 107
+		/* XXH32    */ 0x4ed714f5,
+		/* XXH64    */ 0x88252a27a113aab2,
+		/* XXH3_64  */ 0xbb2c7314b80b3b0f,
+		/* XXH3_128 */ 0x8b0dc57213b412d1bb2c7314b80b3b0f,
+	},
+	{ // Length: 108
+		/* XXH32    */ 0x9ccc5aaf,
+		/* XXH64    */ 0xab889e3f73b95815,
+		/* XXH3_64  */ 0xb4464a4577a7703b,
+		/* XXH3_128 */ 0xa61e8d8a9a1d28edb4464a4577a7703b,
+	},
+	{ // Length: 109
+		/* XXH32    */ 0x4684267d,
+		/* XXH64    */ 0x0b96d1b371e8bcb6,
+		/* XXH3_64  */ 0x5a3466ae106da1ea,
+		/* XXH3_128 */ 0x5f17d6c38980d6ba5a3466ae106da1ea,
+	},
+	{ // Length: 110
+		/* XXH32    */ 0xe4c13f18,
+		/* XXH64    */ 0x2ff4e87f8f22943e,
+		/* XXH3_64  */ 0xb12c30cdf125e930,
+		/* XXH3_128 */ 0x99b21434b5a7e572b12c30cdf125e930,
+	},
+	{ // Length: 111
+		/* XXH32    */ 0x2be83288,
+		/* XXH64    */ 0x51c55aadcba25168,
+		/* XXH3_64  */ 0xf56cc9d314389a72,
+		/* XXH3_128 */ 0x71ee1c0783a5a27ff56cc9d314389a72,
+	},
+	{ // Length: 112
+		/* XXH32    */ 0x48b87b5f,
+		/* XXH64    */ 0x8ff8fc9514e3a9c1,
+		/* XXH3_64  */ 0x0fec69d5d3147a05,
+		/* XXH3_128 */ 0x73eaf72901d9ed150fec69d5d3147a05,
+	},
+	{ // Length: 113
+		/* XXH32    */ 0xdd8dc5c6,
+		/* XXH64    */ 0xd0bde90e5fab3ff4,
+		/* XXH3_64  */ 0x1ee2d5eb5af73a6d,
+		/* XXH3_128 */ 0x2728daf56a27656e1ee2d5eb5af73a6d,
+	},
+	{ // Length: 114
+		/* XXH32    */ 0xc6bd3241,
+		/* XXH64    */ 0x93dafaad6b70ebb1,
+		/* XXH3_64  */ 0xe12e6d65d01446ce,
+		/* XXH3_128 */ 0xca83a46fc1952d34e12e6d65d01446ce,
+	},
+	{ // Length: 115
+		/* XXH32    */ 0x9c22d52e,
+		/* XXH64    */ 0x1efed4ee7669964d,
+		/* XXH3_64  */ 0x9104fa7e8b91d4d9,
+		/* XXH3_128 */ 0xfe60790f05e772a09104fa7e8b91d4d9,
+	},
+	{ // Length: 116
+		/* XXH32    */ 0x57dee509,
+		/* XXH64    */ 0x16d485a88b4bcf72,
+		/* XXH3_64  */ 0x26b7693690da51cc,
+		/* XXH3_128 */ 0xb6e5929dc61edeca26b7693690da51cc,
+	},
+	{ // Length: 117
+		/* XXH32    */ 0x439c6d5a,
+		/* XXH64    */ 0x1c56d46c22d26614,
+		/* XXH3_64  */ 0x261681439278fa2a,
+		/* XXH3_128 */ 0xaecc79bc239ddd8c261681439278fa2a,
+	},
+	{ // Length: 118
+		/* XXH32    */ 0xa4321463,
+		/* XXH64    */ 0x339bb5cb4eb37479,
+		/* XXH3_64  */ 0x671401a2b5c11933,
+		/* XXH3_128 */ 0x82f5a2a329f6bfc9671401a2b5c11933,
+	},
+	{ // Length: 119
+		/* XXH32    */ 0x1c26c847,
+		/* XXH64    */ 0x75cb6763e096d06e,
+		/* XXH3_64  */ 0xc186af0f7a16fd9d,
+		/* XXH3_128 */ 0xa07445e6994d1bcac186af0f7a16fd9d,
+	},
+	{ // Length: 120
+		/* XXH32    */ 0x57f83ca2,
+		/* XXH64    */ 0xebf658eac0cf337f,
+		/* XXH3_64  */ 0xe9315d969bd33352,
+		/* XXH3_128 */ 0x9cc448e2cb631f62e9315d969bd33352,
+	},
+	{ // Length: 121
+		/* XXH32    */ 0x690a6bfb,
+		/* XXH64    */ 0x7c96016aa0ca5a15,
+		/* XXH3_64  */ 0x91981764e4e0c5e7,
+		/* XXH3_128 */ 0x4683322ccd505f6391981764e4e0c5e7,
+	},
+	{ // Length: 122
+		/* XXH32    */ 0xe95bee40,
+		/* XXH64    */ 0xe97713014ba86ea9,
+		/* XXH3_64  */ 0xaf2cfaf73348f2e0,
+		/* XXH3_128 */ 0xf87f9e621cbbbbe1af2cfaf73348f2e0,
+	},
+	{ // Length: 123
+		/* XXH32    */ 0x6af94ee8,
+		/* XXH64    */ 0xbf684d98f7ebd23c,
+		/* XXH3_64  */ 0x39c95d260b45f41e,
+		/* XXH3_128 */ 0xaa9156bbd7e261fe39c95d260b45f41e,
+	},
+	{ // Length: 124
+		/* XXH32    */ 0xe0466841,
+		/* XXH64    */ 0xa3757598b527f803,
+		/* XXH3_64  */ 0xf39844fd2d36922b,
+		/* XXH3_128 */ 0xbea151339b866c53f39844fd2d36922b,
+	},
+	{ // Length: 125
+		/* XXH32    */ 0xceb40858,
+		/* XXH64    */ 0x22ffc5db3a2ccbd7,
+		/* XXH3_64  */ 0x36a8e231daa6c7d4,
+		/* XXH3_128 */ 0x00c7eae03dc718c636a8e231daa6c7d4,
+	},
+	{ // Length: 126
+		/* XXH32    */ 0x5f9d1a2a,
+		/* XXH64    */ 0x3621681b87571af7,
+		/* XXH3_64  */ 0x3133805e2401c842,
+		/* XXH3_128 */ 0x76b10ca5f0f86cfd3133805e2401c842,
+	},
+	{ // Length: 127
+		/* XXH32    */ 0x8ba2a3d9,
+		/* XXH64    */ 0x5108ad5e4adcded4,
+		/* XXH3_64  */ 0x759eea08c3b77cae,
+		/* XXH3_128 */ 0x9a73d42d33690e31759eea08c3b77cae,
+	},
+	{ // Length: 128
+		/* XXH32    */ 0x235fdcd9,
+		/* XXH64    */ 0x6f975641f69e7c17,
+		/* XXH3_64  */ 0x093c29f27ecfcf21,
+		/* XXH3_128 */ 0xd3c4f706d8fc547f093c29f27ecfcf21,
+	},
+	{ // Length: 129
+		/* XXH32    */ 0x59f76c57,
+		/* XXH64    */ 0xfe430696af65c43e,
+		/* XXH3_64  */ 0x37f7943eb2f51359,
+		/* XXH3_128 */ 0x5dc489d54b6d88d4dd4911635f2c7a91,
+	},
+	{ // Length: 130
+		/* XXH32    */ 0xc9ea583d,
+		/* XXH64    */ 0xf04dc1c959ce843f,
+		/* XXH3_64  */ 0x9cc8599ac6e3f7c5,
+		/* XXH3_128 */ 0x685efa3543bffd48fc9462e7ccc9cefa,
+	},
+	{ // Length: 131
+		/* XXH32    */ 0x6640897d,
+		/* XXH64    */ 0xa9ee72c422dbe72b,
+		/* XXH3_64  */ 0x9a3ccf6f257eb24d,
+		/* XXH3_128 */ 0x492e7e0b481f717edd73129e093b3062,
+	},
+	{ // Length: 132
+		/* XXH32    */ 0xb5e4e488,
+		/* XXH64    */ 0xdbe11f0fda7406a3,
+		/* XXH3_64  */ 0xd43b251ce340166a,
+		/* XXH3_128 */ 0x037e8f34cc2427c9c38660776d2f2a1e,
+	},
+	{ // Length: 133
+		/* XXH32    */ 0x19f684db,
+		/* XXH64    */ 0xc66fb07ffb558f1d,
+		/* XXH3_64  */ 0xe1192a918d2cbadc,
+		/* XXH3_128 */ 0x3997439fc9e0a5e7189aaf765938ad8d,
+	},
+	{ // Length: 134
+		/* XXH32    */ 0xa364ea55,
+		/* XXH64    */ 0x521efd4c7ffc6ca7,
+		/* XXH3_64  */ 0x5b6bbbf1e2ac1115,
+		/* XXH3_128 */ 0x99829ba0450827f24067ef3692490da3,
+	},
+	{ // Length: 135
+		/* XXH32    */ 0xa8775ee5,
+		/* XXH64    */ 0x982ef4e1d405e4e3,
+		/* XXH3_64  */ 0x0eaf9d6bd22b59b6,
+		/* XXH3_128 */ 0xaa3c8c56db27785e515b2290fa18d964,
+	},
+	{ // Length: 136
+		/* XXH32    */ 0x418f5fd7,
+		/* XXH64    */ 0xf276d46ddc912f23,
+		/* XXH3_64  */ 0xff7a5eeab4cc6be6,
+		/* XXH3_128 */ 0x348a605c95181223ba2e184e1c95a85b,
+	},
+	{ // Length: 137
+		/* XXH32    */ 0x486e2d96,
+		/* XXH64    */ 0x948c5282231737fb,
+		/* XXH3_64  */ 0x78589a7934760291,
+		/* XXH3_128 */ 0x26848cde8a45b91b614f8f1cc9c170f0,
+	},
+	{ // Length: 138
+		/* XXH32    */ 0xca62b27c,
+		/* XXH64    */ 0x17cc23cf0414188b,
+		/* XXH3_64  */ 0x4fd1b759b0345b1c,
+		/* XXH3_128 */ 0x0813b352081ce8afe0818f80a26baff6,
+	},
+	{ // Length: 139
+		/* XXH32    */ 0xab3c6d45,
+		/* XXH64    */ 0x89d9b42891eb44ec,
+		/* XXH3_64  */ 0x856eb67dcdcf8b7e,
+		/* XXH3_128 */ 0x180a4166130fbfe742f8c49be7888577,
+	},
+	{ // Length: 140
+		/* XXH32    */ 0x766bcb75,
+		/* XXH64    */ 0x8657aa6307fe0e6b,
+		/* XXH3_64  */ 0x4a7595bca3bd79ea,
+		/* XXH3_128 */ 0x4202ee9f9521cfb494160cc1f0e8254f,
+	},
+	{ // Length: 141
+		/* XXH32    */ 0xd6a053a2,
+		/* XXH64    */ 0x848e65140f707d90,
+		/* XXH3_64  */ 0xc6cd66da7b5cecc4,
+		/* XXH3_128 */ 0x256546379feb03cd2566f6009b0137b0,
+	},
+	{ // Length: 142
+		/* XXH32    */ 0xb9758fac,
+		/* XXH64    */ 0xe8a4106b43ca97b8,
+		/* XXH3_64  */ 0xa5076563459b7129,
+		/* XXH3_128 */ 0x920e111d861ea535897f621196b6d067,
+	},
+	{ // Length: 143
+		/* XXH32    */ 0x64997737,
+		/* XXH64    */ 0x07cc592da6070013,
+		/* XXH3_64  */ 0x9b98f7bc164ca797,
+		/* XXH3_128 */ 0x5858ea26b15bd93c543052bb8343c1ee,
+	},
+	{ // Length: 144
+		/* XXH32    */ 0x9ff13c53,
+		/* XXH64    */ 0x3dd18e17e240d3b8,
+		/* XXH3_64  */ 0xdf6dc0a536016fb1,
+		/* XXH3_128 */ 0x4fd039d44b51c58f46fb2985ab4f9b8d,
+	},
+	{ // Length: 145
+		/* XXH32    */ 0xeeaa2e51,
+		/* XXH64    */ 0x2d1db0a92e192d74,
+		/* XXH3_64  */ 0x08b0d4724f9139bf,
+		/* XXH3_128 */ 0x19cf3d17f101d28ad4c32ae653c1cdfe,
+	},
+	{ // Length: 146
+		/* XXH32    */ 0x664e49c8,
+		/* XXH64    */ 0x1fd61543daa9068e,
+		/* XXH3_64  */ 0xfbbede8d95da165b,
+		/* XXH3_128 */ 0x02a973ad8f137e00d9e686cf90cd44bd,
+	},
+	{ // Length: 147
+		/* XXH32    */ 0x1440bea8,
+		/* XXH64    */ 0xb825bf1a2a3c5aa3,
+		/* XXH3_64  */ 0x202cd7f5822c3311,
+		/* XXH3_128 */ 0x5e71cbff35462786f1869e1a479b5bb6,
+	},
+	{ // Length: 148
+		/* XXH32    */ 0x362ed6b2,
+		/* XXH64    */ 0x54230965d949daea,
+		/* XXH3_64  */ 0xb7767cab524fd1dd,
+		/* XXH3_128 */ 0x1f15b8a68eee6ff861034f483573940b,
+	},
+	{ // Length: 149
+		/* XXH32    */ 0x67df83a1,
+		/* XXH64    */ 0xbc54b7c7b40c25a3,
+		/* XXH3_64  */ 0x4ef79c52cf3d61ca,
+		/* XXH3_128 */ 0xd5e6e8e64efa93700f5c439849250ece,
+	},
+	{ // Length: 150
+		/* XXH32    */ 0xcdd29422,
+		/* XXH64    */ 0x33e158a6e41061c1,
+		/* XXH3_64  */ 0x4aafee3be4f45b80,
+		/* XXH3_128 */ 0xe0368389c444fc4a30e72389047a906f,
+	},
+	{ // Length: 151
+		/* XXH32    */ 0x1d92070b,
+		/* XXH64    */ 0x6c9894781e79ddf0,
+		/* XXH3_64  */ 0x49cf7789996453c6,
+		/* XXH3_128 */ 0x7362d99a43ffe8045a3fcfcc52f9f233,
+	},
+	{ // Length: 152
+		/* XXH32    */ 0x255d7630,
+		/* XXH64    */ 0xb78da64779210473,
+		/* XXH3_64  */ 0x972387ed4da3493d,
+		/* XXH3_128 */ 0xb3b98fbb4321709231ff55235bc2f4e0,
+	},
+	{ // Length: 153
+		/* XXH32    */ 0x86ae3314,
+		/* XXH64    */ 0x1cbd814fb4845932,
+		/* XXH3_64  */ 0xe523a2ea621c206c,
+		/* XXH3_128 */ 0xfa907959314e912fcaf905221c403772,
+	},
+	{ // Length: 154
+		/* XXH32    */ 0x720027fb,
+		/* XXH64    */ 0xd22b2245136d3385,
+		/* XXH3_64  */ 0x2c5dd35f964b92d3,
+		/* XXH3_128 */ 0x45ac0d9184c4b51753ce12fb6f47f2c2,
+	},
+	{ // Length: 155
+		/* XXH32    */ 0xa370a549,
+		/* XXH64    */ 0x6016e983cc04af6c,
+		/* XXH3_64  */ 0x8bfa291a67dac814,
+		/* XXH3_128 */ 0x6d4deddb3bc3a7dce480621c78cc3490,
+	},
+	{ // Length: 156
+		/* XXH32    */ 0x35be5d22,
+		/* XXH64    */ 0xea1681fcaf34f7aa,
+		/* XXH3_64  */ 0xb93c5cdbf77eb50f,
+		/* XXH3_128 */ 0x4770c8f3d57e4d9d2b312bb4063a6598,
+	},
+	{ // Length: 157
+		/* XXH32    */ 0xb356caf2,
+		/* XXH64    */ 0x346200640a0c81f4,
+		/* XXH3_64  */ 0xe5fdb29db5aa9a93,
+		/* XXH3_128 */ 0x87b64dd9308113df176d9ee6c34aafb3,
+	},
+	{ // Length: 158
+		/* XXH32    */ 0x693cc0e1,
+		/* XXH64    */ 0x8cb79b52d442024e,
+		/* XXH3_64  */ 0xbbf2ecab82ab44e8,
+		/* XXH3_128 */ 0xb42b8b5f55ae182b02c2aee1a42f7f40,
+	},
+	{ // Length: 159
+		/* XXH32    */ 0x824b222d,
+		/* XXH64    */ 0xff168981a9aa4770,
+		/* XXH3_64  */ 0x540a0a29a74cb611,
+		/* XXH3_128 */ 0x02cbb050925b1a9ecd9b2cce52d50761,
+	},
+	{ // Length: 160
+		/* XXH32    */ 0x0c2e646f,
+		/* XXH64    */ 0xd43db9564ed0c199,
+		/* XXH3_64  */ 0xa6b0123d94516d8c,
+		/* XXH3_128 */ 0xf39c86283933549ed50766ead6050888,
+	},
+	{ // Length: 161
+		/* XXH32    */ 0x29932ed2,
+		/* XXH64    */ 0x09d0991aeff1d413,
+		/* XXH3_64  */ 0xf49f44d598950087,
+		/* XXH3_128 */ 0x568e539bd19499ec347f3757df70bab4,
+	},
+	{ // Length: 162
+		/* XXH32    */ 0x28e16fdf,
+		/* XXH64    */ 0x1c7648283ea2868b,
+		/* XXH3_64  */ 0x2974e2208c2f4c60,
+		/* XXH3_128 */ 0xfac1148d42715d243e070b64803b5d7d,
+	},
+	{ // Length: 163
+		/* XXH32    */ 0x9c6a2562,
+		/* XXH64    */ 0xb3eb5f32000bc872,
+		/* XXH3_64  */ 0xed4c15b25573fd4f,
+		/* XXH3_128 */ 0xd3c9f99a59cd1ca6d76ce8832cdc6622,
+	},
+	{ // Length: 164
+		/* XXH32    */ 0xf6364c80,
+		/* XXH64    */ 0xb76d3f5c3523c866,
+		/* XXH3_64  */ 0xa86d7589aa75895b,
+		/* XXH3_128 */ 0x30b103b976b26b610da758f8d2133544,
+	},
+	{ // Length: 165
+		/* XXH32    */ 0xb9521150,
+		/* XXH64    */ 0x828472e7bca6c667,
+		/* XXH3_64  */ 0x79ff666315d8f122,
+		/* XXH3_128 */ 0x90600e08ca24529c3237ce3d750002e2,
+	},
+	{ // Length: 166
+		/* XXH32    */ 0xebbfb7c5,
+		/* XXH64    */ 0x5aff088b2cdc3347,
+		/* XXH3_64  */ 0xe38cd371110c3749,
+		/* XXH3_128 */ 0xeff5aeebddfbc858ee1343b4b7e86dfd,
+	},
+	{ // Length: 167
+		/* XXH32    */ 0xfd40bca6,
+		/* XXH64    */ 0x18367b1bc927605a,
+		/* XXH3_64  */ 0xc6a09d95e32b6b08,
+		/* XXH3_128 */ 0xb5b4a1a4a7250e89598c7d9700bc1198,
+	},
+	{ // Length: 168
+		/* XXH32    */ 0x4f58474d,
+		/* XXH64    */ 0xdb94a0b687d78f30,
+		/* XXH3_64  */ 0xb2b3f4e0ad83707e,
+		/* XXH3_128 */ 0x452065223af9d08f6fd7a8c78c6efbd5,
+	},
+	{ // Length: 169
+		/* XXH32    */ 0x6443ddbf,
+		/* XXH64    */ 0xa3e81bd48515a05e,
+		/* XXH3_64  */ 0x0cb2f20c98ea8ea1,
+		/* XXH3_128 */ 0xde8c94cb950bab1351c8f9c4e81b8d05,
+	},
+	{ // Length: 170
+		/* XXH32    */ 0x7094738f,
+		/* XXH64    */ 0x91b8588ca9e83f59,
+		/* XXH3_64  */ 0x6af99afba67c6696,
+		/* XXH3_128 */ 0xc1ecf6f2ff00628e2725928f6ee87aa0,
+	},
+	{ // Length: 171
+		/* XXH32    */ 0x19c2b19d,
+		/* XXH64    */ 0x31f4b2ea4b320855,
+		/* XXH3_64  */ 0x19e01472466d0a27,
+		/* XXH3_128 */ 0x1d9c682e78aa17cb2991e06dfad5aa41,
+	},
+	{ // Length: 172
+		/* XXH32    */ 0x6982dd14,
+		/* XXH64    */ 0xd34e15129de9271c,
+		/* XXH3_64  */ 0x458d646bd40f53c3,
+		/* XXH3_128 */ 0xdcf3bda13a881d93eb93ae4caa5a3200,
+	},
+	{ // Length: 173
+		/* XXH32    */ 0xba3136fb,
+		/* XXH64    */ 0x1cbaf30cbd795e74,
+		/* XXH3_64  */ 0x9f5654a3e6948869,
+		/* XXH3_128 */ 0xefaf5383d37d565a9d6e69126a0a1f85,
+	},
+	{ // Length: 174
+		/* XXH32    */ 0xd64c43d8,
+		/* XXH64    */ 0x49ee8c514ed4319b,
+		/* XXH3_64  */ 0x29eed3b9a5abcdf9,
+		/* XXH3_128 */ 0x3a1da941621033566dd0cee17a995c65,
+	},
+	{ // Length: 175
+		/* XXH32    */ 0x31f6ea1f,
+		/* XXH64    */ 0xd3157d3a2e70cfc1,
+		/* XXH3_64  */ 0xde9fd10b908d202d,
+		/* XXH3_128 */ 0x30449046380779ee1d5a46a730ede8d3,
+	},
+	{ // Length: 176
+		/* XXH32    */ 0x491d6907,
+		/* XXH64    */ 0xb2641aba6475ed94,
+		/* XXH3_64  */ 0x8e728904a8c91502,
+		/* XXH3_128 */ 0xe3cc365a6e8693e11650803f9eb10781,
+	},
+	{ // Length: 177
+		/* XXH32    */ 0x2be8376f,
+		/* XXH64    */ 0xec93f856871c107f,
+		/* XXH3_64  */ 0xdc90f00e0e22531a,
+		/* XXH3_128 */ 0x9dfbcef74e95764509a62d325b115a18,
+	},
+	{ // Length: 178
+		/* XXH32    */ 0x6bee79eb,
+		/* XXH64    */ 0xbc8eb3fb1f626529,
+		/* XXH3_64  */ 0xea3e27f6fb361261,
+		/* XXH3_128 */ 0x780439d1b75637a14546ff3519035989,
+	},
+	{ // Length: 179
+		/* XXH32    */ 0xd4428de2,
+		/* XXH64    */ 0x7abc16b8449e4506,
+		/* XXH3_64  */ 0x97c3ac10163e3a37,
+		/* XXH3_128 */ 0xb2903f4a1df1ea81df11797953c2a268,
+	},
+	{ // Length: 180
+		/* XXH32    */ 0xc88a2907,
+		/* XXH64    */ 0x25ce7f9579b49879,
+		/* XXH3_64  */ 0xfcc5d76560909cc6,
+		/* XXH3_128 */ 0xb8793440faac32a664408ab445559556,
+	},
+	{ // Length: 181
+		/* XXH32    */ 0xee75ccc6,
+		/* XXH64    */ 0x62f03803adc4bd62,
+		/* XXH3_64  */ 0x3d4bd91bd52d0f4d,
+		/* XXH3_128 */ 0x3c63b7838d63e63ce9503a772e7713fa,
+	},
+	{ // Length: 182
+		/* XXH32    */ 0xf76aa653,
+		/* XXH64    */ 0xf45c3738849cdbee,
+		/* XXH3_64  */ 0x0ad02f4187dfeb56,
+		/* XXH3_128 */ 0x5642d82e5bb93ceb8f5f3c242c4b0423,
+	},
+	{ // Length: 183
+		/* XXH32    */ 0x372ed946,
+		/* XXH64    */ 0x31814a1b1d29ce5a,
+		/* XXH3_64  */ 0x7a34e4ea4379ddb2,
+		/* XXH3_128 */ 0xe1db34acf24105c6ff70fd535c565464,
+	},
+	{ // Length: 184
+		/* XXH32    */ 0xb097c21f,
+		/* XXH64    */ 0xf682d5802dd2526e,
+		/* XXH3_64  */ 0x1f9142eec9ed4ea9,
+		/* XXH3_128 */ 0x195dc972500caa9597d9866930788fea,
+	},
+	{ // Length: 185
+		/* XXH32    */ 0x4b269bca,
+		/* XXH64    */ 0x72877a65da8e7bbe,
+		/* XXH3_64  */ 0x3ae977674d620994,
+		/* XXH3_128 */ 0x993c172fbdaae41db81ee5525a581b4f,
+	},
+	{ // Length: 186
+		/* XXH32    */ 0x71bc74e8,
+		/* XXH64    */ 0x46a799a017193592,
+		/* XXH3_64  */ 0x41e5198e1d0d6338,
+		/* XXH3_128 */ 0x7db055a773db66c502ee25722586755b,
+	},
+	{ // Length: 187
+		/* XXH32    */ 0xbe46eac0,
+		/* XXH64    */ 0x8bef915997ce75e2,
+		/* XXH3_64  */ 0x2cae690655f49f3f,
+		/* XXH3_128 */ 0x0ec81b9564ded5e4b6f796adc304c40f,
+	},
+	{ // Length: 188
+		/* XXH32    */ 0x00a45d6d,
+		/* XXH64    */ 0x34579f22606353a9,
+		/* XXH3_64  */ 0x4e953d2fbcef2703,
+		/* XXH3_128 */ 0xe183be64bbfaa518bd8df0565849ef46,
+	},
+	{ // Length: 189
+		/* XXH32    */ 0xb746cd7d,
+		/* XXH64    */ 0xdfc0ec0f1b3bc5ba,
+		/* XXH3_64  */ 0x4a51ab4e9c1ba8fd,
+		/* XXH3_128 */ 0xe5db22e7f7397ab463efe055dbd0dab8,
+	},
+	{ // Length: 190
+		/* XXH32    */ 0x57740dad,
+		/* XXH64    */ 0x18b4d98deb55fc20,
+		/* XXH3_64  */ 0x9b94f71a594d317b,
+		/* XXH3_128 */ 0x74001b00f295532370e1166ece7b1725,
+	},
+	{ // Length: 191
+		/* XXH32    */ 0x10159bd9,
+		/* XXH64    */ 0x67df6130ec09aaa9,
+		/* XXH3_64  */ 0x6bf1c5c32ecda797,
+		/* XXH3_128 */ 0xd82ffc88a95c94906b2b648432dc6293,
+	},
+	{ // Length: 192
+		/* XXH32    */ 0xf56cd828,
+		/* XXH64    */ 0x415492578a3b319a,
+		/* XXH3_64  */ 0x0c2722aa3370cd20,
+		/* XXH3_128 */ 0x303ed8fdcd8320296b44b2a2390eb607,
+	},
+	{ // Length: 193
+		/* XXH32    */ 0x1d986f5a,
+		/* XXH64    */ 0xaaa75cc8f4e4ae0c,
+		/* XXH3_64  */ 0x6dde9658f4a427da,
+		/* XXH3_128 */ 0x019920ab07be7820452b329b09eabe45,
+	},
+	{ // Length: 194
+		/* XXH32    */ 0xdc639c7f,
+		/* XXH64    */ 0x1ab6bd70b0eba55c,
+		/* XXH3_64  */ 0xb23401b64be9f0be,
+		/* XXH3_128 */ 0xed00f81f85bf8d6beeefa96fab666328,
+	},
+	{ // Length: 195
+		/* XXH32    */ 0xd0799876,
+		/* XXH64    */ 0x75730cb18448b318,
+		/* XXH3_64  */ 0x0a8c9bbfb9240751,
+		/* XXH3_128 */ 0x95cea555f3f65343c3ed74f1434b27fc,
+	},
+	{ // Length: 196
+		/* XXH32    */ 0x21d39c42,
+		/* XXH64    */ 0x85d9ff76a0567cd7,
+		/* XXH3_64  */ 0x4006c287eff05b6b,
+		/* XXH3_128 */ 0xcb592c6ae71e5ac8456d1d73e774b536,
+	},
+	{ // Length: 197
+		/* XXH32    */ 0x6fb568af,
+		/* XXH64    */ 0xc549dbc4f23af633,
+		/* XXH3_64  */ 0x45ce71b2b709aa6b,
+		/* XXH3_128 */ 0x57a65d0bcf7b43f63ac6211eb7b7caed,
+	},
+	{ // Length: 198
+		/* XXH32    */ 0x84a513ff,
+		/* XXH64    */ 0xf081af872f6eb389,
+		/* XXH3_64  */ 0x066ff1e42b9a93e3,
+		/* XXH3_128 */ 0xd4b5edd49354468cd5003be8e448de88,
+	},
+	{ // Length: 199
+		/* XXH32    */ 0xa5c66eb7,
+		/* XXH64    */ 0xf309c6a6fe37dbdc,
+		/* XXH3_64  */ 0xd305d146fe3e87c2,
+		/* XXH3_128 */ 0x932ca0b640315fbd40e8d28f219892a0,
+	},
+	{ // Length: 200
+		/* XXH32    */ 0xdb1b4d23,
+		/* XXH64    */ 0x7d476f4500ea754f,
+		/* XXH3_64  */ 0x8f8c9188233578c2,
+		/* XXH3_128 */ 0x68ac297d87ba6fb2f24858a3a3e3018f,
+	},
+	{ // Length: 201
+		/* XXH32    */ 0xcc446d03,
+		/* XXH64    */ 0x12d80b9b26155121,
+		/* XXH3_64  */ 0x10fa64ba1a3b8d12,
+		/* XXH3_128 */ 0x00bc071918c029441668ed92d73e17fa,
+	},
+	{ // Length: 202
+		/* XXH32    */ 0x1da33a7d,
+		/* XXH64    */ 0xdb84bea0deded0ae,
+		/* XXH3_64  */ 0x9292c47835f64621,
+		/* XXH3_128 */ 0x4b9a15ab893a00c8fb585adaa3034110,
+	},
+	{ // Length: 203
+		/* XXH32    */ 0xc3cb2f99,
+		/* XXH64    */ 0x343247d585dee2e6,
+		/* XXH3_64  */ 0xf05df894b4d2f00c,
+		/* XXH3_128 */ 0xdfa5126674643405eaa48dc3aabc9984,
+	},
+	{ // Length: 204
+		/* XXH32    */ 0xdc84a58b,
+		/* XXH64    */ 0xceed54572117eec5,
+		/* XXH3_64  */ 0x828875b12ca82d02,
+		/* XXH3_128 */ 0x9e7eff30d9121219b194f1fdf82b4a05,
+	},
+	{ // Length: 205
+		/* XXH32    */ 0x7a1df45c,
+		/* XXH64    */ 0x13961d12f7b36b1c,
+		/* XXH3_64  */ 0x8b5a0ed01f2b292a,
+		/* XXH3_128 */ 0xe818524f817b929ddd08b1afcda0d812,
+	},
+	{ // Length: 206
+		/* XXH32    */ 0x84e914c6,
+		/* XXH64    */ 0x3672b5730978769e,
+		/* XXH3_64  */ 0xd84c2e4f6b2a5dd7,
+		/* XXH3_128 */ 0xd9a6123cec991231a5af87975aed3e1a,
+	},
+	{ // Length: 207
+		/* XXH32    */ 0xc1ec87e0,
+		/* XXH64    */ 0xa058bd322ae3ec97,
+		/* XXH3_64  */ 0xd2c682e80d489879,
+		/* XXH3_128 */ 0x71497b2c425aebd0a980d043f0d1deee,
+	},
+	{ // Length: 208
+		/* XXH32    */ 0x8549f2ed,
+		/* XXH64    */ 0x884d6d31f0481bc3,
+		/* XXH3_64  */ 0x1b9ae23269f7d0cd,
+		/* XXH3_128 */ 0xc10a0c1e6c51ba1e11a68559cb1fa8b7,
+	},
+	{ // Length: 209
+		/* XXH32    */ 0x5c6557bd,
+		/* XXH64    */ 0x9f82565f540beb76,
+		/* XXH3_64  */ 0xeb4f25dfa09e3606,
+		/* XXH3_128 */ 0x78a37664c555d71d4ec40170e112959b,
+	},
+	{ // Length: 210
+		/* XXH32    */ 0x145459d4,
+		/* XXH64    */ 0x5d30dbc4957ab5ad,
+		/* XXH3_64  */ 0x745bf1d793a1ab9f,
+		/* XXH3_128 */ 0x0a9841532aa89740f94f5eb9f0f74234,
+	},
+	{ // Length: 211
+		/* XXH32    */ 0x4d095bc4,
+		/* XXH64    */ 0x85bbe0cdd41de364,
+		/* XXH3_64  */ 0x07d9b5c058b6db67,
+		/* XXH3_128 */ 0x796e919c10a060e801d38e60bb859aba,
+	},
+	{ // Length: 212
+		/* XXH32    */ 0x0e59f0cf,
+		/* XXH64    */ 0x2c4b4d67f3412e68,
+		/* XXH3_64  */ 0x7d60343af4c0e5a1,
+		/* XXH3_128 */ 0x4b8c1c65f7362be22eab64a5f2a6b136,
+	},
+	{ // Length: 213
+		/* XXH32    */ 0xba45f430,
+		/* XXH64    */ 0x58a3dc0500b8832e,
+		/* XXH3_64  */ 0xecaf8b9695f202f2,
+		/* XXH3_128 */ 0x44409e6b0d2c2d762184e68518172b89,
+	},
+	{ // Length: 214
+		/* XXH32    */ 0xcdcb2537,
+		/* XXH64    */ 0x71d6b794f1cf15c9,
+		/* XXH3_64  */ 0x95043c8a342880ae,
+		/* XXH3_128 */ 0x2092729564d825ce573fca7a752b7f08,
+	},
+	{ // Length: 215
+		/* XXH32    */ 0x3d0254f2,
+		/* XXH64    */ 0x0a7f6af44b806ff5,
+		/* XXH3_64  */ 0x1dd7ae9ee7586262,
+		/* XXH3_128 */ 0x941748a650a641217e888877ba5b5e9b,
+	},
+	{ // Length: 216
+		/* XXH32    */ 0x95e95a10,
+		/* XXH64    */ 0xd24830a2f2dbbaad,
+		/* XXH3_64  */ 0xe56d102869a881a2,
+		/* XXH3_128 */ 0xabff4fcfb0bb0bf36fa8801d9a2cdbc2,
+	},
+	{ // Length: 217
+		/* XXH32    */ 0xe3008db5,
+		/* XXH64    */ 0x0195afbbc367becb,
+		/* XXH3_64  */ 0x356829409338e4e1,
+		/* XXH3_128 */ 0x5f0e20e50c78aeeb48f9f1cee644fd15,
+	},
+	{ // Length: 218
+		/* XXH32    */ 0x37b1107f,
+		/* XXH64    */ 0x89194b6d11375f04,
+		/* XXH3_64  */ 0x368213f675c22a3d,
+		/* XXH3_128 */ 0xb482ccf5ef3188a5a0d32efa6425fedc,
+	},
+	{ // Length: 219
+		/* XXH32    */ 0xae5de4be,
+		/* XXH64    */ 0xd39594ba8baa92b7,
+		/* XXH3_64  */ 0x47fbf3c8aafa311e,
+		/* XXH3_128 */ 0xda7987d0d0292071aafb6550a8876863,
+	},
+	{ // Length: 220
+		/* XXH32    */ 0x56803cb3,
+		/* XXH64    */ 0x6a0de24b6a363331,
+		/* XXH3_64  */ 0x324a7573b18eca79,
+		/* XXH3_128 */ 0x19c6cb9ecf1dda6b1b22cd19eedb4cac,
+	},
+	{ // Length: 221
+		/* XXH32    */ 0x9fbd210f,
+		/* XXH64    */ 0xb5f7cce305406c09,
+		/* XXH3_64  */ 0x31433cc8374fd416,
+		/* XXH3_128 */ 0x4cfe6421a3d2c02b2749ad128e9a8482,
+	},
+	{ // Length: 222
+		/* XXH32    */ 0x78ba3030,
+		/* XXH64    */ 0x19e0506f21545893,
+		/* XXH3_64  */ 0xcadeaed200dfe94a,
+		/* XXH3_128 */ 0x2bdba227cfcec8f766f0940e2ac5faca,
+	},
+	{ // Length: 223
+		/* XXH32    */ 0x7c7921cf,
+		/* XXH64    */ 0xc34990a514204fa8,
+		/* XXH3_64  */ 0x122138e40292814d,
+		/* XXH3_128 */ 0x57c09a3d33f27536921019f5108baebf,
+	},
+	{ // Length: 224
+		/* XXH32    */ 0x28e92fb1,
+		/* XXH64    */ 0x4f52b3010a211735,
+		/* XXH3_64  */ 0xbbc9d216f3b3b942,
+		/* XXH3_128 */ 0x979c04f3a93054cd10fcc2ba7467b6b8,
+	},
+	{ // Length: 225
+		/* XXH32    */ 0xa9a1792a,
+		/* XXH64    */ 0xe49e0c434e7d62e9,
+		/* XXH3_64  */ 0xcb805becabd35d43,
+		/* XXH3_128 */ 0x6846c4bfc82b4b419484a80245c6b155,
+	},
+	{ // Length: 226
+		/* XXH32    */ 0x8e9a2fe1,
+		/* XXH64    */ 0x5caa4df779bd7898,
+		/* XXH3_64  */ 0xeda30f45ed222036,
+		/* XXH3_128 */ 0x1cb438e3b8943071ba87433bc1663593,
+	},
+	{ // Length: 227
+		/* XXH32    */ 0x362a7827,
+		/* XXH64    */ 0xc256f7f6d16557b6,
+		/* XXH3_64  */ 0x3bbd102d01e36483,
+		/* XXH3_128 */ 0x70cc10b2a428cfdaf02428bfa3395809,
+	},
+	{ // Length: 228
+		/* XXH32    */ 0x2e914512,
+		/* XXH64    */ 0xf508eeb7c9a95c16,
+		/* XXH3_64  */ 0xd9015c8201c7ee6a,
+		/* XXH3_128 */ 0xc007a5ef48628809841dc869be520f30,
+	},
+	{ // Length: 229
+		/* XXH32    */ 0xa079c84d,
+		/* XXH64    */ 0x1528d0e0e469b8f7,
+		/* XXH3_64  */ 0xc0821653c307de87,
+		/* XXH3_128 */ 0x2535291fea958636480180f20f99156e,
+	},
+	{ // Length: 230
+		/* XXH32    */ 0xccd58159,
+		/* XXH64    */ 0x9872b892cdfe57e2,
+		/* XXH3_64  */ 0x00f1b16f01dc32ea,
+		/* XXH3_128 */ 0xbf5adda0dc7f7b8d496c2b2d6621b908,
+	},
+	{ // Length: 231
+		/* XXH32    */ 0x7b6458e1,
+		/* XXH64    */ 0x437be5c842830c37,
+		/* XXH3_64  */ 0x8fd3b255ddad7420,
+		/* XXH3_128 */ 0x5c9cbc8ce202575644df2a469685ef7e,
+	},
+	{ // Length: 232
+		/* XXH32    */ 0x357a8a04,
+		/* XXH64    */ 0x9068db7d256defd6,
+		/* XXH3_64  */ 0xd214225a9e084f29,
+		/* XXH3_128 */ 0xd5b7f074dc944f688e8dccf07db3c5f7,
+	},
+	{ // Length: 233
+		/* XXH32    */ 0xe66ff742,
+		/* XXH64    */ 0x72d3c097a6674b4d,
+		/* XXH3_64  */ 0x3d6c2fff713c11d6,
+		/* XXH3_128 */ 0xa6276dc611338dd0b2610195e18c3e6c,
+	},
+	{ // Length: 234
+		/* XXH32    */ 0x0451906e,
+		/* XXH64    */ 0x8cd5f0ce9565ac98,
+		/* XXH3_64  */ 0xfd28b043d8795c97,
+		/* XXH3_128 */ 0xeaddd68ac8d1cfbeb62434d13c364be2,
+	},
+	{ // Length: 235
+		/* XXH32    */ 0xcebd0222,
+		/* XXH64    */ 0xd55723b69895a964,
+		/* XXH3_64  */ 0x81f35c50bdabcf0f,
+		/* XXH3_128 */ 0x5010a7296e627d300c5126bf5dfad88e,
+	},
+	{ // Length: 236
+		/* XXH32    */ 0xe27b0e0d,
+		/* XXH64    */ 0x5836388b7e96ab2c,
+		/* XXH3_64  */ 0x282b4d244863533e,
+		/* XXH3_128 */ 0xd055720adb60f81b9076ebc24597a4fc,
+	},
+	{ // Length: 237
+		/* XXH32    */ 0x9d66e6fb,
+		/* XXH64    */ 0xc3c554513a258a6f,
+		/* XXH3_64  */ 0xa6b1815802a2e04e,
+		/* XXH3_128 */ 0x1b22e24c292ec1bab7f7a5bcdd02ac7e,
+	},
+	{ // Length: 238
+		/* XXH32    */ 0xcb44db74,
+		/* XXH64    */ 0x0c062fe9432310e6,
+		/* XXH3_64  */ 0xb980bcafae826b6a,
+		/* XXH3_128 */ 0xd165a0bf9e7c1ff0df5db0fc797b2e5a,
+	},
+	{ // Length: 239
+		/* XXH32    */ 0xc9e2caa3,
+		/* XXH64    */ 0xb5ea2ee9848886e1,
+		/* XXH3_64  */ 0xf01bb3becb264837,
+		/* XXH3_128 */ 0x236b41c213f15a8b7bb3f3aa81e3cf87,
+	},
+	{ // Length: 240
+		/* XXH32    */ 0x4adb057d,
+		/* XXH64    */ 0x3b2f9b86d7a3505d,
+		/* XXH3_64  */ 0x053f07444f70da08,
+		/* XXH3_128 */ 0x0550e1dd88b6c17ca499f0a80fd3850a,
+	},
+	{ // Length: 241
+		/* XXH32    */ 0x1ac49503,
+		/* XXH64    */ 0xce57013ff2e37492,
+		/* XXH3_64  */ 0x5c5b5d5d40c59ce3,
+		/* XXH3_128 */ 0xb9b45065a364c5b95c5b5d5d40c59ce3,
+	},
+	{ // Length: 242
+		/* XXH32    */ 0x9f1308d0,
+		/* XXH64    */ 0xd81331be4be9af89,
+		/* XXH3_64  */ 0xd6197ac30eb7e67b,
+		/* XXH3_128 */ 0x7c2427f7dd163d54d6197ac30eb7e67b,
+	},
+	{ // Length: 243
+		/* XXH32    */ 0x343d523e,
+		/* XXH64    */ 0x85e6707782492f3d,
+		/* XXH3_64  */ 0x6a043c8acf2edfe5,
+		/* XXH3_128 */ 0xd3e478b2f3c7d4d86a043c8acf2edfe5,
+	},
+	{ // Length: 244
+		/* XXH32    */ 0x6b8b6dd5,
+		/* XXH64    */ 0x83fe8b87a7fb2c98,
+		/* XXH3_64  */ 0x83cfeefc38e135af,
+		/* XXH3_128 */ 0x0b9fe6c92758f31483cfeefc38e135af,
+	},
+	{ // Length: 245
+		/* XXH32    */ 0x979fde91,
+		/* XXH64    */ 0xe3af0e29b09f4f5d,
+		/* XXH3_64  */ 0xefe82cfd0523d461,
+		/* XXH3_128 */ 0x4ca024527dbcb172efe82cfd0523d461,
+	},
+	{ // Length: 246
+		/* XXH32    */ 0x2024f5b0,
+		/* XXH64    */ 0xe2de97f426ff9438,
+		/* XXH3_64  */ 0xa6b5634825f07065,
+		/* XXH3_128 */ 0xe7b8eb86fb978789a6b5634825f07065,
+	},
+	{ // Length: 247
+		/* XXH32    */ 0xfc605b7c,
+		/* XXH64    */ 0x04220be8458fc95b,
+		/* XXH3_64  */ 0xc304c990dd8eaed1,
+		/* XXH3_128 */ 0xe3f6b4c2291582b4c304c990dd8eaed1,
+	},
+	{ // Length: 248
+		/* XXH32    */ 0x5e18e4f4,
+		/* XXH64    */ 0x85df5e87c94c4652,
+		/* XXH3_64  */ 0x7d332b897562bdc9,
+		/* XXH3_128 */ 0x8f1e66cfe3dbcc8e7d332b897562bdc9,
+	},
+	{ // Length: 249
+		/* XXH32    */ 0x7dcdb120,
+		/* XXH64    */ 0x9fee450153ce5498,
+		/* XXH3_64  */ 0xaa11cf8277c09b38,
+		/* XXH3_128 */ 0x0a439d5130ea3945aa11cf8277c09b38,
+	},
+	{ // Length: 250
+		/* XXH32    */ 0x00f67f93,
+		/* XXH64    */ 0x867470b86d5d035f,
+		/* XXH3_64  */ 0xcee1243792d92228,
+		/* XXH3_128 */ 0x91f72ad8f463333acee1243792d92228,
+	},
+	{ // Length: 251
+		/* XXH32    */ 0x360c5063,
+		/* XXH64    */ 0xe14ea3ccd8383691,
+		/* XXH3_64  */ 0xaa0cce41abd3d89a,
+		/* XXH3_128 */ 0x4441edea487e9271aa0cce41abd3d89a,
+	},
+	{ // Length: 252
+		/* XXH32    */ 0x44b01a6d,
+		/* XXH64    */ 0x291504a9d94b9db4,
+		/* XXH3_64  */ 0x8635a5bc4489c202,
+		/* XXH3_128 */ 0x2a95959774e5d11b8635a5bc4489c202,
+	},
+	{ // Length: 253
+		/* XXH32    */ 0xec5d3ed9,
+		/* XXH64    */ 0x77c6f933875e932e,
+		/* XXH3_64  */ 0xdeea51b5cdb93095,
+		/* XXH3_128 */ 0xfa53878500f99304deea51b5cdb93095,
+	},
+	{ // Length: 254
+		/* XXH32    */ 0xf7b6bc24,
+		/* XXH64    */ 0x71f6067ea032ad8f,
+		/* XXH3_64  */ 0x3c71094b804016fa,
+		/* XXH3_128 */ 0xd213563f26d5ffc13c71094b804016fa,
+	},
+	{ // Length: 255
+		/* XXH32    */ 0x769746c1,
+		/* XXH64    */ 0x5baf79c705ca1e7b,
+		/* XXH3_64  */ 0xe2da45c7400ad882,
+		/* XXH3_128 */ 0xeba01432c5dcf325e2da45c7400ad882,
+	},
+	{ // Length: 256
+		/* XXH32    */ 0xcea24005,
+		/* XXH64    */ 0x34c0d99cf5a71a60,
+		/* XXH3_64  */ 0xa68dfbb1d75c6e8d,
+		/* XXH3_128 */ 0xbb039d71e9630a91a68dfbb1d75c6e8d,
+	},
+}