This commit is contained in:
Dennis Schwerdel 2017-03-15 21:53:05 +01:00 committed by Dennis Schwerdel
parent 7e66d806b5
commit 1a2ea29d24
10 changed files with 524 additions and 41 deletions

259
Comparison.txt Normal file
View File

@ -0,0 +1,259 @@
++ mkdir repos
++ target/release/zvault init --compression brotli/3 repos/zvault_brotli3
real 0m0.009s
user 0m0.008s
sys 0m0.000s
++ target/release/zvault init --compression brotli/6 repos/zvault_brotli6
real 0m0.010s
user 0m0.004s
sys 0m0.004s
++ target/release/zvault init --compression lzma2/2 repos/zvault_lzma2
real 0m0.009s
user 0m0.004s
sys 0m0.004s
++ attic init repos/attic
Initializing repository at "repos/attic"
Encryption NOT enabled.
Use the "--encryption=passphrase|keyfile" to enable encryption.
Initializing cache...
real 0m0.136s
user 0m0.100s
sys 0m0.016s
++ borg init -e none repos/borg
real 0m0.253s
user 0m0.204s
sys 0m0.012s
++ borg init -e none repos/borg-zlib
real 0m0.243s
user 0m0.200s
sys 0m0.008s
++ zbackup init --non-encrypted repos/zbackup
real 0m0.003s
user 0m0.000s
sys 0m0.000s
++ cat
++ target/release/zvault put repos/zvault_brotli3::silesia1 test_data/silesia.tar
real 0m3.389s
user 0m3.172s
sys 0m0.220s
++ target/release/zvault put repos/zvault_brotli3::silesia2 test_data/silesia.tar
real 0m0.741s
user 0m0.708s
sys 0m0.032s
++ target/release/zvault put repos/zvault_brotli6::silesia1 test_data/silesia.tar
real 0m10.166s
user 0m9.880s
sys 0m0.284s
++ target/release/zvault put repos/zvault_brotli6::silesia2 test_data/silesia.tar
real 0m0.707s
user 0m0.660s
sys 0m0.044s
++ target/release/zvault put repos/zvault_lzma2::silesia1 test_data/silesia.tar
real 0m26.277s
user 0m25.988s
sys 0m0.288s
++ target/release/zvault put repos/zvault_lzma2::silesia2 test_data/silesia.tar
real 0m0.710s
user 0m0.656s
sys 0m0.052s
++ attic create repos/attic::silesia1 test_data/silesia.tar
real 0m9.304s
user 0m8.440s
sys 0m0.328s
++ attic create repos/attic::silesia2 test_data/silesia.tar
real 0m1.210s
user 0m1.128s
sys 0m0.040s
++ borg create -C none repos/borg::silesia1 test_data/silesia.tar
real 0m4.805s
user 0m2.240s
sys 0m1.156s
++ borg create -C none repos/borg::silesia2 test_data/silesia.tar
real 0m1.475s
user 0m1.260s
sys 0m0.164s
++ borg create -C zlib repos/borg-zlib::silesia1 test_data/silesia.tar
real 0m10.093s
user 0m9.184s
sys 0m0.428s
++ borg create -C zlib repos/borg-zlib::silesia2 test_data/silesia.tar
real 0m1.534s
user 0m1.280s
sys 0m0.192s
++ zbackup backup --non-encrypted repos/zbackup/backups/silesia1
Loading index...
Index loaded.
Using up to 4 thread(s) for compression
real 0m24.362s
user 1m32.292s
sys 0m0.776s
++ zbackup backup --non-encrypted repos/zbackup/backups/silesia2
Loading index...
Loading index file 90cd1b771e3c068c6617b0089f4fe5fde4f654cb0473b7d7...
Index loaded.
Using up to 4 thread(s) for compression
real 0m1.281s
user 0m1.248s
sys 0m0.032s
++ du -h test_data/silesia.tar
203M test_data/silesia.tar
++ du -sh repos/zbackup/bundles repos/zvault_brotli3/bundles repos/zvault_brotli6/bundles repos/zvault_lzma2/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup
51M repos/zbackup/bundles
65M repos/zvault_brotli3/bundles
58M repos/zvault_brotli6/bundles
55M repos/zvault_lzma2/bundles
68M repos/attic
203M repos/borg
66M repos/borg-zlib
164K repos/zbackup
++ rm -rf repos
++ mkdir repos
++ target/release/zvault init --compression brotli/3 repos/zvault_brotli3
real 0m0.005s
user 0m0.000s
sys 0m0.004s
++ target/release/zvault init --compression brotli/6 repos/zvault_brotli6
real 0m0.005s
user 0m0.004s
sys 0m0.000s
++ target/release/zvault init --compression lzma2/2 repos/zvault_lzma2
real 0m0.005s
user 0m0.004s
sys 0m0.000s
++ attic init repos/attic
Initializing repository at "repos/attic"
Encryption NOT enabled.
Use the "--encryption=passphrase|keyfile" to enable encryption.
Initializing cache...
real 0m0.095s
user 0m0.060s
sys 0m0.020s
++ borg init -e none repos/borg
real 0m0.235s
user 0m0.184s
sys 0m0.016s
++ borg init -e none repos/borg-zlib
real 0m0.262s
user 0m0.200s
sys 0m0.016s
++ zbackup init --non-encrypted repos/zbackup
real 0m0.004s
user 0m0.000s
sys 0m0.000s
++ cat
++ target/release/zvault put repos/zvault_brotli3::ubuntu1 test_data/ubuntu.tar
real 0m3.008s
user 0m2.748s
sys 0m0.260s
++ target/release/zvault put repos/zvault_brotli3::ubuntu2 test_data/ubuntu.tar
real 0m0.621s
user 0m0.580s
sys 0m0.040s
++ target/release/zvault put repos/zvault_brotli6::ubuntu1 test_data/ubuntu.tar
real 0m10.916s
user 0m10.680s
sys 0m0.232s
++ target/release/zvault put repos/zvault_brotli6::ubuntu2 test_data/ubuntu.tar
real 0m0.619s
user 0m0.596s
sys 0m0.020s
++ target/release/zvault put repos/zvault_lzma2::ubuntu1 test_data/ubuntu.tar
real 0m37.039s
user 0m36.792s
sys 0m0.244s
++ target/release/zvault put repos/zvault_lzma2::ubuntu2 test_data/ubuntu.tar
real 0m0.640s
user 0m0.624s
sys 0m0.012s
++ attic create repos/attic::ubuntu1 test_data/ubuntu.tar
real 0m9.309s
user 0m8.316s
sys 0m0.368s
++ attic create repos/attic::ubuntu2 test_data/ubuntu.tar
real 0m1.093s
user 0m1.008s
sys 0m0.044s
++ borg create -C none repos/borg::ubuntu1 test_data/ubuntu.tar
real 0m4.317s
user 0m1.988s
sys 0m1.032s
++ borg create -C none repos/borg::ubuntu2 test_data/ubuntu.tar
real 0m1.402s
user 0m1.160s
sys 0m0.188s
++ borg create -C zlib repos/borg-zlib::ubuntu1 test_data/ubuntu.tar
real 0m10.049s
user 0m8.788s
sys 0m0.532s
++ borg create -C zlib repos/borg-zlib::ubuntu2 test_data/ubuntu.tar
real 0m1.291s
user 0m1.088s
sys 0m0.168s
++ zbackup backup --non-encrypted repos/zbackup/backups/ubuntu1
Loading index...
Index loaded.
Using up to 4 thread(s) for compression
real 0m17.972s
user 1m7.956s
sys 0m0.644s
++ zbackup backup --non-encrypted repos/zbackup/backups/ubuntu2
Loading index...
Loading index file 3fea916708827f3f5cdfc18fca024ef9cf00aa92a0c8d676...
Index loaded.
Using up to 4 thread(s) for compression
real 0m1.158s
user 0m1.132s
sys 0m0.024s
++ du -h test_data/ubuntu.tar
176M test_data/ubuntu.tar
++ du -sh repos/zbackup/bundles repos/zvault_brotli3/bundles repos/zvault_brotli6/bundles repos/zvault_lzma2/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup
64M repos/zbackup/bundles
77M repos/zvault_brotli3/bundles
68M repos/zvault_brotli6/bundles
63M repos/zvault_lzma2/bundles
84M repos/attic
176M repos/borg
83M repos/borg-zlib
148K repos/zbackup

