xxHash 0.8.2
Extremely fast non-cryptographic hash function
|
Macros | |
#define | XXH_RESTRICT /* disable */ |
#define | XXH_likely(x) (x) |
#define | XXH_unlikely(x) (x) |
#define | XXH_HAS_INCLUDE(x) 0 |
#define | XXH_SEC_ALIGN XXH_ACC_ALIGN |
#define | XXH_ALIASING /* nothing */ |
#define | XXH_VSX_BE 0 |
#define | ACCRND(acc, offset) |
#define | XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ |
#define | XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ |
#define | XXH3_MIDSIZE_MAX 240 |
#define | XXH_STRIPE_LEN 64 |
#define | XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ |
#define | XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64)) |
#define | XXH_PREFETCH_DIST 512 |
#define | XXH3_ACCUMULATE_TEMPLATE(name) |
#define | XXH3_accumulate_512 XXH3_accumulate_512_avx512 |
#define | XXH3_accumulate XXH3_accumulate_avx512 |
#define | XXH3_scrambleAcc XXH3_scrambleAcc_avx512 |
#define | XXH3_initCustomSecret XXH3_initCustomSecret_avx512 |
#define | XXH3_INIT_ACC |
#define | XXH3_STREAM_USE_STACK 1 |
#define | XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) |
Typedefs | |
typedef uint64x2_t xxh_aliasing_uint64x2_t | XXH_ALIASING |
typedef __vector unsigned long long | xxh_u64x2 |
typedef __vector unsigned char | xxh_u8x16 |
typedef __vector unsigned | xxh_u32x4 |
typedef long long | xxh_i64 |
typedef void(* | XXH3_f_accumulate) (xxh_u64 *restrict, const xxh_u8 *restrict, const xxh_u8 *restrict, size_t) |
typedef void(* | XXH3_f_scrambleAcc) (void *restrict, const void *) |
typedef void(* | XXH3_f_initCustomSecret) (void *restrict, xxh_u64) |
typedef XXH64_hash_t(* | XXH3_hashLong64_f) (const void *restrict, size_t, XXH64_hash_t, const xxh_u8 *restrict, size_t) |
typedef XXH128_hash_t(* | XXH3_hashLong128_f) (const void *restrict, size_t, XXH64_hash_t, const void *restrict, size_t) |
Functions | |
XXH_STATIC_ASSERT (XXH_STRIPE_LEN==sizeof(__m512i)) | |
for (i=0;i< XXH_STRIPE_LEN/sizeof(__m256i);i++) | |
XXH_ASSERT ((((size_t) acc) &(XXH_ACC_ALIGN-1))==0) | |
XXH_ASSERT (lane< XXH_ACC_NB) | |
XXH3_WITH_SECRET_INLINE XXH64_hash_t | XXH3_hashLong_64b_withSecret (const void *restrict input, size_t len, XXH64_hash_t seed64, const xxh_u8 *restrict secret, size_t secretLen) |
XXH64_hash_t | XXH3_64bits_withSecretandSeed (XXH_NOESCAPE const void *data, size_t len, XXH_NOESCAPE const void *secret, size_t secretSize, XXH64_hash_t seed) |
XXH3_WITH_SECRET_INLINE XXH128_hash_t | XXH3_hashLong_128b_withSecret (const void *restrict input, size_t len, XXH64_hash_t seed64, const void *restrict secret, size_t secretLen) |
Variables | |
static XXH_TARGET_AVX512 const void *restrict | secret |
const __m512i | prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1) |
__m512i const | acc_vec = *xacc |
__m512i const | shifted = _mm512_srli_epi64 (acc_vec, 47) |
__m512i const | key_vec = _mm512_loadu_si512 (secret) |
__m512i const | data_key = _mm512_ternarylogic_epi32(key_vec, acc_vec, shifted, 0x96 ) |
__m512i const | data_key_hi = _mm512_srli_epi64 (data_key, 32) |
__m512i const | prod_lo = _mm512_mul_epu32 (data_key, prime32) |
__m512i const | prod_hi = _mm512_mul_epu32 (data_key_hi, prime32) |
* | xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)) |
const __m256i *const | xsecret = (const __m256i *) secret |
size_t | i |
uint32x2_t const | kPrimeLo = vdup_n_u32(XXH_PRIME32_1) |
uint32x4_t const | kPrimeHi = vreinterpretq_u32_u64(vdupq_n_u64((xxh_u64)XXH_PRIME32_1 << 32)) |
xxh_u64x2 const | v32 = { 32, 32 } |
xxh_u64x2 const | v47 = { 47, 47 } |
xxh_u32x4 const | prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 } |
static void const *restrict size_t | lane |
xxh_u64 | acc64 = xacc[lane] |
#define ACCRND | ( | acc, | |
offset | |||
) |
#define XXH3_ACCUMULATE_TEMPLATE | ( | name | ) |
#define XXH3_INIT_ACC |
XXH64_hash_t XXH3_64bits_withSecretandSeed | ( | XXH_NOESCAPE const void * | data, |
size_t | len, | ||
XXH_NOESCAPE const void * | secret, | ||
size_t | secretSize, | ||
XXH64_hash_t | seed | ||
) |
These variants generate hash values using either seed
for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) or secret
for "large" keys (>= XXH3_MIDSIZE_MAX).
This generally benefits speed, compared to _withSeed()
or _withSecret()
. _withSeed()
has to generate the secret on the fly for "large" keys. It's fast, but can be perceptible for "not so large" keys (< 1 KB). _withSecret()
has to generate the masks on the fly for "small" keys, which requires more instructions than _withSeed() variants. Therefore, _withSecretandSeed variant combines the best of both worlds.
When secret
has been generated by XXH3_generateSecret_fromSeed(), this variant produces exactly the same results as _withSeed()
variant, hence offering only a pure speed benefit on "large" input, by skipping the need to regenerate the secret for every large input.
Another usage scenario is to hash the secret to a 64-bit hash value, for example with XXH3_64bits(), which then becomes the seed, and then employ both the seed and the secret in _withSecretandSeed(). On top of speed, an added benefit is that each bit in the secret has a 50% chance to swap each bit in the output, via its impact to the seed.
This is not guaranteed when using the secret directly in "small data" scenarios, because only portions of the secret are employed for small data.
static void const *restrict secret |
void const* restrict size_t lane |