annotate rust/hg-core/src/revlog/compression.rs @ 52316:a820a7a1fce0 default tip

setup: require TLS 1.2 support from the Python interpreter (BC) Before it was optional, and either 1.1 or 1.2 was sufficient. Now that the default minimum is 1.2, it needs to be present to work out of the box. The code here is more convoluted than the corresponding checks in `sslutil.py`, but I'm leaving it alone because it can all be simplified when py38 is dropped.
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 21 Nov 2024 11:46:10 -0500
parents f69a3f55fa9b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
52158
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
1 //! Helpers around revlog compression
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
2
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
3 use std::cell::RefCell;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
4 use std::collections::HashSet;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
5 use std::io::Read;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
6
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
7 use flate2::bufread::ZlibEncoder;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
8 use flate2::read::ZlibDecoder;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
9
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
10 use crate::config::Config;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
11 use crate::errors::HgError;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
12 use crate::exit_codes;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
13
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
14 use super::corrupted;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
15 use super::RevlogError;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
16
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
17 /// Header byte used to identify ZSTD-compressed data
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
18 pub const ZSTD_BYTE: u8 = b'\x28';
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
19 /// Header byte used to identify Zlib-compressed data
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
20 pub const ZLIB_BYTE: u8 = b'x';
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
21
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
22 const ZSTD_DEFAULT_LEVEL: u8 = 3;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
23 const ZLIB_DEFAULT_LEVEL: u8 = 6;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
24 /// The length of data below which we don't even try to compress it when using
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
25 /// Zstandard.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
26 const MINIMUM_LENGTH_ZSTD: usize = 50;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
27 /// The length of data below which we don't even try to compress it when using
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
28 /// Zlib.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
29 const MINIMUM_LENGTH_ZLIB: usize = 44;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
30
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
31 /// Defines the available compression engines and their options.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
32 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
33 pub enum CompressionConfig {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
34 Zlib {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
35 /// Between 0 and 9 included
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
36 level: u8,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
37 },
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
38 Zstd {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
39 /// Between 0 and 22 included
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
40 level: u8,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
41 /// Never used in practice for now
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
42 threads: u8,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
43 },
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
44 /// No compression is performed
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
45 None,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
46 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
47
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
48 impl CompressionConfig {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
49 pub fn new(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
50 config: &Config,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
51 requirements: &HashSet<String>,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
52 ) -> Result<Self, HgError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
53 let mut new = Self::default();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
54
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
55 let zlib_level = config.get_u32(b"storage", b"revlog.zlib.level")?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
56 let zstd_level = config.get_u32(b"storage", b"revlog.zstd.level")?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
57
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
58 for requirement in requirements {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
59 if requirement.starts_with("revlog-compression-")
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
60 || requirement.starts_with("exp-compression-")
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
61 {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
62 let split = &mut requirement.splitn(3, '-');
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
63 split.next();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
64 split.next();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
65 new = match split.next().unwrap() {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
66 "zstd" => CompressionConfig::zstd(zstd_level)?,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
67 e => {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
68 return Err(HgError::UnsupportedFeature(format!(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
69 "Unsupported compression engine '{e}'"
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
70 )))
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
71 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
72 };
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
73 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
74 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
75 if let Some(level) = zlib_level {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
76 if matches!(new, CompressionConfig::Zlib { .. }) {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
77 new.set_level(level as usize)?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
78 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
79 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
80 Ok(new)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
81 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
82
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
83 /// Sets the level of the current compression engine
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
84 pub fn set_level(&mut self, new_level: usize) -> Result<(), HgError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
85 match self {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
86 CompressionConfig::Zlib { level } => {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
87 if new_level > 9 {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
88 return Err(HgError::abort(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
89 format!(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
90 "invalid compression zlib compression level {}, \
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
91 expected between 0 and 9 included",
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
92 new_level
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
93 ),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
94 exit_codes::ABORT,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
95 None,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
96 ));
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
97 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
98 *level = new_level as u8;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
99 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
100 CompressionConfig::Zstd { level, .. } => {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
101 if new_level > 22 {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
102 return Err(HgError::abort(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
103 format!(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
104 "invalid compression zstd compression level {}, \
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
105 expected between 0 and 22 included",
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
106 new_level
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
107 ),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
108 exit_codes::ABORT,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
109 None,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
110 ));
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
111 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
112 *level = new_level as u8;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
113 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
114 CompressionConfig::None => {}
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
115 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
116 Ok(())
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
117 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
118
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
119 /// Return a ZSTD compression config
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
120 pub fn zstd(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
121 zstd_level: Option<u32>,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
122 ) -> Result<CompressionConfig, HgError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
123 let mut engine = CompressionConfig::Zstd {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
124 level: ZSTD_DEFAULT_LEVEL,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
125 threads: 0,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
126 };
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
127 if let Some(level) = zstd_level {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
128 engine.set_level(level as usize)?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
129 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
130 Ok(engine)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
131 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
132 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
133
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
134 impl Default for CompressionConfig {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
135 fn default() -> Self {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
136 Self::Zlib {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
137 level: ZLIB_DEFAULT_LEVEL,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
138 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
139 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
140 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
141
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
142 /// A high-level trait to define compressors that should be able to compress
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
143 /// and decompress arbitrary bytes.
52309
f69a3f55fa9b rust-compression: move the `Send` bound to the `Compressor` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 52158
diff changeset
144 pub trait Compressor: Send {
52158
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
145 /// Returns a new [`Vec`] with the compressed data.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
146 /// Should return `Ok(None)` if compression does not apply (e.g. too small)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
147 fn compress(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
148 &mut self,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
149 data: &[u8],
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
150 ) -> Result<Option<Vec<u8>>, RevlogError>;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
151 /// Returns a new [`Vec`] with the decompressed data.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
152 fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, RevlogError>;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
153 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
154
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
155 /// A compressor that does nothing (useful in tests)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
156 pub struct NoneCompressor;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
157
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
158 impl Compressor for NoneCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
159 fn compress(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
160 &mut self,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
161 _data: &[u8],
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
162 ) -> Result<Option<Vec<u8>>, RevlogError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
163 Ok(None)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
164 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
165
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
166 fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, RevlogError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
167 Ok(data.to_owned())
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
168 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
169 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
170
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
171 /// A compressor for Zstandard
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
172 pub struct ZstdCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
173 /// Level of compression to use
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
174 level: u8,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
175 /// How many threads are used (not implemented yet)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
176 threads: u8,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
177 /// The underlying zstd compressor
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
178 compressor: zstd::bulk::Compressor<'static>,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
179 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
180
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
181 impl ZstdCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
182 pub fn new(level: u8, threads: u8) -> Self {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
183 Self {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
184 level,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
185 threads,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
186 compressor: zstd::bulk::Compressor::new(level.into())
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
187 .expect("invalid zstd arguments"),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
188 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
189 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
190 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
191
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
192 impl Compressor for ZstdCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
193 fn compress(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
194 &mut self,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
195 data: &[u8],
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
196 ) -> Result<Option<Vec<u8>>, RevlogError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
197 if self.threads != 0 {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
198 // TODO use a zstd builder + zstd cargo feature to support this
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
199 unimplemented!("zstd parallel compression is not implemented");
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
200 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
201 if data.len() < MINIMUM_LENGTH_ZSTD {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
202 return Ok(None);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
203 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
204 let level = self.level as i32;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
205 if data.len() <= 1000000 {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
206 let compressed = self.compressor.compress(data).map_err(|e| {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
207 corrupted(format!("revlog compress error: {}", e))
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
208 })?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
209 Ok(if compressed.len() < data.len() {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
210 Some(compressed)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
211 } else {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
212 None
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
213 })
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
214 } else {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
215 Ok(Some(zstd::stream::encode_all(data, level).map_err(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
216 |e| corrupted(format!("revlog compress error: {}", e)),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
217 )?))
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
218 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
219 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
220
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
221 fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, RevlogError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
222 zstd::stream::decode_all(data).map_err(|e| {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
223 corrupted(format!("revlog decompress error: {}", e)).into()
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
224 })
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
225 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
226 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
227
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
228 /// A compressor for Zlib
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
229 pub struct ZlibCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
230 /// Level of compression to use
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
231 level: flate2::Compression,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
232 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
233
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
234 impl ZlibCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
235 pub fn new(level: u8) -> Self {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
236 Self {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
237 level: flate2::Compression::new(level.into()),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
238 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
239 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
240 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
241
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
242 impl Compressor for ZlibCompressor {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
243 fn compress(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
244 &mut self,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
245 data: &[u8],
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
246 ) -> Result<Option<Vec<u8>>, RevlogError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
247 assert!(!data.is_empty());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
248 if data.len() < MINIMUM_LENGTH_ZLIB {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
249 return Ok(None);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
250 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
251 let mut buf = Vec::with_capacity(data.len());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
252 ZlibEncoder::new(data, self.level)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
253 .read_to_end(&mut buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
254 .map_err(|e| corrupted(format!("revlog compress error: {}", e)))?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
255
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
256 Ok(if buf.len() < data.len() {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
257 buf.shrink_to_fit();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
258 Some(buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
259 } else {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
260 None
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
261 })
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
262 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
263
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
264 fn decompress(&self, data: &[u8]) -> Result<Vec<u8>, RevlogError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
265 let mut decoder = ZlibDecoder::new(data);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
266 // TODO reuse the allocation somehow?
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
267 let mut buf = vec![];
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
268 decoder.read_to_end(&mut buf).map_err(|e| {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
269 corrupted(format!("revlog decompress error: {}", e))
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
270 })?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
271 Ok(buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
272 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
273 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
274
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
275 thread_local! {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
276 // seems fine to [unwrap] here: this can only fail due to memory allocation
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
277 // failing, and it's normal for that to cause panic.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
278 static ZSTD_DECODER : RefCell<zstd::bulk::Decompressor<'static>> =
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
279 RefCell::new(zstd::bulk::Decompressor::new().ok().unwrap());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
280 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
281
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
282 /// Util to wrap the reuse of a zstd decoder while controlling its buffer size.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
283 fn zstd_decompress_to_buffer(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
284 bytes: &[u8],
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
285 buf: &mut Vec<u8>,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
286 ) -> Result<usize, std::io::Error> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
287 ZSTD_DECODER
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
288 .with(|decoder| decoder.borrow_mut().decompress_to_buffer(bytes, buf))
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
289 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
290
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
291 /// Specialized revlog decompression to use less memory for deltas while
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
292 /// keeping performance acceptable.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
293 pub(super) fn uncompressed_zstd_data(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
294 bytes: &[u8],
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
295 is_delta: bool,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
296 uncompressed_len: i32,
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
297 ) -> Result<Vec<u8>, HgError> {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
298 let cap = uncompressed_len.max(0) as usize;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
299 if is_delta {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
300 // [cap] is usually an over-estimate of the space needed because
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
301 // it's the length of delta-decoded data, but we're interested
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
302 // in the size of the delta.
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
303 // This means we have to [shrink_to_fit] to avoid holding on
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
304 // to a large chunk of memory, but it also means we must have a
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
305 // fallback branch, for the case when the delta is longer than
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
306 // the original data (surprisingly, this does happen in practice)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
307 let mut buf = Vec::with_capacity(cap);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
308 match zstd_decompress_to_buffer(bytes, &mut buf) {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
309 Ok(_) => buf.shrink_to_fit(),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
310 Err(_) => {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
311 buf.clear();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
312 zstd::stream::copy_decode(bytes, &mut buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
313 .map_err(|e| corrupted(e.to_string()))?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
314 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
315 };
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
316 Ok(buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
317 } else {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
318 let mut buf = Vec::with_capacity(cap);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
319 let len = zstd_decompress_to_buffer(bytes, &mut buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
320 .map_err(|e| corrupted(e.to_string()))?;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
321 if len != uncompressed_len as usize {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
322 Err(corrupted("uncompressed length does not match"))
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
323 } else {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
324 Ok(buf)
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
325 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
326 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
327 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
328
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
329 #[cfg(test)]
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
330 mod tests {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
331 use super::*;
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
332
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
333 const LARGE_TEXT: &[u8] = b"
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
334 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
335 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
336 Emana Karassoli, Loucra Loucra Nonponto, Pata Pata, Ko Ko Ko.";
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
337
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
338 #[test]
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
339 fn test_zlib_compressor() {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
340 // Can return `Ok(None)`
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
341 let mut compressor = ZlibCompressor::new(1);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
342 assert_eq!(compressor.compress(b"too small").unwrap(), None);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
343
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
344 // Compression returns bytes
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
345 let compressed_with_1 =
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
346 compressor.compress(LARGE_TEXT).unwrap().unwrap();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
347 assert!(compressed_with_1.len() < LARGE_TEXT.len());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
348 // Round trip works
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
349 assert_eq!(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
350 compressor.decompress(&compressed_with_1).unwrap(),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
351 LARGE_TEXT
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
352 );
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
353
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
354 // Compression levels mean something
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
355 let mut compressor = ZlibCompressor::new(9);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
356 // Compression returns bytes
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
357 let compressed = compressor.compress(LARGE_TEXT).unwrap().unwrap();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
358 assert!(compressed.len() < compressed_with_1.len());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
359 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
360
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
361 #[test]
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
362 fn test_zstd_compressor() {
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
363 // Can return `Ok(None)`
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
364 let mut compressor = ZstdCompressor::new(1, 0);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
365 assert_eq!(compressor.compress(b"too small").unwrap(), None);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
366
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
367 // Compression returns bytes
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
368 let compressed_with_1 =
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
369 compressor.compress(LARGE_TEXT).unwrap().unwrap();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
370 assert!(compressed_with_1.len() < LARGE_TEXT.len());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
371 // Round trip works
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
372 assert_eq!(
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
373 compressor.decompress(&compressed_with_1).unwrap(),
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
374 LARGE_TEXT
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
375 );
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
376
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
377 // Compression levels mean something
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
378 let mut compressor = ZstdCompressor::new(22, 0);
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
379 // Compression returns bytes
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
380 let compressed = compressor.compress(LARGE_TEXT).unwrap().unwrap();
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
381 assert!(compressed.len() < compressed_with_1.len());
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
382 }
0744248cc541 rust-revlog: add compression helpers
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
383 }