Mercurial > hg
comparison rust/hg-core/src/revlog/mod.rs @ 50508:39ed7b2953bb
rust: mostly avoid streaming zstd decompression
Streaming ZStd decompression seems slightly slower, and
the API we use makes it very inconvenient to re-use the
decompression context.
Instead of using that, use the buffer-backed version,
because we can give a reasonable-ish size estimate.
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Thu, 18 May 2023 17:53:17 +0100 |
parents | d1cab48354bc |
children | 0159b014f3ab |
comparison
equal
deleted
inserted
replaced
50507:d1cab48354bc | 50508:39ed7b2953bb |
---|---|
594 Ok(buf) | 594 Ok(buf) |
595 } | 595 } |
596 } | 596 } |
597 | 597 |
598 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> { | 598 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> { |
599 let cap = self.uncompressed_len.max(0) as usize; | |
599 if self.is_delta() { | 600 if self.is_delta() { |
600 let mut buf = Vec::with_capacity(self.compressed_len as usize); | 601 // [cap] is usually an over-estimate of the space needed because |
601 zstd::stream::copy_decode(self.bytes, &mut buf) | 602 // it's the length of delta-decoded data, but we're interested |
602 .map_err(|e| corrupted(e.to_string()))?; | 603 // in the size of the delta. |
604 // This means we have to [shrink_to_fit] to avoid holding on | |
605 // to a large chunk of memory, but it also means we must have a | |
606 // fallback branch, for the case when the delta is longer than | |
607 // the original data (surprisingly, this does happen in practice) | |
608 let mut buf = Vec::with_capacity(cap); | |
609 match zstd_decompress_to_buffer(self.bytes, &mut buf) { | |
610 Ok(_) => buf.shrink_to_fit(), | |
611 Err(_) => { | |
612 buf.clear(); | |
613 zstd::stream::copy_decode(self.bytes, &mut buf) | |
614 .map_err(|e| corrupted(e.to_string()))?; | |
615 } | |
616 }; | |
603 Ok(buf) | 617 Ok(buf) |
604 } else { | 618 } else { |
605 let cap = self.uncompressed_len.max(0) as usize; | |
606 let mut buf = Vec::with_capacity(cap); | 619 let mut buf = Vec::with_capacity(cap); |
607 let len = zstd_decompress_to_buffer(self.bytes, &mut buf) | 620 let len = zstd_decompress_to_buffer(self.bytes, &mut buf) |
608 .map_err(|e| corrupted(e.to_string()))?; | 621 .map_err(|e| corrupted(e.to_string()))?; |
609 if len != self.uncompressed_len as usize { | 622 if len != self.uncompressed_len as usize { |
610 Err(corrupted("uncompressed length does not match")) | 623 Err(corrupted("uncompressed length does not match")) |