View File

@ -483,6 +483,11 @@ impl Index {
self.entries self.entries
} }
#[inline]
pub fn size(&self) -> usize {
self.mmap.len()
}
#[inline] #[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.entries == 0 self.entries == 0

View File

@ -11,34 +11,38 @@ extern crate docopt;
extern crate rustc_serialize; extern crate rustc_serialize;
mod errors; mod errors;
mod util; pub mod util;
mod bundle; pub mod bundle;
mod index; pub mod index;
mod chunker; mod chunker;
mod repository; mod repository;
mod algotest; mod algotest;
use chunker::ChunkerType;
use repository::{Repository, Config, Mode, Inode};
use util::{ChecksumType, Compression, HashMethod, to_file_size};
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::time; use std::time;
use docopt::Docopt; use docopt::Docopt;
use chunker::ChunkerType;
use repository::{Repository, Config, Mode, Inode, Backup};
use util::{ChecksumType, Compression, HashMethod, to_file_size};
static USAGE: &'static str = " static USAGE: &'static str = "
Usage: Usage:
zvault init <repo> zvault init [--bundle-size SIZE] [--chunker METHOD] [--chunk-size SIZE] [--compression COMPRESSION] <repo>
zvault info <repo> zvault backup [--full] <backup> <path>
zvault bundles <repo> zvault restore <backup> <path>
zvault check [--full] <repo> zvault check [--full] <repo>
zvault list <repo>
zvault info <backup>
zvault stats <repo>
zvault bundles <repo>
zvault algotest <path> zvault algotest <path>
zvault test <repo> <path> zvault test <repo> <path>
zvault stat <path> zvault stat <path>
zvault put <repo> <path> zvault put <backup> <path>
Options: Options:
--full Whether to verify the repository by loading all bundles --full Whether to verify the repository by loading all bundles
@ -52,15 +56,25 @@ Options:
#[derive(RustcDecodable, Debug)] #[derive(RustcDecodable, Debug)]
struct Args { struct Args {
cmd_init: bool, cmd_init: bool,
cmd_backup: bool,
cmd_restore: bool,
cmd_check: bool,
cmd_list: bool,
cmd_info: bool, cmd_info: bool,
cmd_stats: bool,
cmd_bundles: bool,
cmd_algotest: bool, cmd_algotest: bool,
cmd_test: bool, cmd_test: bool,
cmd_stat: bool, cmd_stat: bool,
cmd_check: bool,
cmd_bundles: bool,
cmd_put: bool, cmd_put: bool,
arg_repo: Option<String>, arg_repo: Option<String>,
arg_path: Option<String>, arg_path: Option<String>,
arg_backup: Option<String>,
flag_full: bool, flag_full: bool,
flag_bundle_size: usize, flag_bundle_size: usize,
flag_chunker: String, flag_chunker: String,
@ -100,14 +114,23 @@ fn main() {
return return
} }
let mut repo = Repository::open(&args.arg_repo.unwrap()).unwrap();
let mut repo;
if let Some(path) = args.arg_repo {
repo = Repository::open(path).unwrap();
} else if let Some(ref backup) = args.arg_backup {
let path = backup.splitn(2, "::").nth(0).unwrap();
repo = Repository::open(path).unwrap();
} else {
panic!("Repository is needed");
}
if args.cmd_check { if args.cmd_check {
repo.check(args.flag_full).unwrap(); repo.check(args.flag_full).unwrap();
return return
} }
if args.cmd_info { if args.cmd_stats {
let info = repo.info(); let info = repo.info();
println!("Bundles: {}", info.bundle_count); println!("Bundles: {}", info.bundle_count);
println!("Total size: {}", to_file_size(info.encoded_data_size)); println!("Total size: {}", to_file_size(info.encoded_data_size));
@ -115,6 +138,15 @@ fn main() {
println!("Compression ratio: {:.1}", info.compression_ratio * 100.0); println!("Compression ratio: {:.1}", info.compression_ratio * 100.0);
println!("Chunk count: {}", info.chunk_count); println!("Chunk count: {}", info.chunk_count);
println!("Average chunk size: {}", to_file_size(info.avg_chunk_size as u64)); println!("Average chunk size: {}", to_file_size(info.avg_chunk_size as u64));
let index_usage = info.index_entries as f32 / info.index_capacity as f32;
println!("Index: {}, {}% full", to_file_size(info.index_size as u64), index_usage * 100.0);
return
}
if args.cmd_list {
for backup in repo.list_backups().unwrap() {
println!("{}", backup);
}
return return
} }
@ -136,12 +168,6 @@ fn main() {
return return
} }
if args.cmd_put {
let chunks = repo.put_inode(&args.arg_path.unwrap()).unwrap();
println!("done. {} chunks, total size: {}", chunks.len(), to_file_size(chunks.iter().map(|&(_,s)| s).sum::<usize>() as u64));
return
}
if args.cmd_test { if args.cmd_test {
print!("Integrity check before..."); print!("Integrity check before...");
repo.check(true).unwrap(); repo.check(true).unwrap();
@ -175,5 +201,29 @@ fn main() {
let read_speed = data.len() as f64 / duration; let read_speed = data.len() as f64 / duration;
assert_eq!(data.len(), data2.len()); assert_eq!(data.len(), data2.len());
println!(" done. {:.1} MB/s", read_speed / 1_000_000.0); println!(" done. {:.1} MB/s", read_speed / 1_000_000.0);
return
}
let backup_name = args.arg_backup.unwrap().splitn(2, "::").nth(1).unwrap().to_string();
if args.cmd_put {
let chunks = repo.put_inode(&args.arg_path.unwrap()).unwrap();
repo.save_backup(&Backup{root: chunks, ..Default::default()}, &backup_name).unwrap();
return
}
if args.cmd_backup {
unimplemented!()
}
let backup = repo.get_backup(&backup_name).unwrap();
if args.cmd_info {
println!("{:?}", backup.root);
return
}
if args.cmd_restore {
repo.restore_backup(&backup, &args.arg_path.unwrap()).unwrap();
} }
} }

