Skip to content

Commit cb9574b

Browse files
authored
refactor: shrink HPACK encode tables (#949)
1 parent 69a678a commit cb9574b

4 files changed

Lines changed: 69 additions & 271 deletions

File tree

src/hpack/huffman/decode.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//!
1313
//! These are decoded by walking the generated `DECODE_TABLE` one input byte at a time.
1414
15-
use crate::hpack::huffman::table::{DECODE_TABLE, ENCODE_TABLE};
15+
use crate::hpack::huffman::table::{DECODE_TABLE, ENCODE_CODES, ENCODE_CODE_LENGTHS};
1616
use crate::hpack::DecoderError;
1717

1818
use bytes::BytesMut;
@@ -44,7 +44,8 @@ const fn build_fast_table() -> [u32; 1 << FAST_BITS] {
4444
// First fill in every index that starts with one whole code
4545
let mut a = 0;
4646
while a < 256 {
47-
let (len1, code1) = ENCODE_TABLE[a];
47+
let len1 = ENCODE_CODE_LENGTHS[a] as usize;
48+
let code1 = ENCODE_CODES[a] as u64;
4849
if len1 <= FAST_BITS {
4950
let rem = FAST_BITS - len1;
5051
let base = (code1 as usize) << rem;
@@ -61,13 +62,15 @@ const fn build_fast_table() -> [u32; 1 << FAST_BITS] {
6162
// Overwrite the indices where a second whole code fit right after the first
6263
let mut a = 0;
6364
while a < 256 {
64-
let (len1, code1) = ENCODE_TABLE[a];
65+
let len1 = ENCODE_CODE_LENGTHS[a] as usize;
66+
let code1 = ENCODE_CODES[a] as u64;
6567
// A second code needs at least 5 more bits (the shortest code)
6668
if len1 + 5 <= FAST_BITS {
6769
let rem = FAST_BITS - len1;
6870
let mut b = 0;
6971
while b < 256 {
70-
let (len2, code2) = ENCODE_TABLE[b];
72+
let len2 = ENCODE_CODE_LENGTHS[b] as usize;
73+
let code2 = ENCODE_CODES[b] as u64;
7174
if len2 <= rem {
7275
let rem2 = rem - len2;
7376
let base = ((code1 as usize) << rem) | ((code2 as usize) << rem2);
@@ -222,9 +225,10 @@ mod test {
222225
// out on purpose: encoded EOS is an error per RFC 7541 §5.2.
223226
fn reference_decode(src: &[u8]) -> Result<BytesMut, DecoderError> {
224227
// Each symbol's code as a string of '0' and '1', e.g. "11111000".
225-
let codes: Vec<String> = ENCODE_TABLE[..256]
228+
let codes: Vec<String> = ENCODE_CODES
226229
.iter()
227-
.map(|&(len, code)| format!("{code:0len$b}"))
230+
.zip(ENCODE_CODE_LENGTHS.iter())
231+
.map(|(&code, &len)| format!("{code:0len$b}", len = len as usize))
228232
.collect();
229233
let bits: String = src.iter().map(|byte| format!("{byte:08b}")).collect();
230234

src/hpack/huffman/encode.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::hpack::huffman::table::ENCODE_TABLE;
1+
use crate::hpack::huffman::table::{ENCODE_CODES, ENCODE_CODE_LENGTHS};
22

33
use bytes::{BufMut, BytesMut};
44

@@ -7,7 +7,8 @@ pub fn encode(src: &[u8], dst: &mut BytesMut) {
77
let mut bits_len = 0;
88

99
for &b in src {
10-
let (nbits, code) = ENCODE_TABLE[b as usize];
10+
let nbits = ENCODE_CODE_LENGTHS[b as usize] as usize;
11+
let code = ENCODE_CODES[b as usize] as u64;
1112

1213
bits = (bits << nbits) | code;
1314
bits_len += nbits;

src/hpack/huffman/table.rs

Lines changed: 42 additions & 259 deletions
Original file line numberDiff line numberDiff line change
@@ -1,266 +1,49 @@
11
// !!! DO NOT EDIT !!! Generated by util/genhuff/src/main.rs
22

3-
// (num-bits, bits)
4-
pub const ENCODE_TABLE: [(usize, u64); 257] = [
5-
(13, 0x1ff8),
6-
(23, 0x7fffd8),
7-
(28, 0xfffffe2),
8-
(28, 0xfffffe3),
9-
(28, 0xfffffe4),
10-
(28, 0xfffffe5),
11-
(28, 0xfffffe6),
12-
(28, 0xfffffe7),
13-
(28, 0xfffffe8),
14-
(24, 0xffffea),
15-
(30, 0x3ffffffc),
16-
(28, 0xfffffe9),
17-
(28, 0xfffffea),
18-
(30, 0x3ffffffd),
19-
(28, 0xfffffeb),
20-
(28, 0xfffffec),
21-
(28, 0xfffffed),
22-
(28, 0xfffffee),
23-
(28, 0xfffffef),
24-
(28, 0xffffff0),
25-
(28, 0xffffff1),
26-
(28, 0xffffff2),
27-
(30, 0x3ffffffe),
28-
(28, 0xffffff3),
29-
(28, 0xffffff4),
30-
(28, 0xffffff5),
31-
(28, 0xffffff6),
32-
(28, 0xffffff7),
33-
(28, 0xffffff8),
34-
(28, 0xffffff9),
35-
(28, 0xffffffa),
36-
(28, 0xffffffb),
37-
(6, 0x14),
38-
(10, 0x3f8),
39-
(10, 0x3f9),
40-
(12, 0xffa),
41-
(13, 0x1ff9),
42-
(6, 0x15),
43-
(8, 0xf8),
44-
(11, 0x7fa),
45-
(10, 0x3fa),
46-
(10, 0x3fb),
47-
(8, 0xf9),
48-
(11, 0x7fb),
49-
(8, 0xfa),
50-
(6, 0x16),
51-
(6, 0x17),
52-
(6, 0x18),
53-
(5, 0x0),
54-
(5, 0x1),
55-
(5, 0x2),
56-
(6, 0x19),
57-
(6, 0x1a),
58-
(6, 0x1b),
59-
(6, 0x1c),
60-
(6, 0x1d),
61-
(6, 0x1e),
62-
(6, 0x1f),
63-
(7, 0x5c),
64-
(8, 0xfb),
65-
(15, 0x7ffc),
66-
(6, 0x20),
67-
(12, 0xffb),
68-
(10, 0x3fc),
69-
(13, 0x1ffa),
70-
(6, 0x21),
71-
(7, 0x5d),
72-
(7, 0x5e),
73-
(7, 0x5f),
74-
(7, 0x60),
75-
(7, 0x61),
76-
(7, 0x62),
77-
(7, 0x63),
78-
(7, 0x64),
79-
(7, 0x65),
80-
(7, 0x66),
81-
(7, 0x67),
82-
(7, 0x68),
83-
(7, 0x69),
84-
(7, 0x6a),
85-
(7, 0x6b),
86-
(7, 0x6c),
87-
(7, 0x6d),
88-
(7, 0x6e),
89-
(7, 0x6f),
90-
(7, 0x70),
91-
(7, 0x71),
92-
(7, 0x72),
93-
(8, 0xfc),
94-
(7, 0x73),
95-
(8, 0xfd),
96-
(13, 0x1ffb),
97-
(19, 0x7fff0),
98-
(13, 0x1ffc),
99-
(14, 0x3ffc),
100-
(6, 0x22),
101-
(15, 0x7ffd),
102-
(5, 0x3),
103-
(6, 0x23),
104-
(5, 0x4),
105-
(6, 0x24),
106-
(5, 0x5),
107-
(6, 0x25),
108-
(6, 0x26),
109-
(6, 0x27),
110-
(5, 0x6),
111-
(7, 0x74),
112-
(7, 0x75),
113-
(6, 0x28),
114-
(6, 0x29),
115-
(6, 0x2a),
116-
(5, 0x7),
117-
(6, 0x2b),
118-
(7, 0x76),
119-
(6, 0x2c),
120-
(5, 0x8),
121-
(5, 0x9),
122-
(6, 0x2d),
123-
(7, 0x77),
124-
(7, 0x78),
125-
(7, 0x79),
126-
(7, 0x7a),
127-
(7, 0x7b),
128-
(15, 0x7ffe),
129-
(11, 0x7fc),
130-
(14, 0x3ffd),
131-
(13, 0x1ffd),
132-
(28, 0xffffffc),
133-
(20, 0xfffe6),
134-
(22, 0x3fffd2),
135-
(20, 0xfffe7),
136-
(20, 0xfffe8),
137-
(22, 0x3fffd3),
138-
(22, 0x3fffd4),
139-
(22, 0x3fffd5),
140-
(23, 0x7fffd9),
141-
(22, 0x3fffd6),
142-
(23, 0x7fffda),
143-
(23, 0x7fffdb),
144-
(23, 0x7fffdc),
145-
(23, 0x7fffdd),
146-
(23, 0x7fffde),
147-
(24, 0xffffeb),
148-
(23, 0x7fffdf),
149-
(24, 0xffffec),
150-
(24, 0xffffed),
151-
(22, 0x3fffd7),
152-
(23, 0x7fffe0),
153-
(24, 0xffffee),
154-
(23, 0x7fffe1),
155-
(23, 0x7fffe2),
156-
(23, 0x7fffe3),
157-
(23, 0x7fffe4),
158-
(21, 0x1fffdc),
159-
(22, 0x3fffd8),
160-
(23, 0x7fffe5),
161-
(22, 0x3fffd9),
162-
(23, 0x7fffe6),
163-
(23, 0x7fffe7),
164-
(24, 0xffffef),
165-
(22, 0x3fffda),
166-
(21, 0x1fffdd),
167-
(20, 0xfffe9),
168-
(22, 0x3fffdb),
169-
(22, 0x3fffdc),
170-
(23, 0x7fffe8),
171-
(23, 0x7fffe9),
172-
(21, 0x1fffde),
173-
(23, 0x7fffea),
174-
(22, 0x3fffdd),
175-
(22, 0x3fffde),
176-
(24, 0xfffff0),
177-
(21, 0x1fffdf),
178-
(22, 0x3fffdf),
179-
(23, 0x7fffeb),
180-
(23, 0x7fffec),
181-
(21, 0x1fffe0),
182-
(21, 0x1fffe1),
183-
(22, 0x3fffe0),
184-
(21, 0x1fffe2),
185-
(23, 0x7fffed),
186-
(22, 0x3fffe1),
187-
(23, 0x7fffee),
188-
(23, 0x7fffef),
189-
(20, 0xfffea),
190-
(22, 0x3fffe2),
191-
(22, 0x3fffe3),
192-
(22, 0x3fffe4),
193-
(23, 0x7ffff0),
194-
(22, 0x3fffe5),
195-
(22, 0x3fffe6),
196-
(23, 0x7ffff1),
197-
(26, 0x3ffffe0),
198-
(26, 0x3ffffe1),
199-
(20, 0xfffeb),
200-
(19, 0x7fff1),
201-
(22, 0x3fffe7),
202-
(23, 0x7ffff2),
203-
(22, 0x3fffe8),
204-
(25, 0x1ffffec),
205-
(26, 0x3ffffe2),
206-
(26, 0x3ffffe3),
207-
(26, 0x3ffffe4),
208-
(27, 0x7ffffde),
209-
(27, 0x7ffffdf),
210-
(26, 0x3ffffe5),
211-
(24, 0xfffff1),
212-
(25, 0x1ffffed),
213-
(19, 0x7fff2),
214-
(21, 0x1fffe3),
215-
(26, 0x3ffffe6),
216-
(27, 0x7ffffe0),
217-
(27, 0x7ffffe1),
218-
(26, 0x3ffffe7),
219-
(27, 0x7ffffe2),
220-
(24, 0xfffff2),
221-
(21, 0x1fffe4),
222-
(21, 0x1fffe5),
223-
(26, 0x3ffffe8),
224-
(26, 0x3ffffe9),
225-
(28, 0xffffffd),
226-
(27, 0x7ffffe3),
227-
(27, 0x7ffffe4),
228-
(27, 0x7ffffe5),
229-
(20, 0xfffec),
230-
(24, 0xfffff3),
231-
(20, 0xfffed),
232-
(21, 0x1fffe6),
233-
(22, 0x3fffe9),
234-
(21, 0x1fffe7),
235-
(21, 0x1fffe8),
236-
(23, 0x7ffff3),
237-
(22, 0x3fffea),
238-
(22, 0x3fffeb),
239-
(25, 0x1ffffee),
240-
(25, 0x1ffffef),
241-
(24, 0xfffff4),
242-
(24, 0xfffff5),
243-
(26, 0x3ffffea),
244-
(23, 0x7ffff4),
245-
(26, 0x3ffffeb),
246-
(27, 0x7ffffe6),
247-
(26, 0x3ffffec),
248-
(26, 0x3ffffed),
249-
(27, 0x7ffffe7),
250-
(27, 0x7ffffe8),
251-
(27, 0x7ffffe9),
252-
(27, 0x7ffffea),
253-
(27, 0x7ffffeb),
254-
(28, 0xffffffe),
255-
(27, 0x7ffffec),
256-
(27, 0x7ffffed),
257-
(27, 0x7ffffee),
258-
(27, 0x7ffffef),
259-
(27, 0x7fffff0),
260-
(26, 0x3ffffee),
261-
(30, 0x3fffffff),
3+
pub const ENCODE_CODES: [u32; 256] = [
4+
0x1ff8, 0x7fffd8, 0xfffffe2, 0xfffffe3, 0xfffffe4, 0xfffffe5, 0xfffffe6, 0xfffffe7, 0xfffffe8,
5+
0xffffea, 0x3ffffffc, 0xfffffe9, 0xfffffea, 0x3ffffffd, 0xfffffeb, 0xfffffec, 0xfffffed,
6+
0xfffffee, 0xfffffef, 0xffffff0, 0xffffff1, 0xffffff2, 0x3ffffffe, 0xffffff3, 0xffffff4,
7+
0xffffff5, 0xffffff6, 0xffffff7, 0xffffff8, 0xffffff9, 0xffffffa, 0xffffffb, 0x14, 0x3f8,
8+
0x3f9, 0xffa, 0x1ff9, 0x15, 0xf8, 0x7fa, 0x3fa, 0x3fb, 0xf9, 0x7fb, 0xfa, 0x16, 0x17, 0x18,
9+
0x0, 0x1, 0x2, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x5c, 0xfb, 0x7ffc, 0x20, 0xffb,
10+
0x3fc, 0x1ffa, 0x21, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
11+
0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xfc, 0x73, 0xfd, 0x1ffb, 0x7fff0,
12+
0x1ffc, 0x3ffc, 0x22, 0x7ffd, 0x3, 0x23, 0x4, 0x24, 0x5, 0x25, 0x26, 0x27, 0x6, 0x74, 0x75,
13+
0x28, 0x29, 0x2a, 0x7, 0x2b, 0x76, 0x2c, 0x8, 0x9, 0x2d, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7ffe,
14+
0x7fc, 0x3ffd, 0x1ffd, 0xffffffc, 0xfffe6, 0x3fffd2, 0xfffe7, 0xfffe8, 0x3fffd3, 0x3fffd4,
15+
0x3fffd5, 0x7fffd9, 0x3fffd6, 0x7fffda, 0x7fffdb, 0x7fffdc, 0x7fffdd, 0x7fffde, 0xffffeb,
16+
0x7fffdf, 0xffffec, 0xffffed, 0x3fffd7, 0x7fffe0, 0xffffee, 0x7fffe1, 0x7fffe2, 0x7fffe3,
17+
0x7fffe4, 0x1fffdc, 0x3fffd8, 0x7fffe5, 0x3fffd9, 0x7fffe6, 0x7fffe7, 0xffffef, 0x3fffda,
18+
0x1fffdd, 0xfffe9, 0x3fffdb, 0x3fffdc, 0x7fffe8, 0x7fffe9, 0x1fffde, 0x7fffea, 0x3fffdd,
19+
0x3fffde, 0xfffff0, 0x1fffdf, 0x3fffdf, 0x7fffeb, 0x7fffec, 0x1fffe0, 0x1fffe1, 0x3fffe0,
20+
0x1fffe2, 0x7fffed, 0x3fffe1, 0x7fffee, 0x7fffef, 0xfffea, 0x3fffe2, 0x3fffe3, 0x3fffe4,
21+
0x7ffff0, 0x3fffe5, 0x3fffe6, 0x7ffff1, 0x3ffffe0, 0x3ffffe1, 0xfffeb, 0x7fff1, 0x3fffe7,
22+
0x7ffff2, 0x3fffe8, 0x1ffffec, 0x3ffffe2, 0x3ffffe3, 0x3ffffe4, 0x7ffffde, 0x7ffffdf,
23+
0x3ffffe5, 0xfffff1, 0x1ffffed, 0x7fff2, 0x1fffe3, 0x3ffffe6, 0x7ffffe0, 0x7ffffe1, 0x3ffffe7,
24+
0x7ffffe2, 0xfffff2, 0x1fffe4, 0x1fffe5, 0x3ffffe8, 0x3ffffe9, 0xffffffd, 0x7ffffe3, 0x7ffffe4,
25+
0x7ffffe5, 0xfffec, 0xfffff3, 0xfffed, 0x1fffe6, 0x3fffe9, 0x1fffe7, 0x1fffe8, 0x7ffff3,
26+
0x3fffea, 0x3fffeb, 0x1ffffee, 0x1ffffef, 0xfffff4, 0xfffff5, 0x3ffffea, 0x7ffff4, 0x3ffffeb,
27+
0x7ffffe6, 0x3ffffec, 0x3ffffed, 0x7ffffe7, 0x7ffffe8, 0x7ffffe9, 0x7ffffea, 0x7ffffeb,
28+
0xffffffe, 0x7ffffec, 0x7ffffed, 0x7ffffee, 0x7ffffef, 0x7fffff0, 0x3ffffee,
26229
];
26330

31+
pub const ENCODE_CODE_LENGTHS: [u8; 256] = [
32+
13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 30, 28,
33+
28, 28, 28, 28, 28, 28, 28, 28, 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, 5, 5,
34+
5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
35+
7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6,
36+
6, 5, 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, 20, 22, 20, 20, 22, 22, 22, 23, 22,
37+
23, 23, 23, 23, 23, 24, 23, 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24, 22,
38+
21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, 21, 21, 22, 21, 23, 22, 23, 23, 20,
39+
22, 22, 22, 23, 22, 22, 23, 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25, 19,
40+
21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, 20, 24, 20, 21, 22, 21, 21, 23, 22,
41+
22, 25, 25, 24, 24, 26, 23, 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
42+
];
43+
44+
const _: [(); 1024] = [(); std::mem::size_of::<[u32; 256]>()];
45+
const _: [(); 256] = [(); std::mem::size_of::<[u8; 256]>()];
46+
26447
// A branch has bit 15 set and its table index in bits 8..=14.
26548
// A leaf stores the number of consumed bits in its high byte and the decoded byte in its low byte.
26649
pub const DECODE_TABLE: [u16; 15 * 256] = [

0 commit comments

Comments
 (0)