bqn_hash refactor
This commit is contained in:
parent
0164e4e0bc
commit
782750fd88
@ -2,6 +2,48 @@
|
||||
#include "hash.h"
|
||||
#include "time.h"
|
||||
|
||||
NOINLINE u64 bqn_hashArr(B x, const u64 secret[4]) { // TODO manual separation of atom & arr probably won't be worth it when there are actually sane typed array hashing things
|
||||
usz xia = a(x)->ia;
|
||||
if (xia==0) return ~secret[3]; // otherwise squeeze will care about fills
|
||||
x = any_squeeze(inc(x));
|
||||
u8 xr = rnk(x);
|
||||
u8 xe = TI(x,elType);
|
||||
u64 shHash;
|
||||
if (xr<=1) shHash = wyhash64(xia, xe);
|
||||
else shHash = wyhash(a(x)->sh, xr*sizeof(usz), xe, secret);
|
||||
bool isTemp = false;
|
||||
void* data;
|
||||
u64 bytes;
|
||||
switch(xe) { default: UD;
|
||||
case el_bit: bcl(x,xia); data = bitarr_ptr(x); bytes = BIT_N(xia); break;
|
||||
case el_i8: case el_c8: data = tyany_ptr(x); bytes = xia*1; break;
|
||||
case el_i16: case el_c16: data = tyany_ptr(x); bytes = xia*2; break;
|
||||
case el_i32: case el_c32: data = tyany_ptr(x); bytes = xia*4; break;
|
||||
case el_f64: data = f64any_ptr(x); bytes = xia*8; break;
|
||||
case el_B:;
|
||||
TALLOC(u64, dataTmp, xia);
|
||||
isTemp = true;
|
||||
SGetU(x)
|
||||
for (usz i = 0; i < xia; i++) dataTmp[i] = bqn_hash(GetU(x, i), secret);
|
||||
data = dataTmp;
|
||||
bytes = xia*sizeof(B);
|
||||
break;
|
||||
}
|
||||
u64 r = wyhash(data, bytes, shHash, secret);
|
||||
if (isTemp) TFREE(data);
|
||||
dec(x);
|
||||
return r;
|
||||
}
|
||||
|
||||
NOINLINE u64 bqn_hash(B x, const u64 secret[4]) {
|
||||
if (isArr(x)) return bqn_hashArr(x, secret);
|
||||
if (q_f64(x)) return wyhash64(secret[0], x.u);
|
||||
if (isC32(x)) return wyhash64(secret[1], x.u);
|
||||
assert(isVal(x));
|
||||
return wyhash64(secret[2], x.u);
|
||||
}
|
||||
|
||||
|
||||
u64 wy_secret[4];
|
||||
|
||||
void hash_init() {
|
||||
|
||||
@ -10,38 +10,8 @@ static void bcl(B x, usz ia) { // clean up bitarr tail bits to zero
|
||||
xp[ia>>6]&= (1ULL<<(ia&63)) - 1;
|
||||
}
|
||||
}
|
||||
static u64 bqn_hash(B x, const u64 secret[4]) { // doesn't consume
|
||||
if (isAtm(x)) {
|
||||
if (q_f64(x)) return wyhash64(secret[0], x.u);
|
||||
if (isC32(x)) return wyhash64(secret[1], x.u);
|
||||
assert(isVal(x));
|
||||
return wyhash64(secret[2], x.u);
|
||||
}
|
||||
inc(x);
|
||||
x = any_squeeze(x);
|
||||
u64 shHash = wyhash(a(x)->sh, rnk(x)*sizeof(usz), 0, secret);
|
||||
u8 xe = TI(x,elType);
|
||||
usz xia = a(x)->ia;
|
||||
u64 r;
|
||||
if (xe==el_bit) { bcl(x,xia); r = wyhash(bitarr_ptr(x), BIT_N(xia), shHash, secret); }
|
||||
else if (xe==el_i8 ) { r = wyhash(i8any_ptr (x), xia*1, shHash, secret); }
|
||||
else if (xe==el_i16) { r = wyhash(i16any_ptr(x), xia*2, shHash, secret); }
|
||||
else if (xe==el_i32) { r = wyhash(i32any_ptr(x), xia*4, shHash, secret); }
|
||||
else if (xe==el_c8 ) { r = wyhash(c8any_ptr (x), xia*1, shHash, secret); }
|
||||
else if (xe==el_c16) { r = wyhash(c16any_ptr(x), xia*2, shHash, secret); }
|
||||
else if (xe==el_c32) { r = wyhash(c32any_ptr(x), xia*4, shHash, secret); }
|
||||
else if (xe==el_f64) { r = wyhash(f64any_ptr(x), xia*8, shHash, secret); }
|
||||
else {
|
||||
assert(xe==el_B);
|
||||
TALLOC(u64, data, xia);
|
||||
SGetU(x)
|
||||
for (usz i = 0; i < xia; i++) data[i] = bqn_hash(GetU(x, i), secret);
|
||||
r = wyhash(data, xia*8, shHash, secret);
|
||||
TFREE(data);
|
||||
}
|
||||
dec(x);
|
||||
return r;
|
||||
}
|
||||
|
||||
u64 bqn_hash(B x, const u64 secret[4]); // doesn't consume
|
||||
|
||||
static u64 bqn_hashP(B x, const u64 secret[4]) { // bqn_hash but never zero
|
||||
u64 r = bqn_hash(x, secret);
|
||||
|
||||
@ -115,7 +115,7 @@ static inline uint64_t _wyr4(const uint8_t *p) {
|
||||
#endif
|
||||
static inline uint64_t _wyr3(const uint8_t *p, size_t k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];}
|
||||
//wyhash main function
|
||||
static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const uint64_t *secret){
|
||||
FORCE_INLINE uint64_t wyhash(const void *key, size_t len, uint64_t seed, const uint64_t *secret){
|
||||
const uint8_t *p=(const uint8_t *)key; seed^=*secret; uint64_t a, b;
|
||||
if(_likely_(len<=16)){
|
||||
if(_likely_(len>=4)){ a=(_wyr4(p)<<32)|_wyr4(p+((len>>3)<<2)); b=(_wyr4(p+len-4)<<32)|_wyr4(p+len-4-((len>>3)<<2)); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user