Use grouped compress for all byte sizes if the number of groups is small enough

This commit is contained in:
Marshall Lochbaum 2022-09-19 19:31:44 -04:00
parent 11e3db1787
commit ac4729bb29

View File

@ -313,6 +313,21 @@ static B where(B x, usz xia, u64 s) {
return r;
}
// Is the number of values switches in w at most max?
static bool groups_lt(u64* wp, usz len, usz max) {
usz r = 0;
u64 prev = 0;
usz l = (len-1)/64+1; // assume trailing bits are zeroed out
usz b = 1<<8;
for (usz i = 0; i < l; ) {
for (usz e = l-i<b?l:i+b; i < e; i++) {
u64 v=wp[i]; r+= POPC(v ^ (v<<1 | prev)); prev = v>>63;
}
if (r > max) return 0;
}
return 1;
}
extern B take_c2(B, B, B);
static B compress(B w, B x, usz wia, u8 xl, u8 xt) {
u64* wp = bitarr_ptr(w);
@ -375,8 +390,9 @@ static B compress(B w, B x, usz wia, u8 xl, u8 xt) {
TFREE(buf)
#define WITH_SPARSE(W, CUTOFF, DENSE) { \
i##W *xp=tyany_ptr(x), *rp; \
if (wsum>=wia/CUTOFF) { DENSE; } \
else { rp=m_tyarrv(&r,W/8,wsum,xt); COMPRESS_BLOCK(i##W); } \
if (wsum<wia/CUTOFF) { rp=m_tyarrv(&r,W/8,wsum,xt); COMPRESS_BLOCK(i##W); } \
else if (groups_lt(wp,wia, wia/128)) r = compress_grouped(wp, x, wia, wsum, xt); \
else { DENSE; } \
break; }
#if SINGELI
case 3: WITH_SPARSE( 8, 32, rp=m_tyarrvO(&r,1,wsum,xt, 8); bmipopc_2slash8 (wp, xp, rp, wia))
@ -386,8 +402,13 @@ static B compress(B w, B x, usz wia, u8 xl, u8 xt) {
case 4: WITH_SPARSE(16, 2, rp=m_tyarrv(&r,2,wsum,xt); for (usz i=0; i<wia; i++) { *rp = xp[i]; rp+= bitp_get(wp,i); })
#endif
#undef WITH_SPARSE
case 5: { i32* xp= tyany_ptr(x); i32* rp=m_tyarrv(&r,4,wsum,xt); COMPRESS_BLOCK(i32); break; }
case 6: if (TI(x,elType)!=el_B) { u64* xp=tyany_ptr(x); u64* rp=m_tyarrv(&r,8,wsum,xt); COMPRESS_BLOCK(u64); break; }
#define BLOCK_OR_GROUPED(T) \
if (wsum>=wia/8 && groups_lt(wp,wia, wia/16)) r = compress_grouped(wp, x, wia, wsum, xt); \
else { T* xp=tyany_ptr(x); T* rp=m_tyarrv(&r,sizeof(T),wsum,xt); COMPRESS_BLOCK(T); break; } \
break;
case 5: BLOCK_OR_GROUPED(i32)
case 6: if (TI(x,elType)!=el_B) { BLOCK_OR_GROUPED(u64) }
#undef BLOCK_OR_GROUPED
else {
B xf = getFillQ(x);
B* xp = arr_bptr(x);