summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compression.rs50
1 files changed, 38 insertions, 12 deletions
diff --git a/src/compression.rs b/src/compression.rs
index 7e20a94..9b17698 100644
--- a/src/compression.rs
+++ b/src/compression.rs
@@ -39,14 +39,37 @@ impl CompressionFormat {
Ok(match self {
CompressionFormat::Gz => Box::new(GzEncoder::new(file, flate2::Compression::best())),
CompressionFormat::Xz => {
- // Note that preset 6 takes about 173MB of memory per thread, so we limit the number of
- // threads to not blow out 32-bit hosts. (We could be more precise with
- // `MtStreamBuilder::memusage()` if desired.)
- let stream = xz2::stream::MtStreamBuilder::new()
- .threads(Ord::min(num_cpus::get(), 8) as u32)
- .preset(6)
- .encoder()?;
- Box::new(XzEncoder::new_stream(file, stream))
+ let mut filters = xz2::stream::Filters::new();
+ // the preset is overridden by the other options so it doesn't matter
+ let mut lzma_ops = xz2::stream::LzmaOptions::new_preset(9).unwrap();
+ // This sets the overall dictionary size, which is also how much memory (baseline)
+ // is needed for decompression.
+ lzma_ops.dict_size(64 * 1024 * 1024);
+ // Use the best match finder for compression ratio.
+ lzma_ops.match_finder(xz2::stream::MatchFinder::BinaryTree4);
+ lzma_ops.mode(xz2::stream::Mode::Normal);
+ // Set nice len to the maximum for best compression ratio
+ lzma_ops.nice_len(273);
+ // Set depth to a reasonable value, 0 means auto, 1000 is somwhat high but gives
+ // good results.
+ lzma_ops.depth(1000);
+ // 2 is the default and does well for most files
+ lzma_ops.position_bits(2);
+ // 0 is the default and does well for most files
+ lzma_ops.literal_position_bits(0);
+ // 3 is the default and does well for most files
+ lzma_ops.literal_context_bits(3);
+
+ filters.lzma2(&lzma_ops);
+ let compressor = XzEncoder::new_stream(
+ std::io::BufWriter::new(file),
+ xz2::stream::MtStreamBuilder::new()
+ .threads(1)
+ .filters(filters)
+ .encoder()
+ .unwrap(),
+ );
+ Box::new(compressor)
}
})
}
@@ -94,10 +117,13 @@ impl fmt::Display for CompressionFormats {
if i != 0 {
write!(f, ",")?;
}
- fmt::Display::fmt(match format {
- CompressionFormat::Xz => "xz",
- CompressionFormat::Gz => "gz",
- }, f)?;
+ fmt::Display::fmt(
+ match format {
+ CompressionFormat::Xz => "xz",
+ CompressionFormat::Gz => "gz",
+ },
+ f,
+ )?;
}
Ok(())
}