Created
January 27, 2020 00:19
-
-
Save nauful/0523d01a98cf99b01847dd9876f442f4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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