79
src/repository/backup.rs Normal file
View File

@ -0,0 +1,79 @@
use super::{Repository, Chunk};
use rmp_serde;
use serde::{Deserialize, Serialize};
use std::fs::{self, File};
use std::path::Path;
#[derive(Default, Debug)]
pub struct Backup {
pub root: Vec<Chunk>,
pub total_data_size: u64,
pub changed_data_size: u64,
pub new_data_size: u64,
pub encoded_data_size: u64,
pub new_bundle_count: usize,
pub chunk_count: usize,
pub avg_chunk_size: f32,
pub date: i64,
pub duration: f32,
pub file_count: usize,
pub dir_count: usize
}
serde_impl!(Backup(u8) {
root: Vec<Chunk> => 0,
total_data_size: u64 => 1,
changed_data_size: u64 => 2,
new_data_size: u64 => 3,
encoded_data_size: u64 => 4,
new_bundle_count: usize => 5,
chunk_count: usize => 6,
avg_chunk_size: f32 => 7,
date: i64 => 8,
duration: f32 => 9,
file_count: usize => 10,
dir_count: usize => 11
});
impl Repository {
pub fn list_backups(&self) -> Result<Vec<String>, &'static str> {
let mut backups = Vec::new();
let mut paths = Vec::new();
let base_path = self.path.join("backups");
paths.push(base_path.clone());
while let Some(path) = paths.pop() {
for entry in try!(fs::read_dir(path).map_err(|_| "Failed to list files")) {
let entry = try!(entry.map_err(|_| "Failed to list files"));
let path = entry.path();
if path.is_dir() {
paths.push(path);
} else {
let relpath = try!(path.strip_prefix(&base_path).map_err(|_| "Failed to obtain relative path"));
backups.push(relpath.to_string_lossy().to_string());
}
}
}
Ok(backups)
}
pub fn get_backup(&self, name: &str) -> Result<Backup, &'static str> {
let file = try!(File::open(self.path.join("backups").join(name)).map_err(|_| "Failed to load backup"));
let mut reader = rmp_serde::Deserializer::new(file);
Backup::deserialize(&mut reader).map_err(|_| "Failed to read backup data")
}
pub fn save_backup(&mut self, backup: &Backup, name: &str) -> Result<(), &'static str> {
let mut file = try!(File::create(self.path.join("backups").join(name)).map_err(|_| "Failed to save backup"));
let mut writer = rmp_serde::Serializer::new(&mut file);
backup.serialize(&mut writer).map_err(|_| "Failed to write backup data")
}
pub fn restore_backup<P: AsRef<Path>>(&mut self, backup: &Backup, path: P) -> Result<(), &'static str> {
let inode = try!(self.get_inode(&backup.root));
try!(self.save_inode_at(&inode, path));
Ok(())
}
}

