From d873ce0d81f5a572d01a5b6d3585401e2820c1bf Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 19 Dec 2021 14:55:21 +0200 Subject: [PATCH] fix hash for bitarrs --- src/builtins/fns.c | 4 ++-- src/h.h | 2 +- src/utils/hash.h | 9 ++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 226bfcd7..1db05c95 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -223,7 +223,7 @@ B indexOf_c2(B t, B w, B x) { } else if (rnk(x)==1) { usz wia = a(w)->ia; usz xia = a(x)->ia; - // TODO O(wia×xia) for small wia + // TODO O(wia×xia) for small wia or xia i32* rp; B r = m_i32arrv(&rp, xia); H_b2i* map = m_b2i(64); SGetU(x) @@ -257,7 +257,7 @@ B memberOf_c2(B t, B w, B x) { if (!isArr(w) || rnk(w)!=1 || !isArr(x) || rnk(x)!=1) return c2(rt_memberOf, w, x); usz wia = a(w)->ia; usz xia = a(x)->ia; - // TODO O(wia×xia) for small wia + // TODO O(wia×xia) for small wia or xia H_Sb* set = m_Sb(64); bool had; SGetU(x) diff --git a/src/h.h b/src/h.h index 14700d59..b767e7be 100644 --- a/src/h.h +++ b/src/h.h @@ -233,7 +233,7 @@ enum ElType { // a⌈b shall return the type that can store both, if possible typedef struct Value { i32 refc; // plain old reference count u8 mmInfo; // bucket size, mark&sweep bits when that's needed - u8 flags; // self-hosted primitive index for callable, fl_* flags for arrays + u8 flags; // self-hosted primitive index (plus 1) for callable, fl_* flags for arrays u8 type; // used by TI, among generally knowing what type of object this is ur extra; // whatever object-specific stuff. Rank for arrays, internal id for functions #ifdef OBJ_COUNTER diff --git a/src/utils/hash.h b/src/utils/hash.h index 09c13605..23248e02 100644 --- a/src/utils/hash.h +++ b/src/utils/hash.h @@ -4,6 +4,12 @@ extern u64 wy_secret[4]; +static void bcl(B x, usz ia) { // clean up bitarr tail bits to zero + if (ia&63) { + u64* xp = bitarr_ptr(x); + 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); @@ -17,7 +23,8 @@ static u64 bqn_hash(B x, const u64 secret[4]) { // doesn't consume u8 xe = TI(x,elType); usz xia = a(x)->ia; u64 r; - if (xe==el_i8 ) { r = wyhash(i8any_ptr (x), xia*1, shHash, secret); } + 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); }