use existing copy functions for arr_join_inline

This commit is contained in:
dzaima 2022-09-01 19:52:51 +03:00
parent 90dd740bfc
commit bd04e38a5e
2 changed files with 28 additions and 38 deletions

View File

@ -393,6 +393,8 @@ static B m_getU_c32(Mut* m, usz ms) { return m_c32(m->ac32[ms]); }
static B m_getU_f64(Mut* m, usz ms) { return m_f64(m->af64[ms]); }
static B m_getU_B (Mut* m, usz ms) { return m->aB[ms]; }
M_CopyF copyFns[el_MAX];
MutFns mutFns[el_MAX+1];
u8 el_orArr[el_MAX*16 + el_MAX+1];
void mutF_init() {
@ -422,4 +424,5 @@ void mutF_init() {
mutFns[el_f64].elType = el_f64; mutFns[el_f64].valType = t_f64arr;
mutFns[el_B ].elType = el_B ; mutFns[el_B ].valType = t_harr;
mutFns[el_MAX].elType = el_MAX; mutFns[el_MAX].valType = t_COUNT;
for (u8 i = 0; i < el_MAX; i++) copyFns[i] = mutFns[i].m_copyG;
}

View File

@ -158,48 +158,34 @@ static void bit_cpy(u64* r, usz rs, u64* x, usz xs, usz l) {
B vec_join(B w, B x); // consumes both
extern M_CopyF copyFns[el_MAX];
#define COPY_TO(WHERE, ELT, MS, X, XS, LEN) copyFns[ELT](WHERE, MS, X, XS, LEN)
// if `consume==true`, consumes w,x and expects both args to be vectors
// else, doesn't consume x, and decrements refcount of w iif *reusedW (won't free because the result will be w)
FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) {
usz wia = IA(w);
usz xia = IA(x);
usz ria = wia+xia;
if (reusable(w)) {
u64 wsz = mm_size(v(w));
u8 wt = TY(w);
// TODO f64∾i32, i32∾i8, c32∾c8 etc
switch (wt) {
case t_bitarr: if (BITARR_SZ( ria)<wsz && TI(x,elType)==el_bit) { bit_cpy(bitarr_ptr(w),wia,bitarr_ptr(x),0,xia); goto rw; } break;
case t_i8arr: if (TYARR_SZ(I8, ria)<wsz && TI(x,elType)==el_i8 ) { memcpy(i8arr_ptr (w)+wia, i8any_ptr (x), xia*1); goto rw; } break;
case t_i16arr: if (TYARR_SZ(I16,ria)<wsz && TI(x,elType)==el_i16) { memcpy(i16arr_ptr(w)+wia, i16any_ptr(x), xia*2); goto rw; } break;
case t_i32arr: if (TYARR_SZ(I32,ria)<wsz && TI(x,elType)==el_i32) { memcpy(i32arr_ptr(w)+wia, i32any_ptr(x), xia*4); goto rw; } break;
case t_c8arr: if (TYARR_SZ(C8, ria)<wsz && TI(x,elType)==el_c8 ) { memcpy(c8arr_ptr (w)+wia, c8any_ptr (x), xia*1); goto rw; } break;
case t_c16arr: if (TYARR_SZ(C16,ria)<wsz && TI(x,elType)==el_c16) { memcpy(c16arr_ptr(w)+wia, c16any_ptr(x), xia*2); goto rw; } break;
case t_c32arr: if (TYARR_SZ(C32,ria)<wsz && TI(x,elType)==el_c32) { memcpy(c32arr_ptr(w)+wia, c32any_ptr(x), xia*4); goto rw; } break;
case t_f64arr: if (TYARR_SZ(F64,ria)<wsz && TI(x,elType)==el_f64) { memcpy(f64arr_ptr(w)+wia, f64any_ptr(x), xia*8); goto rw; } break;
case t_harr: if (fsizeof(HArr,a,B,ria)<wsz) {
B* rp = harr_ptr(w)+wia;
B* xpB = arr_bptr(x);
if (xpB!=NULL) {
memcpy(rp, xpB, xia*sizeof(B));
for (usz i = 0; i < xia; i++) inc(rp[i]);
} else {
switch(TI(x,elType)) {
case el_i8: { i8* xp=i8any_ptr (x); for (usz i=0; i<xia; i++) rp[i] = m_i32(xp[i]); } break;
case el_i16: { i16* xp=i16any_ptr(x); for (usz i=0; i<xia; i++) rp[i] = m_i32(xp[i]); } break;
case el_i32: { i32* xp=i32any_ptr(x); for (usz i=0; i<xia; i++) rp[i] = m_i32(xp[i]); } break;
case el_c8: { u8* xp=c8any_ptr (x); for (usz i=0; i<xia; i++) rp[i] = m_c32(xp[i]); } break;
case el_c16: { u16* xp=c16any_ptr(x); for (usz i=0; i<xia; i++) rp[i] = m_c32(xp[i]); } break;
case el_c32: { u32* xp=c32any_ptr(x); for (usz i=0; i<xia; i++) rp[i] = m_c32(xp[i]); } break;
case el_f64: { f64* xp=f64any_ptr(x); for (usz i=0; i<xia; i++) rp[i] = m_f64(xp[i]); } break;
default: { SGet(x) for (usz i=0; i<xia; i++) rp[i] = Get(x, i); } break;
}
}
goto rw;
} break;
}
u64 ria = wia+xia;
if (!reusable(w)) goto no;
u64 wsz = mm_size(v(w));
u8 wt = TY(w);
u8 we = TI(w, elType);
// TODO f64∾i32, i32∾i8, c32∾c8 etc
void* rp = tyany_ptr(w);
switch (wt) {
case t_bitarr: if (BITARR_SZ( ria)<wsz && TI(x,elType)==el_bit) goto yes; break;
case t_i8arr: if (TYARR_SZ(I8, ria)<wsz && TI(x,elType)<=el_i8 ) goto yes; break;
case t_i16arr: if (TYARR_SZ(I16,ria)<wsz && TI(x,elType)<=el_i16) goto yes; break;
case t_i32arr: if (TYARR_SZ(I32,ria)<wsz && TI(x,elType)<=el_i32) goto yes; break;
case t_f64arr: if (TYARR_SZ(F64,ria)<wsz && TI(x,elType)<=el_f64) goto yes; break;
case t_c8arr: if (TYARR_SZ(C8, ria)<wsz && TI(x,elType)==el_c8 ) goto yes; break;
case t_c16arr: if (TYARR_SZ(C16,ria)<wsz && TI(x,elType)<=el_c16 && TI(x,elType)>=el_c8) goto yes; break;
case t_c32arr: if (TYARR_SZ(C32,ria)<wsz && TI(x,elType)<=el_c32 && TI(x,elType)>=el_c8) goto yes; break;
case t_harr: if (fsizeof(HArr,a,B,ria)<wsz) { rp = harr_ptr(w); goto yes; } break;
}
no: // failed to reuse
MAKE_MUT(r, ria); mut_init(r, el_or(TI(w,elType), TI(x,elType)));
MUTG_INIT(r);
mut_copyG(r, 0, w, 0, wia);
@ -208,11 +194,12 @@ FORCE_INLINE B arr_join_inline(B w, B x, bool consume, bool* reusedW) {
*reusedW = false;
return mut_fv(r);
rw:
yes:
COPY_TO(rp, we, wia, x, 0, xia);
if (consume) decG(x);
*reusedW = true;
a(w)->ia = ria;
return FL_KEEP(w,fl_squoze); // keeping fl_squoze as appending items can't make the smallest item smaller
return FL_KEEP(w,fl_squoze); // keeping fl_squoze as appending items can't make the largest item smaller
}
static inline bool inplace_add(B w, B x) { // consumes x if returns true; fails if fills wouldn't be correct