GCS  0.2.3
Macros
gu_fnv.h File Reference
#include "gu_int128.h"
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <assert.h>

Go to the source code of this file.

Macros

#define GU_FNV32_PRIME   16777619UL
 
#define GU_FNV32_SEED   2166136261UL
 
#define GU_FNV32_MUL(_x)   _x *= GU_FNV32_PRIME
 
#define GU_FNV32_ITERATION(_s, _b)   _s ^= _b; GU_FNV32_MUL(_s);
 
#define GU_FNV64_PRIME   1099511628211ULL
 
#define GU_FNV64_SEED   14695981039346656037ULL
 
#define GU_FNV64_MUL(_x)   _x *= GU_FNV64_PRIME
 
#define GU_FNV64_ITERATION(_s, _b)   _s ^= _b; GU_FNV64_MUL(_s);
 
#define GU_FNV128_XOR(_s, _b)   (_s).u32[GU_32LO] ^= _b
 
#define GU_FNV128_MUL(_x)
 
#define GU_FNV128_ITERATION(_s, _b)   GU_FNV128_XOR(_s,_b); GU_FNV128_MUL(_s);
 

Detailed Description

This header file defines FNV hash functions for 3 hash sizes: 4, 8 and 16 bytes.

Be wary of bitshift multiplication "optimization" (FNV_BITSHIFT_OPTIMIZATION): FNV authors used to claim marginal speedup when using it, however on core2 CPU it has shown no speedup for fnv32a and more than 2x slowdown for fnv64a and fnv128a. Disabled by default.

FNV vs. FNVa: FNVa has a better distribution: multiplication happens after XOR and hence propagates XOR effect to all bytes of the hash. Hence by default functions perform FNVa. GU_FNV_NORMAL macro is needed for unit tests.

gu_fnv*_internal() functions are endian-unsafe, their output should be converted to little-endian format if it is to be exported to other machines.

Macro Definition Documentation

#define GU_FNV128_MUL (   _x)
Value:
{ \
uint32_t carry = \
(((_x).u64[GU_64LO] & 0x00000000ffffffffULL) * 0x013b) >> 32; \
carry = (((_x).u64[GU_64LO] >> 32) * 0x013b + carry) >> 32; \
(_x).u64[GU_64HI] *= 0x013b; \
(_x).u64[GU_64HI] += ((_x).u64[GU_64LO] << 24) + carry; \
(_x).u64[GU_64LO] *= 0x013b; \
}