#if !defined __MULTILINEARPRIMESTRINGHASHFUNCTOR_COMMON_H__
#define __MULTILINEARPRIMESTRINGHASHFUNCTOR_COMMON_H__
#define __MULTILINEARPRIMESTRINGHASHFUNCTOR_COMMON_H__REVISION_ "$Rev: 460 $"
#if defined(_MSC_VER)
#include "stdint.h"
#else
#include "stdint.h"
#ifndef UINT64_C
#define UINT64_C(x) (x##LLU)
#endif
#endif
#ifdef _MSC_VER
#define _LIKELY_BRANCH_( X ) (X)
#else
#define _LIKELY_BRANCH_( X ) __builtin_expect( (X), 1 )
#endif
#if _MSC_VER
#define ALIGN(n) __declspec(align(n))
#define NOINLINE __declspec(noinline)
#define FORCE_INLINE __forceinline
#elif __GNUC__
#define NOINLINE __attribute__ ((noinline))
#define FORCE_INLINE inline __attribute__((always_inline))
#define ALIGN(n) __attribute__ ((aligned(n)))
#else
#define FORCE_INLINE inline
#define NOINLINE
#warning ALIGN, FORCE_INLINE and NOINLINE may not be properly defined
#endif
#define UInt32x32To64(a, b) ((uint64_t)(((uint64_t)((uint32_t)(a))) * ((uint32_t)(b))))
#if !defined NULL
#define NULL 0
#endif
class UniformRandomNumberGenerator
{
public:
virtual uint32_t rand() = 0;
};
typedef union _ULARGE_INTEGER__XX
{
struct {
uint32_t LowPart;
uint32_t HighPart;
};
struct {
uint32_t LowPart;
uint32_t HighPart;
} u;
uint64_t QuadPart;
} ULARGE_INTEGER__XX;
typedef union _LARGE_INTEGER__XX {
struct {
uint32_t LowPart;
int32_t HighPart;
};
struct {
uint32_t LowPart;
int32_t HighPart;
} u;
int64_t QuadPart;
} LARGE_INTEGER__XX;
typedef struct _ULARGELARGE_INTEGER__XX
{
uint64_t LowPart;
uint64_t HighPart;
} ULARGELARGE_INTEGER__XX;
#ifdef __arm__
typedef struct { uint32_t value __attribute__((__packed__)); } unaligned_uint32;
typedef struct { uint64_t value __attribute__((__packed__)); } unaligned_uint64;
#else
typedef struct { uint32_t value; } unaligned_uint32;
typedef struct { uint64_t value; } unaligned_uint64;
#endif
#include <functional>
using namespace std;
inline
unsigned int fmix32_short ( unsigned int h )
{
h ^= h >> 13;
h *= 0xab3be54f;
h ^= h >> 16;
return h;
}
inline
uint64_t fmix64_short ( uint64_t k )
{
k ^= k >> 33;
k *= UINT64_C( 0xc4ceb9fe1a85ec53 );
k ^= k >> 33;
return k;
}
#if !(defined __arm__ || defined __aarch64__)
#define PMPML_USE_SSE
#ifdef PMPML_USE_SSE
#define PMPML_USE_SSE_SIZE 128
#if PMPML_USE_SSE_SIZE == 128
#include <emmintrin.h>
#elif PMPML_USE_SSE_SIZE == 256
#include <immintrin.h>
#endif #endif #endif
#define PMPML_MAIN_PRIME UINT64_C(4294967311)
#define POW_2_64_MOD_PMPML_MAIN_PRIME UINT64_C(225)
#define PMPML_MAXMULKEY_VALUE_32 0xfffffff2
#define IS_VALID_COEFFICIENT_LEVEL_0( x ) ( (x) > 0 )
#define IS_VALID_COEFFICIENT_LEVEL_1PLUS( x ) ( ( (x) > 0 ) && ( (x) <= PMPML_MAXMULKEY_VALUE_32 ) )
#define IS_VALID_COEFFICIENT( x, level ) ( (level) > 0 ? IS_VALID_COEFFICIENT_LEVEL_1PLUS( (x) ) : IS_VALID_COEFFICIENT_LEVEL_0( (x) ) )
#define PMPML_CHUNK_SIZE 128
#define PMPML_CHUNK_SIZE_LOG2 7
#define PMPML_WORD_SIZE_BYTES 4
#define PMPML_CHUNK_SIZE_BYTES ( PMPML_CHUNK_SIZE * PMPML_WORD_SIZE_BYTES )
#define PMPML_WORD_SIZE_BYTES_LOG2 2
#define PMPML_CHUNK_SIZE_BYTES_LOG2 ( PMPML_CHUNK_SIZE_LOG2 + PMPML_WORD_SIZE_BYTES_LOG2 )
#define PMPML_LEVELS 8
typedef struct _random_data_for_MPSHF
{
uint64_t const_term;
uint64_t cachedSum;
#ifdef PMPML_USE_SSE
#if PMPML_USE_SSE_SIZE == 128
ALIGN(16) uint32_t random_coeff[ PMPML_CHUNK_SIZE ];
#elif PMPML_USE_SSE_SIZE == 256
uint64_t dummy[2];
ALIGN(32) uint32_t random_coeff[ PMPML_CHUNK_SIZE ];
#else
#error unsupported PMPML_USE_SSE_SIZE value
#endif
#else
uint32_t random_coeff[ PMPML_CHUNK_SIZE ];
#endif
} random_data_for_MPSHF;
extern const random_data_for_MPSHF rd_for_MPSHF[ PMPML_LEVELS ];
#ifndef __clang__
#define PMPML_CHUNK_LOOP_USE_TWO_ACCUMULATORS_64
#endif
#if (defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64)) \
&& defined(__AVX2__)
# define PMPML_CHUNK_OPTIMIZATION_TYPE_64 1
# define PMPML_USE_SSE_64
#endif
#define PMPML_MAIN_PRIME_64 UINT64_C(13)
#define POW_2_128_MOD_PMPML_MAIN_PRIME_64 UINT64_C(169)
#define PMPML_MAXMULKEY_VALUE_64 UINT64_C( 0xFFFFFFFFFFFFFFF4 )
#define IS_VALID_COEFFICIENT_LEVEL_0_64( x ) ( (x) > 0 )
#define IS_VALID_COEFFICIENT_LEVEL_1PLUS_64( x ) ( ( (x) > 0 ) && ( (x) <= PMPML_MAXMULKEY_VALUE_64 ) )
#define IS_VALID_COEFFICIENT_64( x, level ) ( (level) > 0 ? IS_VALID_COEFFICIENT_LEVEL_1PLUS_64( (x) ) : IS_VALID_COEFFICIENT_LEVEL_0_64( (x) ) )
#define PMPML_CHUNK_SIZE_64 128
#define PMPML_CHUNK_SIZE_LOG2_64 7
#define PMPML_WORD_SIZE_BYTES_64 8
#define PMPML_CHUNK_SIZE_BYTES_64 ( PMPML_CHUNK_SIZE_64 * PMPML_WORD_SIZE_BYTES_64 )
#define PMPML_WORD_SIZE_BYTES_LOG2_64 3
#define PMPML_CHUNK_SIZE_BYTES_LOG2_64 ( PMPML_CHUNK_SIZE_LOG2_64 + PMPML_WORD_SIZE_BYTES_LOG2_64 )
#define PMPML_LEVELS_64 8
typedef struct _random_data_for_PMPML_64
{
uint64_t const_term;
uint64_t cachedSumLow;
uint64_t cachedSumHigh;
uint64_t dummy;
#ifdef PMPML_USE_SSE_64
ALIGN(32) uint64_t random_coeff[ PMPML_CHUNK_SIZE_64 ];
#else
uint64_t random_coeff[ PMPML_CHUNK_SIZE_64 ];
#endif
} random_data_for_PMPML_64;
extern const random_data_for_PMPML_64 rd_for_PMPML_64[ PMPML_LEVELS_64 ];
#endif