From 2c625127d559fbc8cfef2bf63775eac9a44f7066 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 9 Nov 2023 10:39:03 -0500 Subject: [PATCH] Reverse hashed Index-of --- src/builtins/search.c | 4 +-- src/singeli/src/search.singeli | 61 ++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/builtins/search.c b/src/builtins/search.c index 191f2b0c..a1eaf467 100644 --- a/src/builtins/search.c +++ b/src/builtins/search.c @@ -251,7 +251,7 @@ B indexOf_c2(B t, B w, B x) { } 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); B r; #define IND(T) \ @@ -283,7 +283,7 @@ B indexOf_c2(B t, B w, B x) { decG(w); decG(x); return r; } #endif - if (wia<=(we<=el_i16?4:16) && xia>16) { + if (wia<=4 && xia>16) { SGetU(w); #define XEQ(I) C2(ne, GetU(w,I), incG(x)) B r = XEQ(wia-1); diff --git a/src/singeli/src/search.singeli b/src/singeli/src/search.singeli index cb065b20..a2649a33 100644 --- a/src/singeli/src/search.singeli +++ b/src/singeli/src/search.singeli @@ -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} 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 = 0 - if ((prim=='⊒' or prim=='∊') and (swap = n < m)) swap_sides{} + swap:u1 = n+(1024*(prim!='⊒')) < (if (prim!='∊') m else m-m/4) + if (swap) swap_sides{} def stop = 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 promote{i8, swap ^ (found & (j { + {('⊐'), inds} => if (not swap) { has_maxh:u1 = 0 ind_maxh:u32 = 0 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} } 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>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} => {