Extend table-based membership to Index-of

This commit is contained in:
Marshall Lochbaum 2022-10-20 22:05:40 -04:00
parent 0cb5e4ee10
commit d9519eb6e1

View File

@ -3,6 +3,28 @@
#include "../utils/mut.h"
#include "../utils/talloc.h"
#define TABLE(IN, FOR, TY, INIT, SET) \
usz it = 1<<(8*elWidth(IN##e)); /* Range of writes */ \
usz ft = 1<<(8*elWidth(FOR##e)); /* Range of lookups */ \
usz t = it>ft? it : ft; /* Table allocation width */ \
TY* rp; B r = m_##TY##arrc(&rp, FOR); \
TALLOC(TY, tab0, t); TY* tab = tab0 + t/2; \
usz m=IN##ia, n=FOR##ia; \
void* ip = tyany_ptr(IN); \
void* fp = tyany_ptr(FOR); \
/* Initialize */ \
if (FOR##e==el_i16 && n<ft/64) \
{ for (usz i=0; i<n; i++) tab[((i16*)fp)[i]]=INIT; } \
else { for (i64 i=0; i<ft; i++) tab[i-ft/2]=INIT; } \
/* Set */ \
if (IN##e==el_i8) { for (usz i=m; i--; ) tab[((i8 *)ip)[i]]=SET; } \
else { for (usz i=m; i--; ) tab[((i16*)ip)[i]]=SET; } \
decG(IN); \
/* Lookup */ \
if (FOR##e==el_i8){ for (usz i=0; i<n; i++) rp[i]=tab[((i8 *)fp)[i]]; } \
else { for (usz i=0; i<n; i++) rp[i]=tab[((i16*)fp)[i]]; } \
decG(FOR); TFREE(tab0);
extern B rt_indexOf;
B indexOf_c2(B t, B w, B x) {
if (!isArr(w) || RNK(w)==0) thrM("⊐: 𝕨 must have rank at least 1");
@ -31,9 +53,13 @@ B indexOf_c2(B t, B w, B x) {
rp[0] = res;
return taga(r);
} else {
usz wia = IA(w);
usz xia = IA(x);
u8 we = TI(w,elType); usz wia = IA(w);
u8 xe = TI(x,elType); usz xia = IA(x);
// TODO O(wia×xia) for small wia or xia
if (xia+wia>20 && we<=el_i16 && xe<=el_i16 && we!=el_bit && xe!=el_bit) {
TABLE(w, x, i32, wia, i)
return r;
}
i32* rp; B r = m_i32arrc(&rp, x);
H_b2i* map = m_b2i(64);
SGetU(x)
@ -102,25 +128,7 @@ B memberOf_c2(B t, B w, B x) {
#undef WEQ
// TODO O(wia×xia) for small wia
if (xia+wia>20 && we<=el_i16 && xe<=el_i16 && we!=el_bit) {
usz xt = 1<<(8*elWidth(xe)); // Range of x writes
usz wt = 1<<(8*elWidth(we)); // Range of w lookups
usz t = xt>wt? xt : wt; // Table allocation width
void* wp = tyany_ptr(w);
void* xp = tyany_ptr(x);
usz m=wia, n=xia;
i8* rp; B r = m_i8arrv(&rp, m);
TALLOC(u8, tab0, t); u8* tab = tab0 + t/2;
// Initialize
if (we==el_i16 && m<wt/64) { for (usz i=0; i<m; i++) tab[((i16*)wp)[i]]=0; }
else { for (i64 i=0; i<wt; i++) tab[i-wt/2]=0; }
// Set
if (xe==el_i8) { for (usz i=0; i<n; i++) tab[((i8 *)xp)[i]]=1; }
else { for (usz i=0; i<n; i++) tab[((i16*)xp)[i]]=1; }
decG(x);
// Lookup
if (we==el_i8) { for (usz i=0; i<m; i++) rp[i]=tab[((i8 *)wp)[i]]; }
else { for (usz i=0; i<m; i++) rp[i]=tab[((i16*)wp)[i]]; }
decG(w); TFREE(tab0);
TABLE(x, w, i8, 0, 1)
return num_squeeze(r);
}
H_Sb* set = m_Sb(64);