View File

@ -7,7 +7,10 @@ pub struct RepositoryInfo {
pub raw_data_size: u64, pub raw_data_size: u64,
pub compression_ratio: f32, pub compression_ratio: f32,
pub chunk_count: usize, pub chunk_count: usize,
pub avg_chunk_size: f32 pub avg_chunk_size: f32,
pub index_size: usize,
pub index_capacity: usize,
pub index_entries: usize
} }
@ -28,7 +31,10 @@ impl Repository {
encoded_data_size: encoded_data_size, encoded_data_size: encoded_data_size,
raw_data_size: raw_data_size, raw_data_size: raw_data_size,
compression_ratio: encoded_data_size as f32 / raw_data_size as f32, compression_ratio: encoded_data_size as f32 / raw_data_size as f32,
avg_chunk_size: raw_data_size as f32 / chunk_count as f32 avg_chunk_size: raw_data_size as f32 / chunk_count as f32,
index_size: self.index.size(),
index_capacity: self.index.capacity(),
index_entries: self.index.len()
} }
} }
} }

View File

@ -4,11 +4,11 @@ use rmp_serde;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;
use std::fs::{self, Metadata, File}; use std::fs::{self, Metadata, File, Permissions};
use std::os::linux::fs::MetadataExt; use std::os::linux::fs::MetadataExt;
use std::io::{Cursor, Read}; use std::os::unix::fs::{PermissionsExt, symlink};
use std::io::{Cursor, Read, Write};
use ::util::Hash;
use super::{Repository, Mode, Chunk}; use super::{Repository, Mode, Chunk};
@ -118,25 +118,29 @@ impl Inode {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub fn create_at<P: AsRef<Path>>(&self, path: P) -> Result<(), &'static str> { pub fn create_at<P: AsRef<Path>>(&self, path: P) -> Result<Option<File>, &'static str> {
let full_path = path.as_ref().join(&self.name); let full_path = path.as_ref().join(&self.name);
let mut file = None;
match self.file_type { match self.file_type {
FileType::File => { FileType::File => {
try!(File::create(&full_path).map_err(|_| "Failed to create file")); file = Some(try!(File::create(&full_path).map_err(|_| "Failed to create file")));
}, },
FileType::Directory => { FileType::Directory => {
try!(fs::create_dir(&full_path).map_err(|_| "Failed to create directory")); try!(fs::create_dir(&full_path).map_err(|_| "Failed to create directory"));
}, },
FileType::Symlink => { FileType::Symlink => {
if let Some(ref src) = self.symlink_target { if let Some(ref src) = self.symlink_target {
try!(fs::soft_link(src, &full_path).map_err(|_| "Failed to create symlink"));
try!(symlink(src, &full_path).map_err(|_| "Failed to create symlink"));
} else { } else {
return Err("Symlink without destination") return Err("Symlink without destination")
} }
} }
} }
//FIXME: set times and permissions try!(fs::set_permissions(&full_path, Permissions::from_mode(self.mode)).map_err(|_| "Failed to set permissions"));
Ok(()) //FIXME: set times and gid/uid
// https://crates.io/crates/filetime
Ok(file)
} }
} }
@ -158,7 +162,7 @@ impl Repository {
let mut inode_data = Vec::new(); let mut inode_data = Vec::new();
{ {
let mut writer = rmp_serde::Serializer::new(&mut inode_data); let mut writer = rmp_serde::Serializer::new(&mut inode_data);
inode.serialize(&mut writer).map_err(|_| "Failed to write inode data"); try!(inode.serialize(&mut writer).map_err(|_| "Failed to write inode data"));
} }
self.put_data(Mode::Meta, &inode_data) self.put_data(Mode::Meta, &inode_data)
} }
@ -169,4 +173,21 @@ impl Repository {
let mut reader = rmp_serde::Deserializer::new(data); let mut reader = rmp_serde::Deserializer::new(data);
Inode::deserialize(&mut reader).map_err(|_| "Failed to read inode data") Inode::deserialize(&mut reader).map_err(|_| "Failed to read inode data")
} }
#[inline]
pub fn save_inode_at<P: AsRef<Path>>(&mut self, inode: &Inode, path: P) -> Result<(), &'static str> {
if let Some(mut file) = try!(inode.create_at(path.as_ref())) {
if let Some(ref contents) = inode.contents {
match *contents {
FileContents::Inline(ref data) => {
try!(file.write_all(&data).map_err(|_| "Failed to write data to file"));
},
FileContents::Chunked(ref chunks) => {
try!(self.get_stream(chunks, &mut file));
}
}
}
}
Ok(())
}
} }

