From fd33df04a3cd373680a3952f1fed70e9d4a8fe1d Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Sat, 21 Oct 2023 18:03:05 -0500 Subject: [PATCH] Update wyhash to 4.2 --- libfuse/include/linux_dirent64.h | 3 +- src/wyhash.h | 83 ++++++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/libfuse/include/linux_dirent64.h b/libfuse/include/linux_dirent64.h index 7550e746..efeba0d2 100644 --- a/libfuse/include/linux_dirent64.h +++ b/libfuse/include/linux_dirent64.h @@ -1,8 +1,9 @@ #pragma once #include +#include -#define DIRENT_NAMELEN(X) ((X)->reclen - offsetof(linux_dirent64_t,name)) +#define DIRENT_NAMELEN(X) (strlen((X)->name)) typedef struct linux_dirent64_t linux_dirent64_t; struct linux_dirent64_t diff --git a/src/wyhash.h b/src/wyhash.h index 7df33d4d..43c0e4c6 100644 --- a/src/wyhash.h +++ b/src/wyhash.h @@ -8,8 +8,8 @@ uint64_t hash=wyhash(s.c_str(), s.size(), 0, _wyp); */ -#ifndef wyhash_final_version_4 -#define wyhash_final_version_4 +#ifndef wyhash_final_version_4_2 +#define wyhash_final_version_4_2 #ifndef WYHASH_CONDOM //protections that produce different results: @@ -21,7 +21,7 @@ #ifndef WYHASH_32BIT_MUM //0: normal version, slow on 32 bit systems //1: faster on 32 bit systems but produces different results, incompatible with wy2u0k function -#define WYHASH_32BIT_MUM 0 +#define WYHASH_32BIT_MUM 0 #endif //includes @@ -52,7 +52,7 @@ static inline void _wymum(uint64_t *A, uint64_t *B){ *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll; #endif #elif defined(__SIZEOF_INT128__) - __uint128_t r=*A; r*=*B; + __uint128_t r=*A; r*=*B; #if(WYHASH_CONDOM>1) *A^=(uint64_t)r; *B^=(uint64_t)(r>>64); #else @@ -123,15 +123,15 @@ static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const else a=b=0; } else{ - size_t i=len; - if(_unlikely_(i>48)){ + size_t i=len; + if(_unlikely_(i>=48)){ uint64_t see1=seed, see2=seed; do{ seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed); see1=_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^see1); see2=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see2); p+=48; i-=48; - }while(_likely_(i>48)); + }while(_likely_(i>=48)); seed^=see1^see2; } while(_unlikely_(i>16)){ seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed); i-=16; p+=16; } @@ -142,13 +142,13 @@ static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const } //the default secret parameters -static const uint64_t _wyp[4] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull}; +static const uint64_t _wyp[4] = {0x2d358dccaa6c78a5ull, 0x8bb84b93962eacc9ull, 0x4b33a62ed433d4a3ull, 0x4d5a2da51de1aa47ull}; //a useful 64bit-64bit mix function to produce deterministic pseudo random numbers that can pass BigCrush and PractRand -static inline uint64_t wyhash64(uint64_t A, uint64_t B){ A^=0xa0761d6478bd642full; B^=0xe7037ed1a0b428dbull; _wymum(&A,&B); return _wymix(A^0xa0761d6478bd642full,B^0xe7037ed1a0b428dbull);} +static inline uint64_t wyhash64(uint64_t A, uint64_t B){ A^=0x2d358dccaa6c78a5ull; B^=0x8bb84b93962eacc9ull; _wymum(&A,&B); return _wymix(A^0x2d358dccaa6c78a5ull,B^0x8bb84b93962eacc9ull);} //The wyrand PRNG that pass BigCrush and PractRand -static inline uint64_t wyrand(uint64_t *seed){ *seed+=0xa0761d6478bd642full; return _wymix(*seed,*seed^0xe7037ed1a0b428dbull);} +static inline uint64_t wyrand(uint64_t *seed){ *seed+=0x2d358dccaa6c78a5ull; return _wymix(*seed,*seed^0x8bb84b93962eacc9ull);} //convert any 64 bit pseudo random numbers to uniform distribution [0,1). It can be combined with wyrand, wyhash64 or wyhash. static inline double wy2u01(uint64_t r){ const double _wynorm=1.0/(1ull<<52); return (r>>12)*_wynorm;} @@ -173,6 +173,68 @@ static inline uint64_t wytrand(uint64_t *seed){ static inline uint64_t wy2u0k(uint64_t r, uint64_t k){ _wymum(&r,&k); return k; } #endif +// modified from https://github.com/going-digital/Prime64 +static inline unsigned long long mul_mod(unsigned long long a, unsigned long long b, unsigned long long m) { + unsigned long long r=0; + while (b) { + if (b & 1) { + unsigned long long r2 = r + a; + if (r2 < r) r2 -= m; + r = r2 % m; + } + b >>= 1; + if (b) { + unsigned long long a2 = a + a; + if (a2 < a) a2 -= m; + a = a2 % m; + } + } + return r; +} +static inline unsigned long long pow_mod(unsigned long long a, unsigned long long b, unsigned long long m) { + unsigned long long r=1; + while (b) { + if (b&1) r=mul_mod(r,a,m); + b>>=1; + if (b) a=mul_mod(a,a,m); + } + return r; +} +static inline unsigned sprp(unsigned long long n, unsigned long long a) { + unsigned long long d=n-1; + unsigned char s=0; + while (!(d & 0xff)) { d>>=8; s+=8; } + if (!(d & 0xf)) { d>>=4; s+=4; } + if (!(d & 0x3)) { d>>=2; s+=2; } + if (!(d & 0x1)) { d>>=1; s+=1; } + unsigned long long b=pow_mod(a,d,n); + if ((b==1) || (b==(n-1))) return 1; + unsigned char r; + for (r=1; r