Skip to content

Commit 6710039

Browse files
authored
Precompute fixed huffman tables (#39)
1 parent 70a8e18 commit 6710039

File tree

2 files changed

+97
-10
lines changed

2 files changed

+97
-10
lines changed

src/decompress.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use simd_adler32::Adler32;
33
use crate::{
44
huffman::{self, build_table},
55
tables::{
6-
self, CLCL_ORDER, DIST_SYM_TO_DIST_BASE, DIST_SYM_TO_DIST_EXTRA, FIXED_CODE_LENGTHS,
7-
LEN_SYM_TO_LEN_BASE, LEN_SYM_TO_LEN_EXTRA, LITLEN_TABLE_ENTRIES,
6+
self, CLCL_ORDER, DIST_SYM_TO_DIST_BASE, DIST_SYM_TO_DIST_EXTRA, FIXED_DIST_TABLE,
7+
FIXED_LITLEN_TABLE, LEN_SYM_TO_LEN_BASE, LEN_SYM_TO_LEN_EXTRA, LITLEN_TABLE_ENTRIES,
88
},
99
};
1010

@@ -62,13 +62,12 @@ pub const EXCEPTIONAL_ENTRY: u32 = 0x4000;
6262
pub const SECONDARY_TABLE_ENTRY: u32 = 0x2000;
6363

6464
/// The Decompressor state for a compressed block.
65-
#[repr(align(64))]
6665
#[derive(Eq, PartialEq, Debug)]
6766
struct CompressedBlock {
68-
litlen_table: [u32; 4096],
67+
litlen_table: Box<[u32; 4096]>,
6968
secondary_table: Vec<u16>,
7069

71-
dist_table: [u32; 512],
70+
dist_table: Box<[u32; 512]>,
7271
dist_secondary_table: Vec<u16>,
7372

7473
eof_code: u16,
@@ -123,8 +122,8 @@ impl Decompressor {
123122
buffer: 0,
124123
nbits: 0,
125124
compression: CompressedBlock {
126-
litlen_table: [0; 4096],
127-
dist_table: [0; 512],
125+
litlen_table: Box::new([0; 4096]),
126+
dist_table: Box::new([0; 512]),
128127
secondary_table: Vec::new(),
129128
dist_secondary_table: Vec::new(),
130129
eof_code: 0,
@@ -237,7 +236,12 @@ impl Decompressor {
237236
// Build decoding tables if the previous block wasn't also a fixed block.
238237
if !self.fixed_table {
239238
self.fixed_table = true;
240-
Self::build_tables(288, &FIXED_CODE_LENGTHS, &mut self.compression)?;
239+
for chunk in self.compression.litlen_table.chunks_exact_mut(512) {
240+
chunk.copy_from_slice(&FIXED_LITLEN_TABLE);
241+
}
242+
for chunk in self.compression.dist_table.chunks_exact_mut(32) {
243+
chunk.copy_from_slice(&FIXED_DIST_TABLE);
244+
}
241245
}
242246

243247
self.state = State::CompressedData;
@@ -405,7 +409,7 @@ impl Decompressor {
405409
&code_lengths[..hlit],
406410
&LITLEN_TABLE_ENTRIES,
407411
&mut codes[..hlit],
408-
&mut compression.litlen_table,
412+
&mut *compression.litlen_table,
409413
&mut compression.secondary_table,
410414
false,
411415
true,
@@ -427,7 +431,7 @@ impl Decompressor {
427431
lengths,
428432
&tables::DISTANCE_TABLE_ENTRIES,
429433
&mut dist_codes,
430-
&mut compression.dist_table,
434+
&mut *compression.dist_table,
431435
&mut compression.dist_secondary_table,
432436
true,
433437
false,
@@ -1154,6 +1158,23 @@ mod tests {
11541158
}
11551159
}
11561160

1161+
#[test]
1162+
fn fixed_tables() {
1163+
let mut compression = CompressedBlock {
1164+
litlen_table: Box::new([0; 4096]),
1165+
dist_table: Box::new([0; 512]),
1166+
secondary_table: Vec::new(),
1167+
dist_secondary_table: Vec::new(),
1168+
eof_code: 0,
1169+
eof_mask: 0,
1170+
eof_bits: 0,
1171+
};
1172+
Decompressor::build_tables(288, &FIXED_CODE_LENGTHS, &mut compression).unwrap();
1173+
1174+
assert_eq!(compression.litlen_table[..512], FIXED_LITLEN_TABLE);
1175+
assert_eq!(compression.dist_table[..32], FIXED_DIST_TABLE);
1176+
}
1177+
11571178
#[test]
11581179
fn it_works() {
11591180
roundtrip(b"Hello world!");
@@ -1259,6 +1280,7 @@ mod tests {
12591280
}
12601281

12611282
mod test_utils;
1283+
use tables::FIXED_CODE_LENGTHS;
12621284
use test_utils::{decompress_by_chunks, TestDecompressionError};
12631285

12641286
fn verify_no_sensitivity_to_input_chunking(

src/tables.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,72 @@ pub(crate) const DISTANCE_TABLE_ENTRIES: [u32; 32] = {
128128
entries
129129
};
130130

131+
pub(crate) const FIXED_LITLEN_TABLE: [u32; 512] = [
132+
16391, 5275912, 1081608, 7537672, 2032135, 7373064, 3178760, 12615945, 655367, 6324488,
133+
2130184, 10518793, 33032, 8421640, 4227336, 14713097, 393223, 5800200, 1605896, 9470217,
134+
3867399, 7897352, 3703048, 13664521, 1114375, 6848776, 2654472, 11567369, 557320, 8945928,
135+
4751624, 15761673, 262151, 5538056, 1343752, 14877960, 2818823, 7635208, 3440904, 13140233,
136+
852231, 6586632, 2392328, 11043081, 295176, 8683784, 4489480, 15237385, 524295, 6062344,
137+
1868040, 9994505, 5440519, 8159496, 3965192, 14188809, 1507847, 7110920, 2916616, 12091657,
138+
819464, 9208072, 5013768, 16285961, 196615, 5406984, 1212680, 10683656, 2294535, 7504136,
139+
3309832, 12878089, 721159, 6455560, 2261256, 10780937, 164104, 8552712, 4358408, 14975241,
140+
458759, 5931272, 1736968, 9732361, 4391943, 8028424, 3834120, 13926665, 1245703, 6979848,
141+
2785544, 11829513, 688392, 9077000, 4882696, 16023817, 327687, 5669128, 1474824, 16392,
142+
3343111, 7766280, 3571976, 13402377, 983303, 6717704, 2523400, 11305225, 426248, 8814856,
143+
4620552, 15499529, 589831, 6193416, 1999112, 10256649, 6489095, 8290568, 4096264, 14450953,
144+
1769991, 7241992, 3047688, 12353801, 950536, 9339144, 5144840, 16548105, 16391, 5341448,
145+
1147144, 8586504, 2032135, 7438600, 3244296, 12747017, 655367, 6390024, 2195720, 10649865,
146+
98568, 8487176, 4292872, 14844169, 393223, 5865736, 1671432, 9601289, 3867399, 7962888,
147+
3768584, 13795593, 1114375, 6914312, 2720008, 11698441, 622856, 9011464, 4817160, 15892745,
148+
262151, 5603592, 1409288, 16908296, 2818823, 7700744, 3506440, 13271305, 852231, 6652168,
149+
2457864, 11174153, 360712, 8749320, 4555016, 15368457, 524295, 6127880, 1933576, 10125577,
150+
5440519, 8225032, 4030728, 14319881, 1507847, 7176456, 2982152, 12222729, 885000, 9273608,
151+
5079304, 16417033, 196615, 5472520, 1278216, 12780808, 2294535, 7569672, 3375368, 13009161,
152+
721159, 6521096, 2326792, 10912009, 229640, 8618248, 4423944, 15106313, 458759, 5996808,
153+
1802504, 9863433, 4391943, 8093960, 3899656, 14057737, 1245703, 7045384, 2851080, 11960585,
154+
753928, 9142536, 4948232, 16154889, 327687, 5734664, 1540360, 16392, 3343111, 7831816, 3637512,
155+
13533449, 983303, 6783240, 2588936, 11436297, 491784, 8880392, 4686088, 15630601, 589831,
156+
6258952, 2064648, 10387721, 6489095, 8356104, 4161800, 14582025, 1769991, 7307528, 3113224,
157+
12484873, 1016072, 9404680, 5210376, 16679177, 16391, 5275912, 1081608, 7537672, 2032135,
158+
7373064, 3178760, 12681481, 655367, 6324488, 2130184, 10584329, 33032, 8421640, 4227336,
159+
14778633, 393223, 5800200, 1605896, 9535753, 3867399, 7897352, 3703048, 13730057, 1114375,
160+
6848776, 2654472, 11632905, 557320, 8945928, 4751624, 15827209, 262151, 5538056, 1343752,
161+
14877960, 2818823, 7635208, 3440904, 13205769, 852231, 6586632, 2392328, 11108617, 295176,
162+
8683784, 4489480, 15302921, 524295, 6062344, 1868040, 10060041, 5440519, 8159496, 3965192,
163+
14254345, 1507847, 7110920, 2916616, 12157193, 819464, 9208072, 5013768, 16351497, 196615,
164+
5406984, 1212680, 10683656, 2294535, 7504136, 3309832, 12943625, 721159, 6455560, 2261256,
165+
10846473, 164104, 8552712, 4358408, 15040777, 458759, 5931272, 1736968, 9797897, 4391943,
166+
8028424, 3834120, 13992201, 1245703, 6979848, 2785544, 11895049, 688392, 9077000, 4882696,
167+
16089353, 327687, 5669128, 1474824, 16392, 3343111, 7766280, 3571976, 13467913, 983303,
168+
6717704, 2523400, 11370761, 426248, 8814856, 4620552, 15565065, 589831, 6193416, 1999112,
169+
10322185, 6489095, 8290568, 4096264, 14516489, 1769991, 7241992, 3047688, 12419337, 950536,
170+
9339144, 5144840, 16613641, 16391, 5341448, 1147144, 8586504, 2032135, 7438600, 3244296,
171+
12812553, 655367, 6390024, 2195720, 10715401, 98568, 8487176, 4292872, 14909705, 393223,
172+
5865736, 1671432, 9666825, 3867399, 7962888, 3768584, 13861129, 1114375, 6914312, 2720008,
173+
11763977, 622856, 9011464, 4817160, 15958281, 262151, 5603592, 1409288, 16908296, 2818823,
174+
7700744, 3506440, 13336841, 852231, 6652168, 2457864, 11239689, 360712, 8749320, 4555016,
175+
15433993, 524295, 6127880, 1933576, 10191113, 5440519, 8225032, 4030728, 14385417, 1507847,
176+
7176456, 2982152, 12288265, 885000, 9273608, 5079304, 16482569, 196615, 5472520, 1278216,
177+
12780808, 2294535, 7569672, 3375368, 13074697, 721159, 6521096, 2326792, 10977545, 229640,
178+
8618248, 4423944, 15171849, 458759, 5996808, 1802504, 9928969, 4391943, 8093960, 3899656,
179+
14123273, 1245703, 7045384, 2851080, 12026121, 753928, 9142536, 4948232, 16220425, 327687,
180+
5734664, 1540360, 16392, 3343111, 7831816, 3637512, 13598985, 983303, 6783240, 2588936,
181+
11501833, 491784, 8880392, 4686088, 15696137, 589831, 6258952, 2064648, 10453257, 6489095,
182+
8356104, 4161800, 14647561, 1769991, 7307528, 3113224, 12550409, 1016072, 9404680, 5210376,
183+
16744713,
184+
];
185+
186+
pub(crate) const FIXED_DIST_TABLE: [u32; 32] = [
187+
98309, 16877317, 1147653, 268536581, 360709, 67209477, 4293893, 1073843461, 229381, 33654789,
188+
2196485, 536972293, 623109, 134318597, 8488453, 5, 163845, 25265925, 1671941, 402754309,
189+
491781, 100763909, 6391045, 1610714373, 294917, 50432005, 3245061, 805407749, 885253,
190+
201427461, 12682757, 5,
191+
];
192+
193+
#[cfg(test)]
131194
pub(crate) const FIXED_CODE_LENGTHS: [u8; 320] = make_fixed_code_lengths();
195+
196+
#[cfg(test)]
132197
const fn make_fixed_code_lengths() -> [u8; 320] {
133198
let mut i = 0;
134199
let mut lengths = [0; 320];

0 commit comments

Comments
 (0)