Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nauful/0523d01a98cf99b01847dd9876f442f4 to your computer and use it in GitHub Desktop.
Save nauful/0523d01a98cf99b01847dd9876f442f4 to your computer and use it in GitHub Desktop.
int N = fin.len;
const int CH_BITS = 25;
FSM fsm;
memset(&fsm, 0, sizeof(FSM));
memset(fsm.index, -1, sizeof(fsm.index));
init_fsm(fsm);
{
byte* t2 = new byte[1 << 24];
uint16* t4 = new uint16[1 << CH_BITS];
//uint16* t6 = new uint16[1 << CH_BITS];
memset(t2, 0, 1 << 24);
memset(t4, 0, 2 << CH_BITS);
//memset(t6, 0, 2 << CH_BITS);
uint32 table_mix2[64], table_mix24[64][64], table_mix246[32][32][32];
for (int i = 0; i < 64; i++) {
table_mix2[i] = (1 << (19 - 6)) + (i << (20 - 6));
for (int j = 0; j < 64; j++) {
int v = j + 3 * i;
v <<= 20 - 6 - 2;
v += 1 << (19 - 6);
table_mix24[j][i] = v << 8;
}
}
for (int k = 0; k < 32; k++) {
for (int j = 0; j < 32; j++) {
for (int i = 0; i < 32; i++) {
int v = k + 3 * j + 12 * i;
v <<= 20 - 5 - 4;
v += 1 << (19 - 6);
table_mix246[k][j][i] = v << 8;
}
}
}
uint32 table_sse[64];
for (int i = 0; i < 64; i++) {
int v = i << (20 - 6);
v += 1 << (19 - 6);
table_sse[i] = (v << 8) + 23;
}
Common::Benchmark b("forward");
Entropy::BitCoder bc(&fpacked);
bc.Init();
uint32 ctx = 0, ctx1 = 0;
for (int pos = 0; pos < N; pos++) {
uint32 h4 = hash4(ctx);
uint32 h6 = hash4(ctx) ^ hash4(ctx1 & 0xFFFF);
byte* o2 = t2 + ((ctx & 0xFFFF) << 8);
uint16* o4 = t4 + ((h4 >> (32 - CH_BITS)) & ~0x100);
//uint16* o6 = t6 + ((h6 >> (32 - CH_BITS)) & ~0x100);
byte h4b = h4 >> 24;
byte h6b = h6 >> 24;
int y = fin.buf[pos];
int p = 1;
for (int i = 7; i >= 0; i--) {
int b = (y >> i) & 1;
auto& c2 = o2[p];
auto& c4 = o4[p];
//auto& c6 = o6[p];
bool has_c4 = (o4[p] >> 8) == h4b ? true : (o4[p] = h4b << 8, false);
//bool has_c6 = (o6[p] >> 8) == h6b ? true : (o6[p] = h6b << 8, false);
auto& mix_c =
//has_c6 ? table_mix246[fsm.pr5[c2]][fsm.pr5[byte(c4)]][fsm.pr5[byte(c6)]] :
(has_c4 ?
table_mix24[fsm.pr6[c2]][fsm.pr6[byte(c4)]] :
table_mix2[fsm.pr6[c2]]);
auto& sse = table_sse[mix_c >> 22];
//uint16 pr = mix_c >> 16;
uint16 pr = sse >> 16;
pr += pr == 0;
bc.Encode12P(pr, b);
c2 = fsm.next[b][c2];
c4 = fsm.next[b][byte(c4)] + (h4b << 8);
//c6 = fsm.next[b][byte(c6)] + (h6b << 8);
int mix_upd = (b << 19) - (mix_c >> 9);
mix_upd >>= 8;
mix_c += (mix_upd << 8) + (byte(mix_c) < 64);
int sse_upd = (b << 19) - (sse >> 9);
sse_upd >>= byte(sse) >> 3;
sse += (sse_upd << 8) + (byte(sse) < 64);
p += p + b;
}
ctx1 = (ctx1 << 8) + (ctx >> 24);
ctx = (ctx << 8) + byte(p);
}
bc.Flush();
delete[] t2;
delete[] t4;
//delete[] t6;
}
printf("%d -> %d (%.2f KB)\n", N, fpacked.Position(), fpacked.Position() / 1024.0);
fpacked.Rewind();
{
byte* t2 = new byte[1 << 24];
uint16* t4 = new uint16[1 << CH_BITS];
//uint16* t6 = new uint16[1 << CH_BITS];
memset(t2, 0, 1 << 24);
memset(t4, 0, 2 << CH_BITS);
//memset(t6, 0, 2 << CH_BITS);
uint32 table_mix2[64], table_mix24[64][64], table_mix246[32][32][32];
for (int i = 0; i < 64; i++) {
table_mix2[i] = (1 << (19 - 6)) + (i << (20 - 6));
for (int j = 0; j < 64; j++) {
int v = j + 3 * i;
v <<= 20 - 6 - 2;
v += 1 << (19 - 6);
table_mix24[j][i] = v << 8;
}
}
for (int k = 0; k < 32; k++) {
for (int j = 0; j < 32; j++) {
for (int i = 0; i < 32; i++) {
int v = k + 3 * j + 12 * i;
v <<= 20 - 5 - 4;
v += 1 << (19 - 6);
table_mix246[k][j][i] = v << 8;
}
}
}
uint32 table_sse[64];
for (int i = 0; i < 64; i++) {
int v = i << (20 - 6);
v += 1 << (19 - 6);
table_sse[i] = (v << 8) + 23;
}
Common::Benchmark b("reverse");
Entropy::BitDecoder bc(&fpacked);
bc.Init();
uint32 ctx = 0, ctx1 = 0;
for (int pos = 0; pos < N; pos++) {
uint32 h4 = hash4(ctx);
uint32 h6 = hash4(ctx) ^ hash4(ctx1 & 0xFFFF);
byte* o2 = t2 + ((ctx & 0xFFFF) << 8);
uint16* o4 = t4 + ((h4 >> (32 - CH_BITS)) & ~0x100);
//uint16* o6 = t6 + ((h6 >> (32 - CH_BITS)) & ~0x100);
byte h4b = h4 >> 24;
byte h6b = h6 >> 24;
int y = fin.buf[pos];
int p = 1;
for (int i = 7; i >= 0; i--) {
auto& c2 = o2[p];
auto& c4 = o4[p];
//auto& c6 = o6[p];
bool has_c4 = (o4[p] >> 8) == h4b ? true : (o4[p] = h4b << 8, false);
//bool has_c6 = (o6[p] >> 8) == h6b ? true : (o6[p] = h6b << 8, false);
auto& mix_c =
//has_c6 ? table_mix246[fsm.pr5[c2]][fsm.pr5[byte(c4)]][fsm.pr5[byte(c6)]] :
(has_c4 ?
table_mix24[fsm.pr6[c2]][fsm.pr6[byte(c4)]] :
table_mix2[fsm.pr6[c2]]);
auto& sse = table_sse[mix_c >> 22];
//uint16 pr = mix_c >> 16;
uint16 pr = sse >> 16;
pr += pr == 0;
int b = bc.Decode12P(pr);
c2 = fsm.next[b][c2];
c4 = fsm.next[b][byte(c4)] + (h4b << 8);
//c6 = fsm.next[b][byte(c6)] + (h6b << 8);
int mix_upd = (b << 19) - (mix_c >> 9);
mix_upd >>= 8;
mix_c += (mix_upd << 8) + (byte(mix_c) < 64);
int sse_upd = (b << 19) - (sse >> 9);
sse_upd >>= byte(sse) >> 3;
sse += (sse_upd << 8) + (byte(sse) < 64);
p += p + b;
}
ctx1 = (ctx1 << 8) + (ctx >> 24);
ctx = (ctx << 8) + byte(p);
funpacked.Put(p - 0x100);
}
delete[] t2;
delete[] t4;
//delete[] t6;
}
ASSERT(!memcmp(fin.buf, funpacked.buf, N));
delete[] fin.buf;
delete[] fpacked.buf;
delete[] funpacked.buf;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment