Fixes for 64-bit usz
This commit is contained in:
parent
4fb6ce602f
commit
c94d51dcaf
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user