diff --git a/Cargo.toml b/Cargo.toml index 8d5c354e..6303f510 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,3 +39,4 @@ md5 = "0.6" base64 = "0.10" pam-sys = "0.5" pam = "0.7" +lz4 = "1.23" \ No newline at end of file diff --git a/debian/control b/debian/control index 977870de..04b4792c 100644 --- a/debian/control +++ b/debian/control @@ -5,6 +5,7 @@ Maintainer: Proxmox Support Team Build-Depends: bash-completion, debhelper (>= 10), libpam0g-dev, + liblz4-dev, pkg-config, docutils-doc, Standards-Version: 3.9.5 @@ -16,5 +17,6 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, libjs-extjs (>= 6.0.1), fonts-font-awesome, proxmox-widget-toolkit, + liblz4-1, Description: Proxmox Backup Server This is experimental code used to test Rust. diff --git a/src/backup/chunk_store.rs b/src/backup/chunk_store.rs index 57e00b05..0224b4f1 100644 --- a/src/backup/chunk_store.rs +++ b/src/backup/chunk_store.rs @@ -1,6 +1,6 @@ use failure::*; use std::path::{Path, PathBuf}; -use std::io::Write; +use std::io::{Read, Write}; use std::time::Duration; use openssl::sha; @@ -181,22 +181,10 @@ impl ChunkStore { let digest_str = tools::digest_to_hex(&digest); chunk_path.push(&digest_str); - let mut f = std::fs::File::open(&chunk_path)?; + let f = std::fs::File::open(&chunk_path)?; + let mut decoder = lz4::Decoder::new(f)?; - let stat = nix::sys::stat::fstat(f.as_raw_fd())?; - let size = stat.st_size as usize; - - if buffer.capacity() < size { - let mut newsize = buffer.capacity(); - while newsize < size { newsize = newsize << 1; } - let additional = newsize - buffer.len(); - buffer.reserve_exact(additional); - } - unsafe { buffer.set_len(size); } - - use std::io::Read; - - f.read_exact(buffer.as_mut_slice())?; + decoder.read_to_end(buffer)?; Ok(()) } @@ -332,8 +320,15 @@ impl ChunkStore { let mut tmp_path = chunk_path.clone(); tmp_path.set_extension("tmp"); - let mut f = std::fs::File::create(&tmp_path)?; - f.write_all(chunk)?; + + let f = std::fs::File::create(&tmp_path)?; + + // fixme: what is the fasted lz4 encoder available (see lzbench)? + let mut encoder = lz4::EncoderBuilder::new().level(1).build(f)?; + + encoder.write_all(chunk)?; + let (_, encode_result) = encoder.finish(); + encode_result?; if let Err(err) = std::fs::rename(&tmp_path, &chunk_path) { if let Err(_) = std::fs::remove_file(&tmp_path) { /* ignore */ }