#include "../core.h" #include "../utils/hash.h" #include "../utils/mut.h" #include "../utils/talloc.h" B memberOf_c1(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0"); if (RNK(x)!=1) x = toCells(x); usz xia = IA(x); u8 xe = TI(x,elType); #define LOOKUP(T) \ usz tn = 1<=16 && xe==el_i8) { LOOKUP(8); } if (xia>=256 && xe==el_i16) { LOOKUP(16); } #undef LOOKUP // Radix-assisted lookup if (xia>=256 && xe==el_i32) { usz rx = 256, tn = 1<<16; // Radix; table length usz n = xia; u32* v0 = (u32*)i32any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); TALLOC(u8, alloc, 9*n+(tn+2*rx*sizeof(usz))); // Allocations count radix hash deradix usz *c0 = (usz*)(alloc); // rx X-----------------X usz *c1 = (usz*)(c0+rx); // rx X-----------------X u8 *k0 = (u8 *)(c1+rx); // n X-----------------X u8 *k1 = (u8 *)(k0+n); // --/----------X u32 *v1 = (u32*)(k1); // n X-X u32 *v2 = (u32*)(v1+n); // n X----------X u8 *r2 = (u8 *)(k1+n); u8 *r1 = (u8 *)(r2+n); u8 *tab= (u8 *)(v2+n); // tn // Count keys for (usz j=0; j<2*rx; j++) c0[j] = 0; for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } // Exclusive prefix sum usz s0=0, s1=0; for (usz j=0; j>24); usz c=c0[k]++; v1[c]=v; } for (usz i=0; i>16); usz c=c1[k]++; v2[c]=v; } // Table lookup for (usz j=0; j>16; usz e=0; for (usz i=0; i>16; // Clear table when top bytes change if (RARE(tv!=t0)) { for (; e1) x = toCells(x); usz xia = IA(x); u8 xe = TI(x,elType); #define LOOKUP(T) \ usz tn = 1<=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } if (xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP i32* rp; B r = m_i32arrv(&rp, xia); H_b2i* map = m_b2i(64); SGetU(x) for (usz i = 0; i < xia; i++) { bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); rp[i] = had? ++map->a[p].val : (map->a[p].val = 0); } decG(x); free_b2i(map); return r; } extern B rt_indexOf; B indexOf_c1(B t, B x) { if (isAtm(x)) thrM("⊐: 𝕩 cannot have rank 0"); usz xia = IA(x); if (xia==0) { decG(x); return emptyIVec(); } u8 xe = TI(x,elType); #define LOOKUP(T) \ usz tn = 1<=16 && xe==el_i8 && xia<=(usz)I32_MAX+1) { LOOKUP(8); } if (RNK(x)==1 && xia>=256 && xe==el_i16 && xia<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP if (RNK(x)==1 && xe==el_i32) { i32* xp = i32any_ptr(x); i32 min=I32_MAX, max=I32_MIN; for (usz i = 0; i < xia; i++) { i32 c = xp[i]; if (cmax) max = c; } i64 dst = 1 + (max-(i64)min); if ((dsta[p].val; else rp[i] = map->a[p].val = ctr++; } free_b2i(map); decG(x); // u64 e = nsTime(); q1+= e-s; return r; } return c1(rt_indexOf, x); } extern B rt_find; B find_c1(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM("⍷: Argument cannot have rank 0"); usz xia = IA(x); B xf = getFillQ(x); if (RNK(x)!=1) return c1(rt_find, x); B r = emptyHVec(); H_Sb* set = m_Sb(64); SGetU(x) for (usz i = 0; i < xia; i++) { B c = GetU(x,i); if (!ins_Sb(&set, c)) r = vec_add(r, inc(c)); } free_Sb(set); decG(x); return withFill(r, xf); }