View File

@ -4,6 +4,7 @@ mod integrity;
mod basic_io; mod basic_io;
mod info; mod info;
mod metadata; mod metadata;
mod backup;
use std::mem; use std::mem;
use std::cmp::max; use std::cmp::max;
@ -17,6 +18,7 @@ use super::chunker::Chunker;
pub use self::config::Config; pub use self::config::Config;
pub use self::metadata::Inode; pub use self::metadata::Inode;
pub use self::basic_io::Chunk; pub use self::basic_io::Chunk;
pub use self::backup::Backup;
use self::bundle_map::BundleMap; use self::bundle_map::BundleMap;
@ -53,6 +55,7 @@ impl Repository {
try!(config.save(path.join("config.yaml")).map_err(|_| "Failed to save config")); try!(config.save(path.join("config.yaml")).map_err(|_| "Failed to save config"));
let bundle_map = BundleMap::create(); let bundle_map = BundleMap::create();
try!(bundle_map.save(path.join("bundles.map")).map_err(|_| "Failed to save bundle map")); try!(bundle_map.save(path.join("bundles.map")).map_err(|_| "Failed to save bundle map"));
try!(fs::create_dir(&path.join("backups")).map_err(|_| "Failed to create backup directory"));
Ok(Repository{ Ok(Repository{
path: path, path: path,
chunker: config.chunker.create(), chunker: config.chunker.create(),

View File

@ -33,14 +33,14 @@ impl Hash {
impl fmt::Display for Hash { impl fmt::Display for Hash {
#[inline] #[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "{:16x}{:16x}", self.high, self.low) write!(fmt, "{:016x}{:016x}", self.high, self.low)
} }
} }
impl fmt::Debug for Hash { impl fmt::Debug for Hash {
#[inline] #[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "{:16x}{:16x}", self.high, self.low) write!(fmt, "{:016x}{:016x}", self.high, self.low)
} }
} }

View File

@ -45,9 +45,9 @@ impl<K: Eq+Hash, V> LruCache<K, V> {
fn shrink(&mut self) { fn shrink(&mut self) {
let mut tags: Vec<u64> = self.items.values().map(|&(_, n)| n).collect(); let mut tags: Vec<u64> = self.items.values().map(|&(_, n)| n).collect();
tags.sort(); tags.sort();
let bar = tags[tags.len()-self.min_size]; let min = tags[tags.len()-self.min_size];
let mut new = HashMap::with_capacity(self.min_size); let mut new = HashMap::with_capacity(self.min_size);
new.extend(self.items.drain().filter(|&(_,(_, n))| n>=bar)); new.extend(self.items.drain().filter(|&(_,(_, n))| n>=min));
self.items = new; self.items = new;
} }
} }

60
test.sh Executable file
View File

@ -0,0 +1,60 @@
set -ex
mkdir repos
time target/release/zvault init --compression brotli/3 repos/zvault_brotli3
time target/release/zvault init --compression brotli/6 repos/zvault_brotli6
time target/release/zvault init --compression lzma2/2 repos/zvault_lzma2
time attic init repos/attic
time borg init -e none repos/borg
time borg init -e none repos/borg-zlib
time zbackup init --non-encrypted repos/zbackup
cat < test_data/silesia.tar > /dev/null
time target/release/zvault put repos/zvault_brotli3::silesia1 test_data/silesia.tar
time target/release/zvault put repos/zvault_brotli3::silesia2 test_data/silesia.tar
time target/release/zvault put repos/zvault_brotli6::silesia1 test_data/silesia.tar
time target/release/zvault put repos/zvault_brotli6::silesia2 test_data/silesia.tar
time target/release/zvault put repos/zvault_lzma2::silesia1 test_data/silesia.tar
time target/release/zvault put repos/zvault_lzma2::silesia2 test_data/silesia.tar
time attic create repos/attic::silesia1 test_data/silesia.tar
time attic create repos/attic::silesia2 test_data/silesia.tar
time borg create -C none repos/borg::silesia1 test_data/silesia.tar
time borg create -C none repos/borg::silesia2 test_data/silesia.tar
time borg create -C zlib repos/borg-zlib::silesia1 test_data/silesia.tar
time borg create -C zlib repos/borg-zlib::silesia2 test_data/silesia.tar
time zbackup backup --non-encrypted repos/zbackup/backups/silesia1 < test_data/silesia.tar
time zbackup backup --non-encrypted repos/zbackup/backups/silesia2 < test_data/silesia.tar
du -h test_data/silesia.tar
du -sh repos/zvault*/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup
rm -rf repos
mkdir repos
time target/release/zvault init --compression brotli/3 repos/zvault_brotli3
time target/release/zvault init --compression brotli/6 repos/zvault_brotli6
time target/release/zvault init --compression lzma2/2 repos/zvault_lzma2
time attic init repos/attic
time borg init -e none repos/borg
time borg init -e none repos/borg-zlib
time zbackup init --non-encrypted repos/zbackup
cat < test_data/ubuntu.tar > /dev/null
time target/release/zvault put repos/zvault_brotli3::ubuntu1 test_data/ubuntu.tar
time target/release/zvault put repos/zvault_brotli3::ubuntu2 test_data/ubuntu.tar
time target/release/zvault put repos/zvault_brotli6::ubuntu1 test_data/ubuntu.tar
time target/release/zvault put repos/zvault_brotli6::ubuntu2 test_data/ubuntu.tar
time target/release/zvault put repos/zvault_lzma2::ubuntu1 test_data/ubuntu.tar
time target/release/zvault put repos/zvault_lzma2::ubuntu2 test_data/ubuntu.tar
time attic create repos/attic::ubuntu1 test_data/ubuntu.tar
time attic create repos/attic::ubuntu2 test_data/ubuntu.tar
time borg create -C none repos/borg::ubuntu1 test_data/ubuntu.tar
time borg create -C none repos/borg::ubuntu2 test_data/ubuntu.tar
time borg create -C zlib repos/borg-zlib::ubuntu1 test_data/ubuntu.tar
time borg create -C zlib repos/borg-zlib::ubuntu2 test_data/ubuntu.tar
time zbackup backup --non-encrypted repos/zbackup/backups/ubuntu1 < test_data/ubuntu.tar
time zbackup backup --non-encrypted repos/zbackup/backups/ubuntu2 < test_data/ubuntu.tar
du -h test_data/ubuntu.tar
du -sh repos/zvault*/bundles repos/attic repos/borg repos/borg-zlib repos/zbackup