#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"); usz n = *SH(x); if (n==0) { decG(x); return emptyIVec(); } if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); #define BRUTE(T) \ i##T* xp = i##T##any_ptr(x); \ u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \ for (usz i=1; i=256) { LOOKUP(16); } // Radix-assisted lookup usz rx = 256, tn = 256; // Radix; table length u16* v0 = (u16*)i16any_ptr(x); i8* r0; B r = m_i8arrv(&r0, n); TALLOC(u8, alloc, 4*n+(tn+rx)); u8 *c0 = alloc; u8 *k0 = c0+rx; u16 *v1 = (u16*)(k0+n); u8 *r1 = (u8*)(v1+n); u8 *tab= r1+n; // Count keys for (usz j=0; j>8)]++; // Exclusive prefix sum usz s=0; for (usz j=0; j>8); usz c=c0[k]++; v1[c]=v; } // Table lookup for (usz j=0; j>8; for (usz i=0, e=0; i>8; if (tv!=t0) { for (; e=256 && xe==el_i32) { usz rx = 256, tn = 1<<16; // Radix; table length 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); u8 xe = TI(x,elType); #define LOOKUP(T) \ usz tn = 1<=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP i32* rp; B r = m_i32arrv(&rp, n); H_b2i* map = m_b2i(64); SGetU(x) for (usz i = 0; i < n; 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) || RNK(x)==0) thrM("⊐: 𝕩 cannot have rank 0"); usz n = *SH(x); if (n==0) { decG(x); return emptyIVec(); } if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); #define LOOKUP(T) \ usz tn = 1<=16 && xe==el_i8 && n<=(usz)I32_MAX+1) { LOOKUP(8); } if (n>=256 && xe==el_i16 && n<=(usz)I32_MAX+1) { LOOKUP(16); } #undef LOOKUP if (xe==el_i32) { i32* xp = i32any_ptr(x); i32 min=I32_MAX, max=I32_MIN; for (usz i = 0; i < n; 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); return r; } extern B rt_find; B find_c1(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM("⍷: Argument cannot have rank 0"); usz n = *SH(x); if (n<=1) return x; if (RNK(x)>1) return c1(rt_find, x); B xf = getFillQ(x); B r = emptyHVec(); H_Sb* set = m_Sb(64); SGetU(x) for (usz i = 0; i < n; 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); }