Fixes for 64-bit usz

This commit is contained in:
Marshall Lochbaum 2023-11-13 08:24:51 -05:00
parent 4fb6ce602f
commit c94d51dcaf
4 changed files with 20 additions and 17 deletions

View File

@ -331,7 +331,7 @@ B indexOf_c2(B t, B w, B x) {
return r;
}
#if SINGELI
if (we==xe && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm2(&w,wia,&x,xia))))) {
if (we==xe && wia<=INT32_MAX && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm2(&w,wia,&x,xia))))) {
i32* rp; B r = m_i32arrc(&rp, x);
if (si_indexOf_c2_hash[we-el_i32](rp, tyany_ptr(w), wia, tyany_ptr(x), xia)) {
decG(w); decG(x); return reduceI32Width(r, wia);
@ -508,8 +508,8 @@ B count_c2(B t, B w, B x) {
goto el8or16;
} else {
#if SINGELI
if (we==xe && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm2(&w,wia,&x,xia)))) &&
si_count_c2_hash[we-el_i32](rp, tyany_ptr(w), wia, tyany_ptr(x), xia, wnext)) {
if (we==xe && wia<=INT32_MAX && (we==el_i32 || (we==el_f64 && (split || canCompare64_norm2(&w,wia,&x,xia)))) &&
si_count_c2_hash[we-el_i32](rp, tyany_ptr(w), wia, tyany_ptr(x), xia, (u32*)wnext)) {
goto dec_nwx;
}
#endif

View File

@ -76,7 +76,7 @@ def hash_alloc{logsz, msz, ext, Ts, v0s, has_radix, ordered} = {
k0 := h>>sh
if (ordered) { k = max{k0, k+1} } # k0 can't be less than k
else { k = k0; while (hash->k!=h0) ++k }
cc += cast_i{usz, k-k0}
cc += cast_i{ux, k-k0}
hash <-{k} h
def move{p,v0} = {
v := p->j; if (not same{v0,'any'}) p <-{j} v0; p <-{k} v

View File

@ -337,9 +337,11 @@ oper &- ({v:T,m} => v & -promote{T,m}) infix left 35
def rty{name} = if (to_prim{name}=='∊') i8 else i32
def ity{name} = (to_prim{name}=='⊒')**(*u32)
fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{name}) = {
def wt = width{T}
fn hashtab{T, name}(rp:*rty{name}, iv:*void, mi:usz, fv:*void, ni:usz, links:ity{name}) = {
def prim = to_prim{name}
def U = if (prim=='∊') usz else u32
m := cast_i{U,mi}; n := cast_i{U,ni}
def wt = width{T}
ip := *T~~iv; fp := *T~~fv
def swap_sides{} = each{{a,b}=>{t:=a; a=b; b=t}, tup{ip,m}, tup{fp,n}}
swap:u1 = n+(1024*(prim!='⊒')) < (if (prim!='∊') m else m-m/4)
@ -351,12 +353,12 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
msz := usz~~1 << msl
# Starting log-size (try_vec_memb requires size>4)
sl := msl; if (msl>=14) sl = 12+(msl&1)
b:usz = 64 # Block size
b:U = 64 # Block size
# Filling e slots past the end requires e*(e+1)/2 collisions, so
# m entries with <2 each can fill <sqrt(4*m)
def cc_stop = 2*m
ext := tern{m<=b, max{m,usz~~4}, b + (usz~~1 << (log/2 + 1))}
def cc_stop = 2*cast_i{u64,m}
ext := promote{usz, tern{m<=b, max{m,U~~4}, b + (U~~1 << (log/2 + 1))}}
maxh := T~~maxvalue{T}
def aux = prim!='∊'
def {tabs, sz, sh, div_thresh, hash_resize, hash_free} = hash_alloc{
@ -365,9 +367,9 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
def {hash,...vals} = tabs
def abort = makelabel{}
i:usz = 0 # Saved to determine if hashing finished
i:U = 0 # Saved to determine if hashing finished
def insert_all{set_tab, set_maxh, dup, ...uniq} = {
cc:usz = 0 # Collision counter
cc:u64 = 0 # Collision counter
while (i < m) {
e := tern{m-i>b, i+b, m}
while (i < e) {
@ -387,7 +389,7 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
each{store{.,je-c,.}, tabs, kv}
each{=, kv, knv}
} while (k != maxh)
cc += cast_i{usz, je-j0}
cc += cast_i{u64, je-j0}
}
each{{u} => { u += promote{usz,h!=maxh} }, uniq}
store{hash, j, h}
@ -474,7 +476,7 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
def prog_lookup{swap} = { # Progressive Index-of lookup
def rev{a,b} = if (swap) tup{b,a} else tup{a,b}
memset{*u32~~rp, ...rev{m,n}}
c:usz = m; def shortcut = makelabel{}
c := m; def shortcut = makelabel{}
@for (fp over i to n) {
h := hash_val{fp}; j := h>>sh
k := load{hash,j}

View File

@ -8,7 +8,8 @@ fn selfhashtab{T, name}(rp:*rty{name}, xp:*T, n:usz) = {
def wt = width{T}
def prim = to_prim{name}
def has_radix = if (prim=='⊐') 0 else wt==32
def {res0,cc_stop} = if (prim=='∊') tup{1,n>>has_radix} else tup{0,2*n}
n64 := promote{u64,n}
def {res0,cc_stop} = if (prim=='∊') tup{1,n64>>has_radix} else tup{0,2*n64}
log := clzc{n}
# Max size
@ -50,20 +51,20 @@ fn selfhashtab{T, name}(rp:*rty{name}, xp:*T, n:usz) = {
}
def break=makelabel{}
cc:usz = 0 # Collision counter
cc:u64 = 0 # Collision counter
i:usz=1; while (1) {
e := tern{n-i>b, i+b, n}
while (i < e) {
h := hash_val{xp->i}; j0 := h>>sh; j := j0
k:=undefined{T}; while (((k=hash->j)!=h) & (k!=x0)) ++j
cc += cast_i{usz, j-j0}
cc += cast_i{u64, j-j0}
rp <-{i} write_res{j,h,k,x0}
++i
}
if (i == n) goto{break}
# Check collision counter and possibly resize
def p64 = promote{u64,.}
dc := p64{cc} - p64{div_thresh{i}}
dc := cc - p64{div_thresh{i}}
if (i64~~dc >= 0) {
if (sz == msz) goto{break} # Abort
if (has_radix and i < n/2 and sz >= 1<<18) goto{break}