Eliminate a loop when resizing ordered hash
This commit is contained in:
parent
3a50cda5d3
commit
b404c7c1d1
@ -35,7 +35,7 @@ def hash_val{x:u32 & hasarch{'SSE4.2'}} = {
|
|||||||
# Allocate and initialize resizing hash table
|
# Allocate and initialize resizing hash table
|
||||||
# Initial size sz+ext and maximum size msz+ext
|
# Initial size sz+ext and maximum size msz+ext
|
||||||
# One region for each type in Ts initialized with value from v0s
|
# One region for each type in Ts initialized with value from v0s
|
||||||
def hash_alloc{logsz, msz, ext, Ts, v0s} = {
|
def hash_alloc{logsz, msz, ext, Ts, v0s, ordered} = {
|
||||||
def ws = each{width,Ts}
|
def ws = each{width,Ts}
|
||||||
each{assert, slice{ws,0,-1} >= slice{ws,1}} # Doesn't do alignment
|
each{assert, slice{ws,0,-1} >= slice{ws,1}} # Doesn't do alignment
|
||||||
# Variables updated on resize
|
# Variables updated on resize
|
||||||
@ -56,15 +56,16 @@ def hash_alloc{logsz, msz, ext, Ts, v0s} = {
|
|||||||
def hash_resize{cc, m} = {
|
def hash_resize{cc, m} = {
|
||||||
dif := sz*((1<<m)-1)
|
dif := sz*((1<<m)-1)
|
||||||
sh -= m; sz <<= m
|
sh -= m; sz <<= m
|
||||||
j:usz = 0
|
|
||||||
cc = 0
|
cc = 0
|
||||||
|
k:tupsel{0,Ts} = 0; --k
|
||||||
each{{p,v} => { p -= dif; memset{p, v, dif} }, ptrs, v0s}
|
each{{p,v} => { p -= dif; memset{p, v, dif} }, ptrs, v0s}
|
||||||
def {hash, ...vals} = ptrs; def {h0, ...v0r} = v0s
|
def {hash, ...vals} = ptrs; def {h0, ...v0r} = v0s
|
||||||
@for (j from dif to sz + ext) {
|
@for (h in hash over j from dif to sz + ext) {
|
||||||
h := hash->j
|
|
||||||
if (h != h0) {
|
if (h != h0) {
|
||||||
hash <-{j} h0
|
hash <-{j} h0
|
||||||
k0 := h>>sh; k := k0; while (hash->k!=h0) ++k
|
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{usz, k-k0}
|
||||||
hash <-{k} h
|
hash <-{k} h
|
||||||
def move{p,v0} = {
|
def move{p,v0} = {
|
||||||
|
|||||||
@ -360,7 +360,7 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
|
|||||||
maxh := T~~maxvalue{T}
|
maxh := T~~maxvalue{T}
|
||||||
def aux = prim!='∊'
|
def aux = prim!='∊'
|
||||||
def {tabs, sz, sh, hash_resize, hash_free} = hash_alloc{
|
def {tabs, sz, sh, hash_resize, hash_free} = hash_alloc{
|
||||||
sl, msz, ext, tup{T, ...aux**u32}, tup{maxh, ...aux**'any'}
|
sl, msz, ext, tup{T, ...aux**u32}, tup{maxh, ...aux**'any'}, 1
|
||||||
}
|
}
|
||||||
def {hash,...vals} = tabs
|
def {hash,...vals} = tabs
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ fn selfhashtab{T, name}(rp:*rty{name}, xp:*T, n:usz) = {
|
|||||||
rp <-{0} res0
|
rp <-{0} res0
|
||||||
def aux = prim!='∊'
|
def aux = prim!='∊'
|
||||||
def {{hash,...vals}, sz, sh, hash_resize, hash_free} = hash_alloc{
|
def {{hash,...vals}, sz, sh, hash_resize, hash_free} = hash_alloc{
|
||||||
sl, msz, ext, tup{T, ...aux**u32}, tup{x0, ...aux**0}
|
sl, msz, ext, tup{T, ...aux**u32}, tup{x0, ...aux**0}, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Resize or abort if more than 1/2^thresh collisions/element
|
# Resize or abort if more than 1/2^thresh collisions/element
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user