Skip to content

Commit 1627bfc

Browse files
authored
Optimize GzipDecoder (#430)
* Optimize GzipDecoder - no heap allocation for footer which has fixed 8-byte size - do not store unused header - reset CrC instead of reassigning a new one - optimize check_crc: rm unnecessary size check Signed-off-by: Jiahao XU <[email protected]> * Fix GzipDecoder Signed-off-by: Jiahao XU <[email protected]> --------- Signed-off-by: Jiahao XU <[email protected]>
1 parent 7bf1b99 commit 1627bfc

File tree

1 file changed

+8
-19
lines changed

1 file changed

+8
-19
lines changed

crates/compression-codecs/src/gzip/decoder.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::header::{self, Header};
1+
use super::header;
22
use crate::{DecodeV2, FlateDecoder};
33
use compression_core::util::{PartialBuffer, WriteBuffer};
44
use flate2::Crc;
@@ -8,7 +8,7 @@ use std::io::{Error, ErrorKind, Result};
88
enum State {
99
Header(header::Parser),
1010
Decoding,
11-
Footer(PartialBuffer<Vec<u8>>),
11+
Footer(PartialBuffer<[u8; 8]>),
1212
Done,
1313
}
1414

@@ -17,17 +17,9 @@ pub struct GzipDecoder {
1717
inner: FlateDecoder,
1818
crc: Crc,
1919
state: State,
20-
header: Header,
2120
}
2221

23-
fn check_footer(crc: &Crc, input: &[u8]) -> Result<()> {
24-
if input.len() < 8 {
25-
return Err(Error::new(
26-
ErrorKind::InvalidData,
27-
"Invalid gzip footer length",
28-
));
29-
}
30-
22+
fn check_footer(crc: &Crc, input: &[u8; 8]) -> Result<()> {
3123
let crc_sum = crc.sum().to_le_bytes();
3224
let bytes_read = crc.amount().to_le_bytes();
3325

@@ -54,7 +46,6 @@ impl Default for GzipDecoder {
5446
inner: FlateDecoder::new(false),
5547
crc: Crc::new(),
5648
state: State::Header(header::Parser::default()),
57-
header: Header::default(),
5849
}
5950
}
6051
}
@@ -73,8 +64,7 @@ impl GzipDecoder {
7364
loop {
7465
match &mut self.state {
7566
State::Header(parser) => {
76-
if let Some(header) = parser.input(input)? {
77-
self.header = header;
67+
if parser.input(input)?.is_some() {
7868
self.state = State::Decoding;
7969
}
8070
}
@@ -92,16 +82,16 @@ impl GzipDecoder {
9282
let done = res?;
9383

9484
if done {
95-
self.state = State::Footer(vec![0; 8].into())
85+
self.state = State::Footer([0; 8].into());
9686
}
9787
}
9888

9989
State::Footer(footer) => {
10090
footer.copy_unwritten_from(input);
10191

10292
if footer.unwritten().is_empty() {
103-
check_footer(&self.crc, footer.written())?;
104-
self.state = State::Done
93+
check_footer(&self.crc, footer.get_mut())?;
94+
self.state = State::Done;
10595
}
10696
}
10797

@@ -122,9 +112,8 @@ impl GzipDecoder {
122112
impl DecodeV2 for GzipDecoder {
123113
fn reinit(&mut self) -> Result<()> {
124114
self.inner.reinit()?;
125-
self.crc = Crc::new();
115+
self.crc.reset();
126116
self.state = State::Header(header::Parser::default());
127-
self.header = Header::default();
128117
Ok(())
129118
}
130119

0 commit comments

Comments
 (0)