Skip to content

Commit 31b4e31

Browse files
Merge pull request #123 from Mark-Simulacrum/compression
Adjust xz compression settings
2 parents 9981e4d + f1af547 commit 31b4e31

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

src/compression.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,37 @@ impl CompressionFormat {
3939
Ok(match self {
4040
CompressionFormat::Gz => Box::new(GzEncoder::new(file, flate2::Compression::best())),
4141
CompressionFormat::Xz => {
42-
// Note that preset 6 takes about 173MB of memory per thread, so we limit the number of
43-
// threads to not blow out 32-bit hosts. (We could be more precise with
44-
// `MtStreamBuilder::memusage()` if desired.)
45-
let stream = xz2::stream::MtStreamBuilder::new()
46-
.threads(Ord::min(num_cpus::get(), 8) as u32)
47-
.preset(6)
48-
.encoder()?;
49-
Box::new(XzEncoder::new_stream(file, stream))
42+
let mut filters = xz2::stream::Filters::new();
43+
// the preset is overridden by the other options so it doesn't matter
44+
let mut lzma_ops = xz2::stream::LzmaOptions::new_preset(9).unwrap();
45+
// This sets the overall dictionary size, which is also how much memory (baseline)
46+
// is needed for decompression.
47+
lzma_ops.dict_size(64 * 1024 * 1024);
48+
// Use the best match finder for compression ratio.
49+
lzma_ops.match_finder(xz2::stream::MatchFinder::BinaryTree4);
50+
lzma_ops.mode(xz2::stream::Mode::Normal);
51+
// Set nice len to the maximum for best compression ratio
52+
lzma_ops.nice_len(273);
53+
// Set depth to a reasonable value, 0 means auto, 1000 is somwhat high but gives
54+
// good results.
55+
lzma_ops.depth(1000);
56+
// 2 is the default and does well for most files
57+
lzma_ops.position_bits(2);
58+
// 0 is the default and does well for most files
59+
lzma_ops.literal_position_bits(0);
60+
// 3 is the default and does well for most files
61+
lzma_ops.literal_context_bits(3);
62+
63+
filters.lzma2(&lzma_ops);
64+
let compressor = XzEncoder::new_stream(
65+
std::io::BufWriter::new(file),
66+
xz2::stream::MtStreamBuilder::new()
67+
.threads(1)
68+
.filters(filters)
69+
.encoder()
70+
.unwrap(),
71+
);
72+
Box::new(compressor)
5073
}
5174
})
5275
}
@@ -94,10 +117,13 @@ impl fmt::Display for CompressionFormats {
94117
if i != 0 {
95118
write!(f, ",")?;
96119
}
97-
fmt::Display::fmt(match format {
98-
CompressionFormat::Xz => "xz",
99-
CompressionFormat::Gz => "gz",
100-
}, f)?;
120+
fmt::Display::fmt(
121+
match format {
122+
CompressionFormat::Xz => "xz",
123+
CompressionFormat::Gz => "gz",
124+
},
125+
f,
126+
)?;
101127
}
102128
Ok(())
103129
}

0 commit comments

Comments
 (0)