Reverse hashed Index-of
This commit is contained in:
parent
f1485ca98c
commit
2c625127d5
@ -251,7 +251,7 @@ B indexOf_c2(B t, B w, B x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CHECK_CHRS_ELSE { tyEls: // Both numbers
|
CHECK_CHRS_ELSE { tyEls: // Both numbers
|
||||||
if (wia>32 && xia<=(we<=el_i8?1:6)) {
|
if (wia>32 && xia<=(we<=el_i8?1:3)) {
|
||||||
SGetU(x);
|
SGetU(x);
|
||||||
B r;
|
B r;
|
||||||
#define IND(T) \
|
#define IND(T) \
|
||||||
@ -283,7 +283,7 @@ B indexOf_c2(B t, B w, B x) {
|
|||||||
decG(w); decG(x); return r;
|
decG(w); decG(x); return r;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (wia<=(we<=el_i16?4:16) && xia>16) {
|
if (wia<=4 && xia>16) {
|
||||||
SGetU(w);
|
SGetU(w);
|
||||||
#define XEQ(I) C2(ne, GetU(w,I), incG(x))
|
#define XEQ(I) C2(ne, GetU(w,I), incG(x))
|
||||||
B r = XEQ(wia-1);
|
B r = XEQ(wia-1);
|
||||||
|
|||||||
@ -342,8 +342,8 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
|
|||||||
def prim = to_prim{name}
|
def prim = to_prim{name}
|
||||||
ip := *T~~iv; fp := *T~~fv
|
ip := *T~~iv; fp := *T~~fv
|
||||||
def swap_sides{} = each{{a,b}=>{t:=a; a=b; b=t}, tup{ip,m}, tup{fp,n}}
|
def swap_sides{} = each{{a,b}=>{t:=a; a=b; b=t}, tup{ip,m}, tup{fp,n}}
|
||||||
swap:u1 = 0
|
swap:u1 = n+(1024*(prim!='⊒')) < (if (prim!='∊') m else m-m/4)
|
||||||
if ((prim=='⊒' or prim=='∊') and (swap = n < m)) swap_sides{}
|
if (swap) swap_sides{}
|
||||||
def stop = m
|
def stop = m
|
||||||
|
|
||||||
log := clzc{m}
|
log := clzc{m}
|
||||||
@ -439,6 +439,24 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
def ind_rev_lookup{uniq, has_maxh} = {
|
||||||
|
def shortcut = makelabel{}
|
||||||
|
@for (ip over i to m) {
|
||||||
|
h := hash_val{ip}; j := h>>sh
|
||||||
|
k := load{hash,j}
|
||||||
|
if (k <= h) {
|
||||||
|
while (k < h) { ++j; k = load{hash,j} }
|
||||||
|
def had_maxh{} = { s:=has_maxh; has_maxh=0; s }
|
||||||
|
if (k == h and (h<maxh or had_maxh{})) {
|
||||||
|
def {inds} = vals
|
||||||
|
store{rp, load{inds, j}, i}
|
||||||
|
--uniq; if (uniq==0) goto{shortcut}
|
||||||
|
hash_remove{j,h}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setlabel{shortcut}
|
||||||
|
}
|
||||||
def prog_lookup{swap} = { # Progressive Index-of lookup
|
def prog_lookup{swap} = { # Progressive Index-of lookup
|
||||||
def rev{a,b} = if (swap) tup{b,a} else tup{a,b}
|
def rev{a,b} = if (swap) tup{b,a} else tup{a,b}
|
||||||
memset{*u32~~rp, ...rev{m,n}}
|
memset{*u32~~rp, ...rev{m,n}}
|
||||||
@ -491,7 +509,7 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
|
|||||||
lookup_all{{found, j} => promote{i8, swap ^ (found & (j<end))}}
|
lookup_all{{found, j} => promote{i8, swap ^ (found & (j<end))}}
|
||||||
}
|
}
|
||||||
|
|
||||||
{('⊐'), inds} => {
|
{('⊐'), inds} => if (not swap) {
|
||||||
has_maxh:u1 = 0
|
has_maxh:u1 = 0
|
||||||
ind_maxh:u32 = 0
|
ind_maxh:u32 = 0
|
||||||
def dup = makelabel{}
|
def dup = makelabel{}
|
||||||
@ -509,6 +527,43 @@ fn hashtab{T, name}(rp:*rty{name}, iv:*void, m:usz, fv:*void, n:usz, links:ity{n
|
|||||||
store{inds, end, ind_maxh}
|
store{inds, end, ind_maxh}
|
||||||
}
|
}
|
||||||
lookup_all{{found, j} => i32~~(m - (load{inds, j} &- found))}
|
lookup_all{{found, j} => i32~~(m - (load{inds, j} &- found))}
|
||||||
|
} else { # swap
|
||||||
|
# After insert_all, position i in rp contains:
|
||||||
|
# - ≠𝕨, if i is the first occurrence of its value in 𝕩, or
|
||||||
|
# - j-≠𝕩, where j<i is the index of the first occurrence
|
||||||
|
uniq:usz = 0
|
||||||
|
ind_maxh:usz = m
|
||||||
|
ri:i32 = 0 # Placed in rp (should be scoped to insert_all loop body)
|
||||||
|
def dup = makelabel{}; def skip_dup = makelabel{}
|
||||||
|
def set_maxh{found, i} = {
|
||||||
|
ri = cast_i{i32, n} # Initialize to not-found
|
||||||
|
if (found) {
|
||||||
|
if (ind_maxh==m) ind_maxh = i
|
||||||
|
else ri = i32~~(ind_maxh - m)
|
||||||
|
goto{skip_dup}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def set{j,je,kr} = {
|
||||||
|
store{inds, j, i}
|
||||||
|
if (u1~~0) {
|
||||||
|
setlabel{dup}
|
||||||
|
ri = i32~~(load{inds, j} - m)
|
||||||
|
setlabel{skip_dup}
|
||||||
|
}
|
||||||
|
store{rp, i, ri}
|
||||||
|
}
|
||||||
|
insert_all{set, set_maxh, dup, uniq}
|
||||||
|
has_maxh := ind_maxh < m
|
||||||
|
# Lookup places correct result index at each first occurrence
|
||||||
|
swap_sides{}; i=m
|
||||||
|
if (has_maxh) {
|
||||||
|
++uniq
|
||||||
|
end := maxh>>sh; while (load{hash,end}!=maxh) ++end
|
||||||
|
store{inds, end, ind_maxh}
|
||||||
|
}
|
||||||
|
ind_rev_lookup{uniq, has_maxh}
|
||||||
|
# Propagate to later occurrences
|
||||||
|
@for (r in rp over i to n) r = load{rp, min{i, u32~~r+n}}
|
||||||
}
|
}
|
||||||
|
|
||||||
{('⊒'), inds, link} => {
|
{('⊒'), inds, link} => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user